From 282c0953c1adbc21803bc1471138bfb89e8a8d57 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:40:04 +0000 Subject: [PATCH 01/23] test: add 20.0-project E2E test asset and update update tests to use it Update e2e assets (cherry picked from commit 11a4438a733a118909c72d54423c4a9705bdfafb) --- tests/e2e/assets/19.0-project/package.json | 37 -------- .../src/app/app.component.spec.ts | 29 ------ .../19.0-project/src/app/app.component.ts | 12 --- .../assets/19.0-project/src/app/app.config.ts | 8 -- tests/e2e/assets/19.0-project/src/index.html | 13 --- tests/e2e/assets/19.0-project/src/main.ts | 5 - .../.editorconfig | 0 .../{19.0-project => 20.0-project}/.gitignore | 1 + .../20.0-project/.vscode/extensions.json | 4 + .../assets/20.0-project/.vscode/launch.json | 20 ++++ .../assets/20.0-project/.vscode/tasks.json | 42 +++++++++ .../{19.0-project => 20.0-project}/README.md | 4 +- .../angular.json | 36 +++++--- tests/e2e/assets/20.0-project/package.json | 48 ++++++++++ .../public/favicon.ico | Bin .../assets/20.0-project/src/app/app.config.ts | 12 +++ .../src/app/app.css} | 0 .../src/app/app.html} | 86 +++++++++--------- .../src/app/app.routes.ts | 0 .../assets/20.0-project/src/app/app.spec.ts | 23 +++++ tests/e2e/assets/20.0-project/src/app/app.ts | 12 +++ tests/e2e/assets/20.0-project/src/index.html | 13 +++ tests/e2e/assets/20.0-project/src/main.ts | 6 ++ .../src/styles.css | 0 .../tsconfig.app.json | 8 +- .../tsconfig.json | 17 +++- .../tsconfig.spec.json | 9 +- .../tests/update/update-multiple-versions.ts | 2 +- tests/e2e/tests/update/update.ts | 14 +-- 29 files changed, 280 insertions(+), 181 deletions(-) delete mode 100644 tests/e2e/assets/19.0-project/package.json delete mode 100644 tests/e2e/assets/19.0-project/src/app/app.component.spec.ts delete mode 100644 tests/e2e/assets/19.0-project/src/app/app.component.ts delete mode 100644 tests/e2e/assets/19.0-project/src/app/app.config.ts delete mode 100644 tests/e2e/assets/19.0-project/src/index.html delete mode 100644 tests/e2e/assets/19.0-project/src/main.ts rename tests/e2e/assets/{19.0-project => 20.0-project}/.editorconfig (100%) rename tests/e2e/assets/{19.0-project => 20.0-project}/.gitignore (97%) create mode 100644 tests/e2e/assets/20.0-project/.vscode/extensions.json create mode 100644 tests/e2e/assets/20.0-project/.vscode/launch.json create mode 100644 tests/e2e/assets/20.0-project/.vscode/tasks.json rename tests/e2e/assets/{19.0-project => 20.0-project}/README.md (96%) rename tests/e2e/assets/{19.0-project => 20.0-project}/angular.json (70%) create mode 100644 tests/e2e/assets/20.0-project/package.json rename tests/e2e/assets/{19.0-project => 20.0-project}/public/favicon.ico (100%) create mode 100644 tests/e2e/assets/20.0-project/src/app/app.config.ts rename tests/e2e/assets/{19.0-project/src/app/app.component.css => 20.0-project/src/app/app.css} (100%) rename tests/e2e/assets/{19.0-project/src/app/app.component.html => 20.0-project/src/app/app.html} (91%) rename tests/e2e/assets/{19.0-project => 20.0-project}/src/app/app.routes.ts (100%) create mode 100644 tests/e2e/assets/20.0-project/src/app/app.spec.ts create mode 100644 tests/e2e/assets/20.0-project/src/app/app.ts create mode 100644 tests/e2e/assets/20.0-project/src/index.html create mode 100644 tests/e2e/assets/20.0-project/src/main.ts rename tests/e2e/assets/{19.0-project => 20.0-project}/src/styles.css (100%) rename tests/e2e/assets/{19.0-project => 20.0-project}/tsconfig.app.json (81%) rename tests/e2e/assets/{19.0-project => 20.0-project}/tsconfig.json (79%) rename tests/e2e/assets/{19.0-project => 20.0-project}/tsconfig.spec.json (76%) diff --git a/tests/e2e/assets/19.0-project/package.json b/tests/e2e/assets/19.0-project/package.json deleted file mode 100644 index 7b65d66807a2..000000000000 --- a/tests/e2e/assets/19.0-project/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "nineteen-project", - "version": "0.0.0", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "ng build", - "watch": "ng build --watch --configuration development", - "test": "ng test" - }, - "private": true, - "dependencies": { - "@angular/common": "^19.2.0", - "@angular/compiler": "^19.2.0", - "@angular/core": "^19.2.0", - "@angular/forms": "^19.2.0", - "@angular/platform-browser": "^19.2.0", - "@angular/platform-browser-dynamic": "^19.2.0", - "@angular/router": "^19.2.0", - "rxjs": "~7.8.0", - "tslib": "^2.3.0", - "zone.js": "~0.15.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^19.2.13", - "@angular/cli": "^19.2.13", - "@angular/compiler-cli": "^19.2.0", - "@types/jasmine": "~5.1.0", - "jasmine-core": "~5.6.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "~3.2.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.7.2" - } -} diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.spec.ts b/tests/e2e/assets/19.0-project/src/app/app.component.spec.ts deleted file mode 100644 index e390fd7bd137..000000000000 --- a/tests/e2e/assets/19.0-project/src/app/app.component.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have the 'nineteen-project' title`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('nineteen-project'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, nineteen-project'); - }); -}); diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.ts b/tests/e2e/assets/19.0-project/src/app/app.component.ts deleted file mode 100644 index 620c8a058372..000000000000 --- a/tests/e2e/assets/19.0-project/src/app/app.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - selector: 'app-root', - imports: [RouterOutlet], - templateUrl: './app.component.html', - styleUrl: './app.component.css', -}) -export class AppComponent { - title = 'nineteen-project'; -} diff --git a/tests/e2e/assets/19.0-project/src/app/app.config.ts b/tests/e2e/assets/19.0-project/src/app/app.config.ts deleted file mode 100644 index 7afc797fbab7..000000000000 --- a/tests/e2e/assets/19.0-project/src/app/app.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; -import { provideRouter } from '@angular/router'; - -import { routes } from './app.routes'; - -export const appConfig: ApplicationConfig = { - providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)], -}; diff --git a/tests/e2e/assets/19.0-project/src/index.html b/tests/e2e/assets/19.0-project/src/index.html deleted file mode 100644 index f374b0fe3d5e..000000000000 --- a/tests/e2e/assets/19.0-project/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - NineteenProject - - - - - - - - diff --git a/tests/e2e/assets/19.0-project/src/main.ts b/tests/e2e/assets/19.0-project/src/main.ts deleted file mode 100644 index 17447a5dce2c..000000000000 --- a/tests/e2e/assets/19.0-project/src/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)); diff --git a/tests/e2e/assets/19.0-project/.editorconfig b/tests/e2e/assets/20.0-project/.editorconfig similarity index 100% rename from tests/e2e/assets/19.0-project/.editorconfig rename to tests/e2e/assets/20.0-project/.editorconfig diff --git a/tests/e2e/assets/19.0-project/.gitignore b/tests/e2e/assets/20.0-project/.gitignore similarity index 97% rename from tests/e2e/assets/19.0-project/.gitignore rename to tests/e2e/assets/20.0-project/.gitignore index cc7b141350ff..b1d225e26e57 100644 --- a/tests/e2e/assets/19.0-project/.gitignore +++ b/tests/e2e/assets/20.0-project/.gitignore @@ -36,6 +36,7 @@ yarn-error.log /libpeerconnection.log testem.log /typings +__screenshots__/ # System files .DS_Store diff --git a/tests/e2e/assets/20.0-project/.vscode/extensions.json b/tests/e2e/assets/20.0-project/.vscode/extensions.json new file mode 100644 index 000000000000..77b374577de8 --- /dev/null +++ b/tests/e2e/assets/20.0-project/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/tests/e2e/assets/20.0-project/.vscode/launch.json b/tests/e2e/assets/20.0-project/.vscode/launch.json new file mode 100644 index 000000000000..925af837050a --- /dev/null +++ b/tests/e2e/assets/20.0-project/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/tests/e2e/assets/20.0-project/.vscode/tasks.json b/tests/e2e/assets/20.0-project/.vscode/tasks.json new file mode 100644 index 000000000000..a298b5bd8796 --- /dev/null +++ b/tests/e2e/assets/20.0-project/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/tests/e2e/assets/19.0-project/README.md b/tests/e2e/assets/20.0-project/README.md similarity index 96% rename from tests/e2e/assets/19.0-project/README.md rename to tests/e2e/assets/20.0-project/README.md index 80d80f5a3f1f..1f4d992edb5b 100644 --- a/tests/e2e/assets/19.0-project/README.md +++ b/tests/e2e/assets/20.0-project/README.md @@ -1,6 +1,6 @@ -# NineteenProject +# TwentyProject -This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.2.13. +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.27. ## Development server diff --git a/tests/e2e/assets/19.0-project/angular.json b/tests/e2e/assets/20.0-project/angular.json similarity index 70% rename from tests/e2e/assets/19.0-project/angular.json rename to tests/e2e/assets/20.0-project/angular.json index b435223e9930..6c24b184adf2 100644 --- a/tests/e2e/assets/19.0-project/angular.json +++ b/tests/e2e/assets/20.0-project/angular.json @@ -3,7 +3,7 @@ "version": 1, "newProjectRoot": "projects", "projects": { - "nineteen-project": { + "twenty-project": { "projectType": "application", "schematics": {}, "root": "", @@ -11,12 +11,13 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular/build:application", "options": { - "outputPath": "dist/nineteen-project", - "index": "src/index.html", + "outputPath": "dist/twenty-project", "browser": "src/main.ts", - "polyfills": ["zone.js"], + "polyfills": [ + "zone.js" + ], "tsConfig": "tsconfig.app.json", "assets": [ { @@ -24,8 +25,9 @@ "input": "public" } ], - "styles": ["src/styles.css"], - "scripts": [] + "styles": [ + "src/styles.css" + ] }, "configurations": { "production": { @@ -52,24 +54,27 @@ "defaultConfiguration": "production" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "configurations": { "production": { - "buildTarget": "nineteen-project:build:production" + "buildTarget": "twenty-project:build:production" }, "development": { - "buildTarget": "nineteen-project:build:development" + "buildTarget": "twenty-project:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n" + "builder": "@angular/build:extract-i18n" }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { - "polyfills": ["zone.js", "zone.js/testing"], + "polyfills": [ + "zone.js", + "zone.js/testing" + ], "tsConfig": "tsconfig.spec.json", "assets": [ { @@ -77,8 +82,9 @@ "input": "public" } ], - "styles": ["src/styles.css"], - "scripts": [] + "styles": [ + "src/styles.css" + ] } } } diff --git a/tests/e2e/assets/20.0-project/package.json b/tests/e2e/assets/20.0-project/package.json new file mode 100644 index 000000000000..dbbe2cd1478a --- /dev/null +++ b/tests/e2e/assets/20.0-project/package.json @@ -0,0 +1,48 @@ +{ + "name": "twenty-project", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "prettier": { + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] + }, + "private": true, + "dependencies": { + "@angular/common": "^20.3.0", + "@angular/compiler": "^20.3.0", + "@angular/core": "^20.3.0", + "@angular/forms": "^20.3.0", + "@angular/platform-browser": "^20.3.0", + "@angular/router": "^20.3.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular/build": "^20.3.27", + "@angular/cli": "^20.3.27", + "@angular/compiler-cli": "^20.3.0", + "@types/jasmine": "~5.1.0", + "jasmine-core": "~5.9.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.9.2" + } +} \ No newline at end of file diff --git a/tests/e2e/assets/19.0-project/public/favicon.ico b/tests/e2e/assets/20.0-project/public/favicon.ico similarity index 100% rename from tests/e2e/assets/19.0-project/public/favicon.ico rename to tests/e2e/assets/20.0-project/public/favicon.ico diff --git a/tests/e2e/assets/20.0-project/src/app/app.config.ts b/tests/e2e/assets/20.0-project/src/app/app.config.ts new file mode 100644 index 000000000000..d953f4c41b31 --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/app/app.config.ts @@ -0,0 +1,12 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter } from '@angular/router'; + +import { routes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(routes) + ] +}; diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.css b/tests/e2e/assets/20.0-project/src/app/app.css similarity index 100% rename from tests/e2e/assets/19.0-project/src/app/app.component.css rename to tests/e2e/assets/20.0-project/src/app/app.css diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.html b/tests/e2e/assets/20.0-project/src/app/app.html similarity index 91% rename from tests/e2e/assets/19.0-project/src/app/app.component.html rename to tests/e2e/assets/20.0-project/src/app/app.html index f8135391366c..752837241913 100644 --- a/tests/e2e/assets/19.0-project/src/app/app.component.html +++ b/tests/e2e/assets/20.0-project/src/app/app.html @@ -36,18 +36,9 @@ --pill-accent: var(--bright-blue); - font-family: - 'Inter', - -apple-system, - BlinkMacSystemFont, - 'Segoe UI', - Roboto, - Helvetica, - Arial, - sans-serif, - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol'; + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; box-sizing: border-box; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -60,18 +51,9 @@ line-height: 100%; letter-spacing: -0.125rem; margin: 0; - font-family: - 'Inter Tight', - -apple-system, - BlinkMacSystemFont, - 'Segoe UI', - Roboto, - Helvetica, - Arial, - sans-serif, - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol'; + font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; } p { @@ -142,6 +124,7 @@ line-height: 1.4rem; letter-spacing: -0.00875rem; text-decoration: none; + white-space: nowrap; } .pill:hover { @@ -152,11 +135,15 @@ --pill-accent: var(--bright-blue); } .pill-group .pill:nth-child(6n + 2) { + --pill-accent: var(--electric-violet); + } + .pill-group .pill:nth-child(6n + 3) { --pill-accent: var(--french-violet); } - .pill-group .pill:nth-child(6n + 3), + .pill-group .pill:nth-child(6n + 4), - .pill-group .pill:nth-child(6n + 5) { + .pill-group .pill:nth-child(6n + 5), + .pill-group .pill:nth-child(6n + 6) { --pill-accent: var(--hot-red); } @@ -227,7 +214,14 @@ - + @@ -236,26 +230,26 @@ -

Hello, {{ title }}

+

Hello, {{ title() }}

Congratulations! Your app is running. 🎉

- @for ( - item of [ - { title: 'Explore the Docs', link: 'https://angular.dev' }, - { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' }, - { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' }, - { - title: 'Angular Language Service', - link: 'https://angular.dev/tools/language-service', - }, - { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' }, - ]; - track item.title - ) { - + @for (item of [ + { title: 'Explore the Docs', link: 'https://angular.dev' }, + { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' }, + { title: 'Prompt and best practices for AI', link: 'https://angular.dev/ai/develop-with-ai'}, + { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' }, + { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' }, + { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' }, + ]; track item.title) { + {{ item.title }} Hello, {{ title }} /> - + Hello, {{ title }} + diff --git a/tests/e2e/assets/19.0-project/src/app/app.routes.ts b/tests/e2e/assets/20.0-project/src/app/app.routes.ts similarity index 100% rename from tests/e2e/assets/19.0-project/src/app/app.routes.ts rename to tests/e2e/assets/20.0-project/src/app/app.routes.ts diff --git a/tests/e2e/assets/20.0-project/src/app/app.spec.ts b/tests/e2e/assets/20.0-project/src/app/app.spec.ts new file mode 100644 index 000000000000..e2efaa52a155 --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/app/app.spec.ts @@ -0,0 +1,23 @@ +import { TestBed } from '@angular/core/testing'; +import { App } from './app'; + +describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [App], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(App); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Hello, twenty-project'); + }); +}); diff --git a/tests/e2e/assets/20.0-project/src/app/app.ts b/tests/e2e/assets/20.0-project/src/app/app.ts new file mode 100644 index 000000000000..41950ee52c8b --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/app/app.ts @@ -0,0 +1,12 @@ +import { Component, signal } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + templateUrl: './app.html', + styleUrl: './app.css' +}) +export class App { + protected readonly title = signal('twenty-project'); +} diff --git a/tests/e2e/assets/20.0-project/src/index.html b/tests/e2e/assets/20.0-project/src/index.html new file mode 100644 index 000000000000..72285bc13676 --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/index.html @@ -0,0 +1,13 @@ + + + + + TwentyProject + + + + + + + + diff --git a/tests/e2e/assets/20.0-project/src/main.ts b/tests/e2e/assets/20.0-project/src/main.ts new file mode 100644 index 000000000000..5df75f9c838e --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/tests/e2e/assets/19.0-project/src/styles.css b/tests/e2e/assets/20.0-project/src/styles.css similarity index 100% rename from tests/e2e/assets/19.0-project/src/styles.css rename to tests/e2e/assets/20.0-project/src/styles.css diff --git a/tests/e2e/assets/19.0-project/tsconfig.app.json b/tests/e2e/assets/20.0-project/tsconfig.app.json similarity index 81% rename from tests/e2e/assets/19.0-project/tsconfig.app.json rename to tests/e2e/assets/20.0-project/tsconfig.app.json index 8886e903f8d0..264f459bf876 100644 --- a/tests/e2e/assets/19.0-project/tsconfig.app.json +++ b/tests/e2e/assets/20.0-project/tsconfig.app.json @@ -6,6 +6,10 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"] + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] } diff --git a/tests/e2e/assets/19.0-project/tsconfig.json b/tests/e2e/assets/20.0-project/tsconfig.json similarity index 79% rename from tests/e2e/assets/19.0-project/tsconfig.json rename to tests/e2e/assets/20.0-project/tsconfig.json index 5525117c6744..e4955f26b14b 100644 --- a/tests/e2e/assets/19.0-project/tsconfig.json +++ b/tests/e2e/assets/20.0-project/tsconfig.json @@ -3,7 +3,6 @@ { "compileOnSave": false, "compilerOptions": { - "outDir": "./dist/out-tsc", "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, @@ -11,17 +10,25 @@ "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, - "esModuleInterop": true, "experimentalDecorators": true, - "moduleResolution": "bundler", "importHelpers": true, "target": "ES2022", - "module": "ES2022" + "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, + "typeCheckHostBindings": true, "strictTemplates": true - } + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] } diff --git a/tests/e2e/assets/19.0-project/tsconfig.spec.json b/tests/e2e/assets/20.0-project/tsconfig.spec.json similarity index 76% rename from tests/e2e/assets/19.0-project/tsconfig.spec.json rename to tests/e2e/assets/20.0-project/tsconfig.spec.json index e00e30e6d4fb..940b30a5fcc8 100644 --- a/tests/e2e/assets/19.0-project/tsconfig.spec.json +++ b/tests/e2e/assets/20.0-project/tsconfig.spec.json @@ -4,7 +4,12 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": ["jasmine"] + "types": [ + "jasmine" + ] }, - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] } diff --git a/tests/e2e/tests/update/update-multiple-versions.ts b/tests/e2e/tests/update/update-multiple-versions.ts index 6fecb7b15b58..c9070b1a090b 100644 --- a/tests/e2e/tests/update/update-multiple-versions.ts +++ b/tests/e2e/tests/update/update-multiple-versions.ts @@ -7,7 +7,7 @@ import { expectToFail } from '../../utils/utils'; export default async function () { let restoreRegistry: (() => Promise) | undefined; try { - restoreRegistry = await createProjectFromAsset('19.0-project', true); + restoreRegistry = await createProjectFromAsset('20.0-project', true); await setRegistry(true); const extraArgs = ['--force']; diff --git a/tests/e2e/tests/update/update.ts b/tests/e2e/tests/update/update.ts index ae941762d6ca..fd8663503ecc 100644 --- a/tests/e2e/tests/update/update.ts +++ b/tests/e2e/tests/update/update.ts @@ -12,10 +12,10 @@ export default async function () { try { // We need to use the public registry because in the local NPM server we don't have // older versions @angular/cli packages which would cause `npm install` during `ng update` to fail. - restoreRegistry = await createProjectFromAsset('19.0-project', true); + restoreRegistry = await createProjectFromAsset('20.0-project', true); // CLI project version - const cliMajorProjectVersion = 19; + const cliMajorProjectVersion = 20; // If using npm, enable legacy peer deps mode to avoid defects in npm 7+'s peer dependency resolution // Example error where 11.2.14 satisfies the SemVer range ^11.0.0 but still fails: @@ -72,8 +72,8 @@ export default async function () { await ng('update', '@angular/cli', ...extraUpdateArgs); // Setup testing to use CI Chrome. - await useCIChrome('nineteen-project', './'); - await useCIDefaults('nineteen-project'); + await useCIChrome('twenty-project', './'); + await useCIDefaults('twenty-project'); // Run CLI commands. await ng('generate', 'component', 'my-comp'); @@ -81,14 +81,14 @@ export default async function () { await executeBrowserTest({ configuration: 'production', - expectedTitleText: 'Hello, nineteen-project', + expectedTitleText: 'Hello, twenty-project', }); await executeBrowserTest({ configuration: 'development', - expectedTitleText: 'Hello, nineteen-project', + expectedTitleText: 'Hello, twenty-project', }); // Verify project now creates bundles await noSilentNg('build', '--configuration=production'); - await expectFileMatchToExist('dist/nineteen-project/browser', /main-[a-zA-Z0-9]{8}\.js/); + await expectFileMatchToExist('dist/twenty-project/browser', /main-[a-zA-Z0-9]{8}\.js/); } From d45b84be9a607e49b391cb216cb6de7eca274931 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 2 Jun 2026 11:24:03 -0400 Subject: [PATCH 02/23] fix(@angular/build): exclude JSON imports from Vite dependency optimization Importing `.json` files (such as package.json files from third-party packages) causes Vite's dependency optimizer to throw errors and warnings during `ng serve`, as Vite is unable to optimize non-JS/TS modules: `Cannot optimize dependency: @pkg-name/package.json, present in client 'optimizeDeps.include'` This fix filters out any implicit dependencies ending in `.json` in the `updateExternalMetadata` utility, preventing them from being included in Vite's `optimizeDeps.include` array. Closes #33280 (cherry picked from commit 3124d165de476ed219f860c7ea582b96a8181d5c) --- packages/angular/build/src/tools/vite/utils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/tools/vite/utils.ts b/packages/angular/build/src/tools/vite/utils.ts index 8f3ded5325f7..7250fd93ceb7 100644 --- a/packages/angular/build/src/tools/vite/utils.ts +++ b/packages/angular/build/src/tools/vite/utils.ts @@ -140,8 +140,12 @@ export function updateExternalMetadata( } const { implicitBrowser, implicitServer, explicit } = result.detail['externalMetadata']; - const implicitServerFiltered = implicitServer.filter((m) => !isBuiltin(m) && !isAbsoluteUrl(m)); - const implicitBrowserFiltered = implicitBrowser.filter((m) => !isAbsoluteUrl(m)); + const implicitServerFiltered = implicitServer.filter( + (m) => !isBuiltin(m) && !isAbsoluteUrl(m) && !m.endsWith('.json'), + ); + const implicitBrowserFiltered = implicitBrowser.filter( + (m) => !isAbsoluteUrl(m) && !m.endsWith('.json'), + ); const explicitBrowserFiltered = explicitPackagesOnly ? explicit.filter((m) => !isAbsoluteUrl(m)) : explicit; From d333116123c7d3d5e87713b7baac048b78f28517 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:26:50 -0400 Subject: [PATCH 03/23] fix(@angular/cli): fallback to local package.json for schematic detection on first run Private package registries frequently strip out custom non-npm metadata properties such as "schematics" or "ng-add" from their remote API responses. This causes `ng add` to bypass executing schematics on the first run. This fix adds a fallback check immediately after package installation: if the registry did not report `hasSchematics` as `true`, the CLI falls back to resolving and reading the physically installed package's `package.json` on disk as the single source of truth. Additionally, if the local manifest specifies `ng-add.save: false` (but it was persistently installed due to registry omissions), it programmatically prunes the package from `dependencies` or `devDependencies` post-execution, and executes a silent `packageManager.install()` to cleanly remove the physical package files and update the lockfile. Fixes #33060 (cherry picked from commit 7be9910057b4adaa56ac29917bb88efd1564cce9) --- packages/angular/cli/src/commands/add/cli.ts | 57 ++++++++- .../add/add-registry-stripped-schematics.ts | 121 ++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index 136704947e69..b1c57a59ad45 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -245,6 +245,22 @@ export default class AddCommandModule const result = await tasks.run(taskContext); assert(result.collectionName, 'Collection name should always be available'); + let shouldCleanUp = false; + if (!result.hasSchematics && !options.dryRun) { + const packageJsonPath = this.resolvePackageJson(result.collectionName); + if (packageJsonPath && existsSync(packageJsonPath)) { + try { + const localManifest = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); + if (localManifest.schematics) { + result.hasSchematics = true; + if (localManifest['ng-add']?.save === false) { + shouldCleanUp = true; + } + } + } catch {} + } + } + // Check if the installed package has actual add actions and not just schematic support if (result.hasSchematics && !options.dryRun) { const workflow = this.getOrCreateWorkflowForBuilder(result.collectionName); @@ -299,7 +315,16 @@ export default class AddCommandModule return; } - return this.executeSchematic({ ...options, collection: result.collectionName }); + const schematicExitCode = await this.executeSchematic({ + ...options, + collection: result.collectionName, + }); + + if (shouldCleanUp) { + await this.cleanUpTemporaryDependency(result.collectionName); + } + + return schematicExitCode; } catch (e) { if (e instanceof CommandError) { logger.error(e.message); @@ -560,6 +585,36 @@ export default class AddCommandModule } } + private async cleanUpTemporaryDependency(packageName: string): Promise { + try { + this.context.logger.info(`Cleaning up temporary dependency '${packageName}'...`); + + // 1. Remove from root package.json + const projectManifest = await this.getProjectManifest(); + if (projectManifest) { + if (projectManifest.dependencies) { + delete projectManifest.dependencies[packageName]; + } + if (projectManifest.devDependencies) { + delete projectManifest.devDependencies[packageName]; + } + + await fs.writeFile( + join(this.context.root, 'package.json'), + JSON.stringify(projectManifest, null, 2) + '\n', + ); + } + + // 2. Silent install pass to prune files from node_modules and update the lockfile + await this.context.packageManager.install({ ignoreScripts: true }); + } catch (error) { + this.context.logger.warn( + `Failed to clean up temporary dependency '${packageName}': ` + + `${error instanceof Error ? error.message : error}`, + ); + } + } + private async installPackageTask( context: AddCommandTaskContext, task: AddCommandTaskWrapper, diff --git a/tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts b/tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts new file mode 100644 index 000000000000..c6356dc8d92c --- /dev/null +++ b/tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts @@ -0,0 +1,121 @@ +import { join } from 'node:path'; +import { promises as fs } from 'node:fs'; +import { getGlobalVariable } from '../../../utils/env'; +import { expectFileToExist, expectFileNotToExist, rimraf } from '../../../utils/fs'; +import { getActivePackageManager } from '../../../utils/packages'; +import { ng, silentNpm } from '../../../utils/process'; +import { mktempd } from '../../../utils/utils'; + +export default async function () { + const testRegistry = getGlobalVariable('package-registry'); + const tmpRoot = getGlobalVariable('tmp-root'); + + // 1. Create a temp directory for the custom package + const pkgDir = await mktempd('registry-stripped-pkg-', tmpRoot); + + try { + // 2. Write the package files + const packageJson = { + name: '@angular-devkit/ng-add-registry-stripped', + version: '1.0.0', + schematics: './collection.json', + 'ng-add': { + save: false, + }, + }; + + const collectionJson = { + schematics: { + 'ng-add': { + factory: './index.js', + description: 'Add test empty file to your application.', + }, + }, + }; + + const indexJs = ` + exports.default = function() { + return function(tree) { + tree.create('schematic-executed-successfully.txt', 'Registry Stripped schematic works!'); + return tree; + }; + }; + `; + + await fs.writeFile(join(pkgDir, 'package.json'), JSON.stringify(packageJson, null, 2)); + await fs.writeFile(join(pkgDir, 'collection.json'), JSON.stringify(collectionJson, null, 2)); + await fs.writeFile(join(pkgDir, 'index.js'), indexJs); + + // Write a temporary .npmrc with a fake authentication token so that npm publish succeeds + // without needing real credentials or throwing ENEEDAUTH. + const npmrcContent = ` +${testRegistry.replace(/^https?:/, '')}/:_authToken=fake-secret +registry=${testRegistry} +`; + await fs.writeFile(join(pkgDir, '.npmrc'), npmrcContent); + + // 3. Pack the package + const packResult = await silentNpm(['pack'], { cwd: pkgDir }); + const tarballName = packResult.stdout.trim().split('\n').pop() || ''; + + // 4. Publish the package to the local verdaccio registry + // Verdaccio has publish: $all for @angular-devkit/* so this will succeed + await silentNpm(['publish'], { cwd: pkgDir }); + + // 5. Strip "schematics" and "ng-add" from Verdaccio's metadata on disk + const verdaccioDbPath = join( + tmpRoot, + 'registry', + 'storage', + '@angular-devkit', + 'ng-add-registry-stripped', + 'package.json', + ); + + const verdaccioDb = JSON.parse(await fs.readFile(verdaccioDbPath, 'utf-8')); + + // Strip from the top-level versions list + if (verdaccioDb.versions) { + for (const versionKey of Object.keys(verdaccioDb.versions)) { + delete verdaccioDb.versions[versionKey].schematics; + delete verdaccioDb.versions[versionKey]['ng-add']; + } + } + + // Write back the modified metadata + await fs.writeFile(verdaccioDbPath, JSON.stringify(verdaccioDb, null, 2), 'utf-8'); + + // 6. Execute `ng add` on the registry-stripped package + // Ensure file doesn't already exist + await expectFileNotToExist('schematic-executed-successfully.txt'); + + await ng('add', '@angular-devkit/ng-add-registry-stripped', '--skip-confirmation'); + + // 7. Assertions + // A. The schematic executed successfully + await expectFileToExist('schematic-executed-successfully.txt'); + + // B. The dependency was pruned from package.json since save: false + const rootPackageJson = JSON.parse(await fs.readFile('package.json', 'utf-8')); + const hasDep = + (rootPackageJson.dependencies && + rootPackageJson.dependencies['@angular-devkit/ng-add-registry-stripped']) || + (rootPackageJson.devDependencies && + rootPackageJson.devDependencies['@angular-devkit/ng-add-registry-stripped']); + + if (hasDep) { + throw new Error( + 'Package @angular-devkit/ng-add-registry-stripped was not cleaned up from package.json dependencies!', + ); + } + + // C. The dependency was pruned from node_modules physical folder + // Bun intentionally does not prune unreferenced packages from node_modules automatically. + if (getActivePackageManager() !== 'bun') { + await expectFileNotToExist('node_modules/@angular-devkit/ng-add-registry-stripped'); + } + } finally { + // Cleanup temp package source folder + await rimraf(pkgDir); + } +} From 27827b2cb49ef4afe52459e0ecdff739ffcc37d9 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 3 Jun 2026 21:30:39 +0000 Subject: [PATCH 04/23] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 6 +++--- MODULE.bazel.lock | 38 +++++++++++++++++------------------ package.json | 6 +++--- pnpm-lock.yaml | 50 +++++++++++++++++++++++------------------------ 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 90003774ce3b..3dcef96ef20d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "c898ddb32c0428e7d97efc713393db84ffa6a38e", + commit = "582ffa9559d60f99fd1d3e50ae32c4223f013fea", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "9ee8a680dd018d61d21588bb04cf40d49a9f5deb", + commit = "b490e5cc7fd2aa57136a1962047bd89454f3df94", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "45441c79322943fc1638b3a40741e925d6089e7b", + commit = "96a315fb4737861718aa59a7e7361408db704148", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index af29118bb1f4..0753cd1055ce 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -28,7 +28,6 @@ "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/source.json": "a32ab71831452b945f3f83a1b1feb9402007e600bce55ac76e15ef0c1e08b520", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/source.json": "745c8dba237b4088409800143241bbb138e7ef37a359bd81a250c2c423f380ce", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.9/MODULE.bazel": "bd5f9ebf517cfcd377eaa7ce1cb16035d167f00774b77789909590c53bc6f20c", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/source.json": "605086bbc197743a0d360f7ddc550a1d4dfa0441bc807236e17170f636153348", @@ -199,7 +198,8 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.10.4/MODULE.bazel": "e8f9ff79199e8d9eaad7f1b0a77ad74b30bb82d794b87d8ca942bead5de83ae9", - "https://bcr.bazel.build/modules/tar.bzl/0.10.4/source.json": "20143442376c03426f6135292ba02d825cb75308aa47e6bf42dd4cc5a435c2ff", + "https://bcr.bazel.build/modules/tar.bzl/0.10.5/MODULE.bazel": "e964c1f07f7174478d43be7177f364640e24956d5994bd39d48548cc6a436e2c", + "https://bcr.bazel.build/modules/tar.bzl/0.10.5/source.json": "6703dc57a6c7118722ac452ffb0a05f6e205408b810c6aaf25741a635d5f4b89", "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", @@ -592,7 +592,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "lFwT6yuDqc73sJB9lqKqoCIJq/vYSrS0UPimP2c0ZWA=", + "bzlTransitiveDigest": "WLnUVJj/ND5g3OI+Y8YJwgtWXfoXpunqLGs7GRZ3PqI=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -601,9 +601,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f8b9f220f5691f88e00a64dafa98570158b50e7051637644df1152e3c96f9738", + "sha256": "7db2d5ced82b7f4c62ed593ff2a0e486dde48ae2b09609ab74fe30dad6eadbab", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -619,9 +619,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "e989d33e0c27d8884ff95d8c485993205b554499587f33ca390041d54dd57415", + "sha256": "87e67dc147587e0c6b7ae5e6d14b778e7782c8273d1798a2841b7b6b8cbcb669", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -637,9 +637,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "e92afa41f45c8cd5241572e21ec3a17a68d12926f7fad7047e8d4bbef0397f4e", + "sha256": "42675dfaf8e89174fafecf300fdba58bc8410c31b7d9d2300505dce3358cff9c", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -655,9 +655,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "374efaa85908a078e41a0a75bded482eeb1d652aea6c5bb0c14cd854736943c8", + "sha256": "f9b135b3d1ca7e80dcced8ece4975a918f1d37d2b1f74793902e3b1ab3fa4ea6", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -673,9 +673,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "69e0625253c89cc7f8d265016fa46bf63401f9f7ca0454d0dade828c58bd9a08", + "sha256": "39c2d4425b848f2e09940b4060f50484ca83f18b9d3bdbe2f42495d4a1d38f71", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -689,9 +689,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "95e64bff15615dede9e6a690cf91fc76603354daa05d80437be39e15dfc94611", + "sha256": "48ece94ee9b286f47c6662f3d2640a4a035af2e4f8101f8a971a909bc552bd36", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -705,9 +705,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "63d0da6ef29c4ad9f6b5ddbe68466e3c301c9e04daed509ac31f339a5948fe8e", + "sha256": "736ec9b51a4d6fe1622d1940df29e3b183fe5d09f7f06d68141c2330f76a9790", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -721,9 +721,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "93b27d5b09340d650923cfd9d8e306c2e6430dcf0b826f34e79080b43dff7064", + "sha256": "77b5c787237dcac62686c125e702d0bddc28466e9660f79a77d8389cd1d94513", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/package.json b/package.json index 1a9c92f1d769..ae1d2f42bb10 100644 --- a/package.json +++ b/package.json @@ -47,14 +47,14 @@ }, "devDependencies": { "@angular/animations": "22.0.0", - "@angular/cdk": "22.0.0-rc.2", + "@angular/cdk": "22.0.0", "@angular/common": "22.0.0", "@angular/compiler": "22.0.0", "@angular/core": "22.0.0", "@angular/forms": "22.0.0", "@angular/localize": "22.0.0", - "@angular/material": "22.0.0-rc.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#a450a2420ca888116e6d4207b38819cd27b06179", + "@angular/material": "22.0.0", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29", "@angular/platform-browser": "22.0.0", "@angular/platform-server": "22.0.0", "@angular/router": "22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b66e16d5762..34620d846b3f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,8 @@ importers: specifier: 22.0.0 version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': specifier: 22.0.0 version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) @@ -47,11 +47,11 @@ importers: specifier: 22.0.0 version: 22.0.0(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(@angular/compiler@22.0.0) '@angular/material': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(626d92b70d6fd1515002dfba4bbacd97) + specifier: 22.0.0 + version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#a450a2420ca888116e6d4207b38819cd27b06179 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2)) '@angular/platform-browser': specifier: 22.0.0 version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -941,12 +941,12 @@ packages: peerDependencies: '@angular/core': 22.0.0 - '@angular/cdk@22.0.0-rc.2': - resolution: {integrity: sha512-KiQInxX5WrPgsNjqqaD3/voRXNNsp0cuvH8VZerIeRUrOxsuqsyU8bUk6q6GWobL4LDj7afiqjDTEdwnq9KVww==} + '@angular/cdk@22.0.0': + resolution: {integrity: sha512-mahXlRD4V8Tj2NtttRNFfuTru5HmMgJt8ny/SJ/Bx1NCOymxLEqxREACNpuwMf/3q1XUe33/oh++mvJQ2JYkgw==} peerDependencies: - '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/common': ^22.0.0 || ^23.0.0 + '@angular/core': ^22.0.0 || ^23.0.0 + '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 '@angular/common@22.0.0': @@ -1001,19 +1001,19 @@ packages: '@angular/compiler': 22.0.0 '@angular/compiler-cli': 22.0.0 - '@angular/material@22.0.0-rc.2': - resolution: {integrity: sha512-pHs8iMDjyX9o07B2qQqsQ1/n7WgonV2RVVJjxp4c9cralKDufizCpQSCgrkq9fnGu4Ijv7f8ShqHVXLGITMAPg==} + '@angular/material@22.0.0': + resolution: {integrity: sha512-sRxbEEgmaVqbwcT65PWfZV/cIpLsZ8vD+yc6rH83L83jDJWVABpqDWFg8Hl88iFMOts8iffml6GddvXhsNHAEQ==} peerDependencies: - '@angular/cdk': 22.0.0-rc.2 - '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/cdk': 22.0.0 + '@angular/common': ^22.0.0 || ^23.0.0 + '@angular/core': ^22.0.0 || ^23.0.0 + '@angular/forms': ^22.0.0 || ^23.0.0 + '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179': - resolution: {gitHosted: true, integrity: sha512-yKQqLu4g+2WiIoXV4M7F0x94929zZESjhTj0kTrincYgJ6GrAzfzdeayD5D2ZVg6xUg6ubPEMDDVUwEMeB93Mw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179} - version: 0.0.0-9ee8a680dd018d61d21588bb04cf40d49a9f5deb + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29': + resolution: {gitHosted: true, integrity: sha512-JAec9kjT065fvyeoiFW/iLaTTZ0QTpg6oiMVoV51l0o7HkIWoNIvIOyVk1WELR6Y2vEw0pNMdQQAlYEiQDshMA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29} + version: 0.0.0-b64a291ca373bc91e5ee876488710c026157bf91 hasBin: true '@angular/platform-browser@22.0.0': @@ -8754,7 +8754,7 @@ snapshots: '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.0.0-rc.2(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) @@ -8818,9 +8818,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/material@22.0.0-rc.2(626d92b70d6fd1515002dfba4bbacd97)': + '@angular/material@22.0.0(6eb83275f51d1d41f72333b1955c7306)': dependencies: - '@angular/cdk': 22.0.0-rc.2(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/cdk': 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) @@ -8828,7 +8828,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/a450a2420ca888116e6d4207b38819cd27b06179(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) From 89d1be979f388d85e9c428bbf1df4e7fb4036dce Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 3 Jun 2026 10:59:10 +0200 Subject: [PATCH 05/23] fix(@angular/build): allow disabling Vitest isolation from builder Keep the isolate builder option undefined when it is omitted so a Vitest runner config can provide its own value. Previously, ng test --isolate worked because true was forwarded as an override, but ng test --no-isolate was normalized to false and then treated the same as an omitted option. As a result, test.isolate: true in vitest-base.config.ts stayed active. Forward explicit false values to the Vitest project config so --no-isolate can override runnerConfig while the default still aligns with the Karma/Jasmine experience. (cherry picked from commit 2d0a1c598c3e8a0d06e8927aab6854343705f305) --- .../build/src/builders/unit-test/options.ts | 2 +- .../unit-test/runners/vitest/plugins.ts | 6 +-- .../unit-test/tests/options/isolate_spec.ts | 54 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 5cd04c4ca7bf..ef09958885a7 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -126,7 +126,7 @@ export async function normalizeOptions( watch, debug: options.debug ?? false, ui: process.env['CI'] ? false : ui, - isolate: isolate ?? false, + isolate, quiet: options.quiet ?? (process.env['CI'] ? false : true), providersFile: options.providersFile && path.join(workspaceRoot, options.providersFile), setupFiles: options.setupFiles diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index eb3d7d106ab4..c5e3764043bb 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -54,7 +54,7 @@ interface VitestConfigPluginOptions { include: string[]; optimizeDepsInclude: string[]; watch: boolean; - isolate: boolean; + isolate: boolean | undefined; } async function findTestEnvironment( @@ -268,8 +268,8 @@ export async function createVitestConfigPlugin( include, // CLI provider browser options override, if present ...(browser ? { browser } : {}), - // Only override if the user explicitly enabled it via CLI - ...(options.isolate ? { isolate: true } : {}), + // Only override if the user explicitly set it via CLI + ...(options.isolate !== undefined ? { isolate: options.isolate } : {}), // If the user has not specified an environment, use a smart default. ...(!testConfig?.environment ? { environment: await findTestEnvironment(projectResolver) } diff --git a/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts index 6ca00a02d94d..a37bf597e91a 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts @@ -54,5 +54,59 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should override isolate from the Vitest config file when set to false', async () => { + harness.writeFile( + 'vitest-base.config.ts', + ` + import { defineConfig } from 'vitest/config'; + + export default defineConfig({ + test: { + fileParallelism: false, + isolate: true, + setupFiles: ['./src/setup.ts'], + }, + }); + `, + ); + + harness.writeFile( + 'src/setup.ts', + ` + const global = globalThis as typeof globalThis & { setupCount?: number }; + global.setupCount = (global.setupCount ?? 0) + 1; + `, + ); + + harness.writeFile( + 'src/app/first.spec.ts', + ` + it('runs first', () => { + expect(true).toBe(true); + }); + `, + ); + + harness.writeFile( + 'src/app/second.spec.ts', + ` + it('shares the test environment with the first spec file', () => { + const global = globalThis as typeof globalThis & { setupCount?: number }; + expect(global.setupCount).toBeGreaterThan(1); + }); + `, + ); + + harness.useTarget('test', { + ...BASE_OPTIONS, + runner: 'vitest' as any, + runnerConfig: true, + isolate: false, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); From a9b784a4bf346a6e1daef33ccd3f79e57d03a74a Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 06:58:08 +0000 Subject: [PATCH 06/23] build: update all github actions See associated pull request for more information. --- .github/workflows/assistant-to-the-branch-manager.yml | 2 +- .github/workflows/codeql.yml | 6 +++--- .github/workflows/pr.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 87519e50b728..eb299f1e8855 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.event.repository.fork == false steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: angular/dev-infra/github-actions/branch-manager@ba726e7bca0b08b125ccc6f93c233749e1213c17 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6595df14c26d..dd199499e759 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,16 +19,16 @@ jobs: fail-fast: false steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index ae107e5c34d6..dd68d34f72e7 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -20,7 +20,7 @@ jobs: outputs: snapshots: ${{ steps.filter.outputs.snapshots }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index fb88be1f8b98..3cf9ef0b1a8d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,7 +25,7 @@ jobs: steps: - name: 'Checkout code' - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -46,6 +46,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: sarif_file: results.sarif From 72c5d09c3aaddefde0eb5ce20a4f50e87c6db62b Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 08:44:43 +0000 Subject: [PATCH 07/23] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 4 ++-- MODULE.bazel.lock | 23 ++++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 3dcef96ef20d..1d86371622b6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,10 +7,10 @@ module( bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "yq.bzl", version = "0.3.6") bazel_dep(name = "rules_nodejs", version = "6.7.4") -bazel_dep(name = "aspect_rules_js", version = "3.1.2") +bazel_dep(name = "aspect_rules_js", version = "3.2.0") bazel_dep(name = "aspect_rules_ts", version = "3.8.10") bazel_dep(name = "rules_pkg", version = "1.2.0") -bazel_dep(name = "rules_cc", version = "0.2.18") +bazel_dep(name = "rules_cc", version = "0.2.19") bazel_dep(name = "jq.bzl", version = "0.6.1") bazel_dep(name = "bazel_lib", version = "3.3.1") bazel_dep(name = "bazel_skylib", version = "1.9.0") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0753cd1055ce..53f5ff646cb4 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -25,7 +25,8 @@ "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/MODULE.bazel": "e3685502155d3cc65f3bf98e714f7435de67d7f8f355d63478a80197310311fc", - "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/source.json": "a32ab71831452b945f3f83a1b1feb9402007e600bce55ac76e15ef0c1e08b520", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/MODULE.bazel": "c3d34345c51a4d90cf678d3b251c6f345b63d5e2e6b0253dbdda467a01efc31f", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/source.json": "3538ab18ac72ba3eaa3db0e4ec5171e04322768723afaa1149c0d822fe5411e2", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/source.json": "745c8dba237b4088409800143241bbb138e7ef37a359bd81a250c2c423f380ce", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", @@ -44,8 +45,8 @@ "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", "https://bcr.bazel.build/modules/bazel_features/1.41.0/MODULE.bazel": "6e0f87fafed801273c371d41e22a15a6f8abf83fdd7f87d5e44ad317b94433d0", - "https://bcr.bazel.build/modules/bazel_features/1.43.0/MODULE.bazel": "defa2226f06ba20550d6548c3a2ea2a7929634437a52973869c20c225450eb91", - "https://bcr.bazel.build/modules/bazel_features/1.43.0/source.json": "1c4207dc858d6de0eecef30026793616bbf420c74aac27b6bad212534a730437", + "https://bcr.bazel.build/modules/bazel_features/1.47.0/MODULE.bazel": "e34df3cb35b1684cfa69923a61ae3803595babd3942cd306a488d51400886b30", + "https://bcr.bazel.build/modules/bazel_features/1.47.0/source.json": "4ba0b5138327f2d73352a51547a4e49a0a828ef400e046b15334d8905bf6b7ff", "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", @@ -126,8 +127,8 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", - "https://bcr.bazel.build/modules/rules_cc/0.2.18/MODULE.bazel": "4460ec36adc8f722a6a2a4ac9374cb91f2acebadaa93fc37966129afb3dece87", - "https://bcr.bazel.build/modules/rules_cc/0.2.18/source.json": "abad668ff2fd63ada1ac49bf386d37e27048b89a3465a6fd968bb832b00a09d3", + "https://bcr.bazel.build/modules/rules_cc/0.2.19/MODULE.bazel": "d5e0f05b63273281a16654eb6b1a8742a75ec153ac8b4f0419949d6e401e46f0", + "https://bcr.bazel.build/modules/rules_cc/0.2.19/source.json": "1ef48cdbd7aa6238015189b582d3d74ef0cbea3cb3e2cb259d782463f570c14a", "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", @@ -219,7 +220,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "eWM29sOFdgwS2/XR2bEHk1NS/hPrYIX7ly4yh7MH5As=", + "bzlTransitiveDigest": "8bNoUkbLk1vCab3fXdV3RN1UoOjEcHlo/bk9XxZ7e3A=", "usagesDigest": "LSQ+zZp7JNgnBONTxxXnwGr4NTh2qtQYk7qwXXz5qWo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -498,7 +499,7 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", - "usagesDigest": "SOv3fnWScyh5pAbfi8TO0WqlioqyUWt3t29KT0VkqLE=", + "usagesDigest": "bsm1cFI7hhC0zj7wvllOScDJKporKySjStBNr8xm+dY=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -507,7 +508,7 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "3.1.2", + "aspect_rules_js": "3.2.0", "aspect_rules_ts": "3.8.10", "aspect_rules_esbuild": "0.26.0", "aspect_rules_jasmine": "2.0.4", @@ -952,7 +953,7 @@ "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "oZFClfRhTTwsYzpxVPkOpOt/r0+OzEfEV37au0jFZ0s=", - "usagesDigest": "28HwARS2PIkmyhXuiSyS1jAaG14m/bsZo/Sm+OPn2M8=", + "usagesDigest": "00+3uj4j6s/drSt+SUad8w/R4Rp2/GHGBsCgrKvF7mE=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -2603,7 +2604,7 @@ }, "@@rules_python+//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "1CieYf7PBGYmx4QxddIeJFyAiJ2OB1ah39h4F4rtjxo=", + "bzlTransitiveDigest": "JOGVSMFw3XSY/6/iPEgXTZqFR5YFbDaa20WiXWZ8m4U=", "usagesDigest": "AK1R124YPWwAs8z1CQYyjYuci8RO5Ofot+EP5ZCNQDc=", "recordedFileInputs": { "@@protobuf+//python/requirements.txt": "983be60d3cec4b319dcab6d48aeb3f5b2f7c3350f26b3a9e97486c37967c73c5", @@ -5342,7 +5343,7 @@ "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", - "usagesDigest": "8e3rbqq064p0a9Kvcmva2jmDBY/XStrYwTWmi2gmqTY=", + "usagesDigest": "6JGNN6+d6JD7F98c3T4zg7eUxkfsfsMEDemA2CIoNQQ=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, From 277934035138c5af803e8daeebc2313f0a4cb5b3 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:10:04 -0400 Subject: [PATCH 08/23] fix(@angular/cli): validate registry option is a valid URL in ng add Ensure that the --registry option passed to ng add is parsed as a valid absolute URL. (cherry picked from commit be251999be4ac6ecc685347271db10ad3c04ee62) --- packages/angular/cli/src/commands/add/cli.ts | 12 ++++++++ .../e2e/tests/commands/add/registry-option.ts | 28 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index b1c57a59ad45..dd78b7038120 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -16,6 +16,7 @@ import npa from 'npm-package-arg'; import semver, { Range, compare, intersects, prerelease, satisfies, valid } from 'semver'; import { Argv } from 'yargs'; import { + CommandModuleError, CommandModuleImplementation, Options, OtherOptions, @@ -131,6 +132,17 @@ export default class AddCommandModule type: 'boolean', default: false, }) + .check(({ registry }) => { + if (registry === undefined) { + return true; + } + + if (typeof registry === 'string' && URL.canParse(registry)) { + return true; + } + + throw new CommandModuleError('Option --registry must be a valid URL.'); + }) // Prior to downloading we don't know the full schema and therefore we cannot be strict on the options. // Possibly in the future update the logic to use the following syntax: // `ng add @angular/localize -- --package-options`. diff --git a/tests/e2e/tests/commands/add/registry-option.ts b/tests/e2e/tests/commands/add/registry-option.ts index dc336cdd5b30..1343cebf4dd1 100644 --- a/tests/e2e/tests/commands/add/registry-option.ts +++ b/tests/e2e/tests/commands/add/registry-option.ts @@ -1,11 +1,37 @@ import { getGlobalVariable } from '../../../utils/env'; import { expectFileToExist } from '../../../utils/fs'; -import { ng } from '../../../utils/process'; +import { execAndCaptureError, ng } from '../../../utils/process'; import { expectToFail } from '../../../utils/utils'; export default async function () { const testRegistry = getGlobalVariable('package-registry'); + // Validate that a non-URL registry string fails with a validation error + const error = await execAndCaptureError('ng', [ + 'add', + '--registry=not-a-valid-url', + '@angular/pwa', + '--skip-confirmation', + ]); + if (!error.message.includes('Option --registry must be a valid URL.')) { + throw new Error( + `Expected registry validation error, but got different error: ${error.message}`, + ); + } + + // Validate that an empty registry string fails with a validation error + const errorEmpty = await execAndCaptureError('ng', [ + 'add', + '--registry=', + '@angular/pwa', + '--skip-confirmation', + ]); + if (!errorEmpty.message.includes('Option --registry must be a valid URL.')) { + throw new Error( + `Expected registry validation error for empty string, but got: ${errorEmpty.message}`, + ); + } + // Set an invalid registry process.env['NPM_CONFIG_REGISTRY'] = 'http://127.0.0.1:9999'; From 979b781ee1f10bc868e62ff7a80ca2da5bdb3c8c Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 10:14:10 +0000 Subject: [PATCH 09/23] build: lock file maintenance See associated pull request for more information. --- pnpm-lock.yaml | 818 +++++++++++++++++++++++++------------------------ 1 file changed, 425 insertions(+), 393 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34620d846b3f..75a4b26ab553 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,7 +90,7 @@ importers: version: 6.0.0(rollup@4.60.2) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.2(rollup@4.60.2) + version: 29.0.3(rollup@4.60.2) '@rollup/plugin-json': specifier: ^6.1.0 version: 6.1.0(rollup@4.60.2) @@ -2037,8 +2037,8 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.7.1': - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@exodus/bytes@1.15.1': @@ -2351,13 +2351,13 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@2.0.5': - resolution: {integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/ansi@2.0.7': + resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/checkbox@5.1.5': - resolution: {integrity: sha512-Jmf9tgBHIEK5SAOB7swYfStqmtkZb00xOTpSQmkoGEpdxOTpJi9RS0A8bkfDPHTTItZRJrRdZrEMu25wyj0VfQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/checkbox@5.2.1': + resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2373,76 +2373,76 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.0.13': - resolution: {integrity: sha512-wkGPC7yJ5WJk1DJ5SX7fzk+gfj4BM8cf5dDDi71B/551xHrdsZVRJOC0WyikXd0pEsb/9cLniuE4atbsMqmFkw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/confirm@6.1.1': + resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/core@11.1.10': - resolution: {integrity: sha512-a4Q5BXHQAHa9eO202sTaFCHFYVB3x5fauDuThEAdZ9gfn76pSxiKU7wWcEH0N1O0XmQvNfQNU6QXpiRxmYQx+A==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/core@11.2.1': + resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/editor@5.1.2': - resolution: {integrity: sha512-Y3Nor7S/DhIPo+8Ym/dSY4efwKI4BsflKDwXh0jNeXJsSF3dteS/3Yf+z4wkibVZDvYMyCgknSTQlNahfunGHg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/editor@5.2.2': + resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/expand@5.0.14': - resolution: {integrity: sha512-qyY9zcIX2eKYwaAUiQo9zORd61Lc3sXeM72fVbeHkYnDkqfr8/armcRbmVAIrExeJhI2puk+uomeKtWrpUVUmQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/expand@5.1.1': + resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/external-editor@3.0.0': - resolution: {integrity: sha512-lDSwMgg+M5rq6JKBYaJwSX6T9e/HK2qqZ1oxmOwn4AQoJE5D+7TumsxLGC02PWS//rkIVqbZv3XA3ejsc9FYvg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/external-editor@3.0.3': + resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/figures@2.0.5': - resolution: {integrity: sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/figures@2.0.7': + resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/input@5.0.13': - resolution: {integrity: sha512-0l0jCHlJnXIV8CTxwQC0C+5Ziq8WP22edWgmciW2xYvoeoSck4v5FvCS1ctKdqLLR0dUo93uAHgWHywgBSoRyw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/input@5.1.2': + resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/number@4.0.13': - resolution: {integrity: sha512-WHmkYnnJAou5gx7RgcvAfUggnHNM1zWfoh0dFPl3dxVssuqt+dK5rIbaOYQXNyOegvFnopbKupjnhw2O8gANNg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/number@4.1.1': + resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/password@5.0.13': - resolution: {integrity: sha512-XDGu64ROHZjOOXLAANvJN7iIxWKhOSCG5VakrZ5kaScVR+snVJCFglD/hL3/677awtWcu4pXoWa280CDIYcBeg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/password@5.1.1': + resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2467,27 +2467,27 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.2.9': - resolution: {integrity: sha512-a1ErXEfgjfPYpyQ89dp+7n2IISjH9oQg3ygvF5adz8B7aHn4n2PjEgu1wpVTp69K3bj3lVLxP0qJ2b1clk1Whw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/rawlist@5.3.1': + resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/search@4.1.9': - resolution: {integrity: sha512-ZlbM28Q9lmLkFPNAIv+ZuY530n5Km8U1WW48oYEvDhe9yc2uL3m3t+JSdRUkQlk5fuIuskgiIVjcb7czFzQpuA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/search@4.2.1': + resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/select@5.1.5': - resolution: {integrity: sha512-6SRg6kHfK/sjLXOsuqNebuir+sjwrf/iWuRUnXgB2slzEewppI1WfzeS16XxDcOQmXBruMmmB9Cgrz7wsAxqMg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/select@5.2.1': + resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2503,6 +2503,15 @@ packages: '@types/node': optional: true + '@inquirer/type@4.0.7': + resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -2576,50 +2585,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.57.2': - resolution: {integrity: sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==} + '@jsonjoy.com/fs-core@4.57.5': + resolution: {integrity: sha512-wl7eAKUwOcEZ8lL2/C38+w6VnNtBiNmvzKstlKPqRV/ymzg/7Aal5H74HEazSM2khYn9XG20I3fRp0Wr7xIbHA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.57.2': - resolution: {integrity: sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==} + '@jsonjoy.com/fs-fsa@4.57.5': + resolution: {integrity: sha512-zIUMYeOgAdhA1M3JvceA2Fli7qas2WJrv6qmruXbq81bgIRKUM1LueJ1G0VRPk4D8wfOceBpayWQZqSEXA0AGA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.57.2': - resolution: {integrity: sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==} + '@jsonjoy.com/fs-node-builtins@4.57.5': + resolution: {integrity: sha512-maev+EH0kBJt7R6GZQgRmL5cHvs46PS71Y5M1FfZKN2/JVSAZPpdrLS+z7KYrvPn4oIYMKcG/XAhircG3eP88g==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.57.2': - resolution: {integrity: sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==} + '@jsonjoy.com/fs-node-to-fsa@4.57.5': + resolution: {integrity: sha512-6IQi4TNoR1d+cSRZisWh6eqQ2mq32qgwESjVeXDs2pMWa+H/pZ24kSJKrDkyooUIfk1OIe40Dv9bnqc0FMcFjQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.57.2': - resolution: {integrity: sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==} + '@jsonjoy.com/fs-node-utils@4.57.5': + resolution: {integrity: sha512-u8GXaNr2VeQvHBXbJ9byY6GWP5z3HK3kCmdEPwVzjcgpEyAPjNnl0alP3Ylo6Aa4JSS8Ssc/F4+q69/03J2bUA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.57.2': - resolution: {integrity: sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==} + '@jsonjoy.com/fs-node@4.57.5': + resolution: {integrity: sha512-F6kdnfsmK6q+WEjGhCOd/2iJpcmffj8q3qgXUG1/gHMXaThZp30Ienk3eMT+GfOpEbuVqoPvqNe8IwiPlDk/QQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.57.2': - resolution: {integrity: sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==} + '@jsonjoy.com/fs-print@4.57.5': + resolution: {integrity: sha512-fTcwBpqk9CEmzYd4Un4WxemvWbS69dGFEQgYmCQ0q02xsMzsZcTKzd3kduB46DBhjRTK77ga4HIQe08Oyn86kg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.57.2': - resolution: {integrity: sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==} + '@jsonjoy.com/fs-snapshot@4.57.5': + resolution: {integrity: sha512-oAUUlG+E4uBw5sFERdMu3FRqt0hEM6jVCIKWkj194xiWppfShAqbMK5G3PahBXfGiTtlJjYErUWDbX3UhQhldw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2715,33 +2724,33 @@ packages: '@cfworker/json-schema': optional: true - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': - resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==} cpu: [arm64] os: [darwin] - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': - resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==} cpu: [x64] os: [darwin] - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': - resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==} cpu: [arm64] os: [linux] - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': - resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==} cpu: [arm] os: [linux] - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': - resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': + resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==} cpu: [x64] os: [linux] - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': - resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==} cpu: [x64] os: [win32] @@ -2884,8 +2893,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@4.0.0': - resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} + '@npmcli/agent@4.0.2': + resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==} engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/fs@5.0.0': @@ -2989,8 +2998,8 @@ packages: resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} engines: {node: '>= 20'} - '@octokit/request@10.0.9': - resolution: {integrity: sha512-o8Bi3f608eyM+7BmBiUWxFsdjLb3/ym1cQek5LZOv9KkZcxRrHCPhhRzm6xjO6HVZ85ItD6+sTsjxo821SVa/A==} + '@octokit/request@10.0.10': + resolution: {integrity: sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -3326,8 +3335,8 @@ packages: rollup: optional: true - '@rollup/plugin-commonjs@29.0.2': - resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} + '@rollup/plugin-commonjs@29.0.3': + resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -3362,6 +3371,15 @@ packages: rollup: optional: true + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.60.2': resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} cpu: [arm] @@ -3846,8 +3864,8 @@ packages: resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.4': - resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} + '@typescript-eslint/types@8.60.1': + resolution: {integrity: sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.59.1': @@ -4238,8 +4256,8 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} - ast-v8-to-istanbul@1.0.2: - resolution: {integrity: sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ==} + ast-v8-to-istanbul@1.0.3: + resolution: {integrity: sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==} async-each-series@0.1.1: resolution: {integrity: sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==} @@ -4327,16 +4345,16 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - bare-events@2.8.3: - resolution: {integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==} + bare-events@2.9.1: + resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: bare-abort-controller: optional: true - bare-fs@4.7.1: - resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==} + bare-fs@4.7.2: + resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -4348,8 +4366,8 @@ packages: resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} engines: {bare: '>=1.14.0'} - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + bare-path@3.0.1: + resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} bare-stream@2.13.1: resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} @@ -4375,8 +4393,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.32: - resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + baseline-browser-mapping@2.10.33: + resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4430,8 +4448,8 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + brace-expansion@1.1.15: + resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} brace-expansion@2.1.1: resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} @@ -5013,8 +5031,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.361: - resolution: {integrity: sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==} + electron-to-chromium@1.5.366: + resolution: {integrity: sha512-OlRuhb688YTCzzU3gXPLn6nGyd+F+53INE1qaKKlu6kETErE8FYsyDh0XqXEU+uBRn0MpCzz2vfNwORhkap8qg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5054,8 +5072,8 @@ packages: resolution: {integrity: sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.22.0: - resolution: {integrity: sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==} + enhanced-resolve@5.22.1: + resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} engines: {node: '>=10.13.0'} ent@2.2.2: @@ -5165,8 +5183,8 @@ packages: eslint-import-resolver-node@0.3.10: resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + eslint-module-utils@2.13.0: + resolution: {integrity: sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -5289,8 +5307,8 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.8: - resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} + eventsource-parser@3.1.0: + resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} engines: {node: '>=18.0.0'} eventsource@3.0.7: @@ -5337,9 +5355,6 @@ packages: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} - fast-content-type-parse@3.0.0: - resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -5647,8 +5662,8 @@ packages: peerDependencies: graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - graphql@16.14.0: - resolution: {integrity: sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q==} + graphql@16.14.1: + resolution: {integrity: sha512-cQOsSMS/IrDz82PVyRDvf/Q1F/bRbBVjJlh+xYOkI1qw2bWRvWGiWc+m2O0d6l4Bt1fyY+8kzJ8JFWGJqNeDBg==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} grpc-gcp@1.0.1: @@ -5692,8 +5707,8 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} hono@4.12.23: @@ -5839,8 +5854,8 @@ packages: resolution: {integrity: sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==} engines: {node: '>=0.10.0'} - immutable@5.1.5: - resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} + immutable@5.1.6: + resolution: {integrity: sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -6177,6 +6192,10 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + hasBin: true + jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} @@ -6299,8 +6318,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - launch-editor@2.13.2: - resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} less-loader@12.3.2: resolution: {integrity: sha512-uLV5c702ff2jBvO7qewpkLRzkh/I9QW07ur2NKkv8TVTrtX2lrKjEbEU/LLXAn7cgpCIBbkfyUm4qYXCQs5/+w==} @@ -6430,8 +6449,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.0: - resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -6455,8 +6474,8 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-fetch-happen@15.0.5: - resolution: {integrity: sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg==} + make-fetch-happen@15.0.6: + resolution: {integrity: sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==} engines: {node: ^20.17.0 || >=22.9.0} math-intrinsics@1.1.0: @@ -6474,8 +6493,8 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} - memfs@4.57.2: - resolution: {integrity: sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==} + memfs@4.57.5: + resolution: {integrity: sha512-qT8bQJyjF6+DsDI9X1yMwUyIkYHrZI8D2PaWjze8aUUbGUkcNlxppcRZF/0VWesIPHtgx6T2mLx3qPmTQxUd6A==} peerDependencies: tslib: '2' @@ -6636,8 +6655,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msgpackr-extract@3.0.3: - resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + msgpackr-extract@3.0.4: + resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} hasBin: true msgpackr@1.11.12: @@ -6757,8 +6776,8 @@ packages: engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.46: - resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + node-releases@2.0.47: + resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} nopt@9.0.0: @@ -7190,8 +7209,8 @@ packages: resolution: {integrity: sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==} engines: {node: '>=18'} - protobufjs@7.6.1: - resolution: {integrity: sha512-4K0myLaWL5EteuSAro91EGFgcfVgxb64Jx+7oDAY6GOkXD4M69yuSEljNcInGVCA5sOPxmZ/EqDLj2x0Q0+Ygg==} + protobufjs@7.6.2: + resolution: {integrity: sha512-N9EiLovGEQOJSPF26Ij7qUGvahfEnq0eeYZ02aigIedkmz1qZSwjnP9SBITHJuF/6MYbIW4HDN8zdYjsjqJKXQ==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: @@ -7797,8 +7816,8 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamx@2.25.0: - resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} + streamx@2.26.0: + resolution: {integrity: sha512-VvNG1K72Po/xwJzxZFnZ++Tbrv4lwSptsbkFuzXCJAYZvCK5nnxsvXU6ajqkv7chyiI1Y0YXq2Jh8Iy8Y7NF/A==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -7888,8 +7907,8 @@ packages: tar-stream@3.2.0: resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} - tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} + tar@7.5.16: + resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} teeny-request@10.1.2: @@ -7899,8 +7918,8 @@ packages: teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser-webpack-plugin@5.6.0: - resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} + terser-webpack-plugin@5.6.1: + resolution: {integrity: sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -7956,8 +7975,8 @@ packages: peerDependencies: tslib: ^2 - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + thread-stream@3.2.0: + resolution: {integrity: sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==} through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} @@ -7977,8 +7996,8 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.2.2: - resolution: {integrity: sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} tinyglobby@0.2.16: @@ -7992,19 +8011,19 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.3.1: - resolution: {integrity: sha512-CSjiLuHll9lt9l+jf0poLVfgddqGAj4vUHoipeTPx3RvVjgCu/krg7t7lsW000y9vNBP34FbXH8S6BuciRtoIw==} + tldts-core@7.4.2: + resolution: {integrity: sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.3.1: - resolution: {integrity: sha512-+tHFHaNlvYCC1g4cwAcPWy/0BXvWZCMVk6WwohwXUupkcFYKpX3EH1jD8gRMIbDBbVKGKzacFf9aSsdXISKz0g==} + tldts@7.4.2: + resolution: {integrity: sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==} hasBin: true - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} to-regex-range@5.0.1: @@ -8105,8 +8124,8 @@ packages: resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + typed-array-length@1.0.8: + resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==} engines: {node: '>= 0.4'} typed-assert@1.0.9: @@ -8146,12 +8165,12 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@6.25.0: - resolution: {integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==} + undici@6.26.0: + resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==} engines: {node: '>=18.17'} - undici@7.25.0: - resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} + undici@7.27.0: + resolution: {integrity: sha512-+t2Z/GwkZQDtu00813aP66ygViGtPHKhhoFZpQKpKrE+9jIgES+Zw+mFNaDWOVRKiuJjuqKHzD3B1sfGg8+ZOQ==} engines: {node: '>=20.18.1'} undici@8.2.0: @@ -8466,8 +8485,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + which-typed-array@1.1.21: + resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==} engines: {node: '>= 0.4'} which@1.3.1: @@ -8656,7 +8675,7 @@ snapshots: '@actions/http-client@4.0.1': dependencies: tunnel: 0.0.6 - undici: 6.25.0 + undici: 6.26.0 '@actions/io@3.0.2': {} @@ -9910,7 +9929,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -9922,7 +9941,7 @@ snapshots: '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.7.1': + '@eslint/plugin-kit@0.7.2': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 @@ -10297,12 +10316,12 @@ snapshots: extend: 3.0.2 google-auth-library: 10.6.2(supports-color@10.2.2) google-gax: 5.0.6(supports-color@10.2.2) - grpc-gcp: 1.0.1(protobufjs@7.6.1) + grpc-gcp: 1.0.1(protobufjs@7.6.2) is: 3.3.2 lodash.snakecase: 4.1.1 merge-stream: 2.0.0 p-queue: 6.6.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 retry-request: 8.0.2(supports-color@10.2.2) split-array-stream: 2.0.0 stack-trace: 0.0.10 @@ -10316,7 +10335,7 @@ snapshots: dependencies: google-auth-library: 10.6.2(supports-color@10.2.2) p-retry: 4.6.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.2) @@ -10339,14 +10358,14 @@ snapshots: dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 yargs: 17.7.2 '@grpc/proto-loader@0.8.1': dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 yargs: 17.7.2 '@harperfast/extended-iterable@1.0.3': @@ -10372,36 +10391,36 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@2.0.5': {} + '@inquirer/ansi@2.0.7': {} - '@inquirer/checkbox@5.1.5(@types/node@24.12.4)': + '@inquirer/checkbox@5.2.1(@types/node@24.12.4)': dependencies: - '@inquirer/ansi': 2.0.5 - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 '@inquirer/confirm@6.0.12(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/confirm@6.0.13(@types/node@24.12.4)': + '@inquirer/confirm@6.1.1(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/core@11.1.10(@types/node@24.12.4)': + '@inquirer/core@11.2.1(@types/node@24.12.4)': dependencies: - '@inquirer/ansi': 2.0.5 - '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 @@ -10409,103 +10428,103 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/editor@5.1.2(@types/node@24.12.4)': + '@inquirer/editor@5.2.2(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/external-editor': 3.0.0(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/external-editor': 3.0.3(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/expand@5.0.14(@types/node@24.12.4)': + '@inquirer/expand@5.1.1(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/external-editor@3.0.0(@types/node@24.12.4)': + '@inquirer/external-editor@3.0.3(@types/node@24.12.4)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: '@types/node': 24.12.4 - '@inquirer/figures@2.0.5': {} + '@inquirer/figures@2.0.7': {} - '@inquirer/input@5.0.13(@types/node@24.12.4)': + '@inquirer/input@5.1.2(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/number@4.0.13(@types/node@24.12.4)': + '@inquirer/number@4.1.1(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/password@5.0.13(@types/node@24.12.4)': + '@inquirer/password@5.1.1(@types/node@24.12.4)': dependencies: - '@inquirer/ansi': 2.0.5 - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 '@inquirer/prompts@8.4.2(@types/node@24.12.4)': dependencies: - '@inquirer/checkbox': 5.1.5(@types/node@24.12.4) + '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) '@inquirer/confirm': 6.0.12(@types/node@24.12.4) - '@inquirer/editor': 5.1.2(@types/node@24.12.4) - '@inquirer/expand': 5.0.14(@types/node@24.12.4) - '@inquirer/input': 5.0.13(@types/node@24.12.4) - '@inquirer/number': 4.0.13(@types/node@24.12.4) - '@inquirer/password': 5.0.13(@types/node@24.12.4) - '@inquirer/rawlist': 5.2.9(@types/node@24.12.4) - '@inquirer/search': 4.1.9(@types/node@24.12.4) - '@inquirer/select': 5.1.5(@types/node@24.12.4) + '@inquirer/editor': 5.2.2(@types/node@24.12.4) + '@inquirer/expand': 5.1.1(@types/node@24.12.4) + '@inquirer/input': 5.1.2(@types/node@24.12.4) + '@inquirer/number': 4.1.1(@types/node@24.12.4) + '@inquirer/password': 5.1.1(@types/node@24.12.4) + '@inquirer/rawlist': 5.3.1(@types/node@24.12.4) + '@inquirer/search': 4.2.1(@types/node@24.12.4) + '@inquirer/select': 5.2.1(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 '@inquirer/prompts@8.4.3(@types/node@24.12.4)': dependencies: - '@inquirer/checkbox': 5.1.5(@types/node@24.12.4) - '@inquirer/confirm': 6.0.13(@types/node@24.12.4) - '@inquirer/editor': 5.1.2(@types/node@24.12.4) - '@inquirer/expand': 5.0.14(@types/node@24.12.4) - '@inquirer/input': 5.0.13(@types/node@24.12.4) - '@inquirer/number': 4.0.13(@types/node@24.12.4) - '@inquirer/password': 5.0.13(@types/node@24.12.4) - '@inquirer/rawlist': 5.2.9(@types/node@24.12.4) - '@inquirer/search': 4.1.9(@types/node@24.12.4) - '@inquirer/select': 5.1.5(@types/node@24.12.4) + '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) + '@inquirer/confirm': 6.1.1(@types/node@24.12.4) + '@inquirer/editor': 5.2.2(@types/node@24.12.4) + '@inquirer/expand': 5.1.1(@types/node@24.12.4) + '@inquirer/input': 5.1.2(@types/node@24.12.4) + '@inquirer/number': 4.1.1(@types/node@24.12.4) + '@inquirer/password': 5.1.1(@types/node@24.12.4) + '@inquirer/rawlist': 5.3.1(@types/node@24.12.4) + '@inquirer/search': 4.2.1(@types/node@24.12.4) + '@inquirer/select': 5.2.1(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/rawlist@5.2.9(@types/node@24.12.4)': + '@inquirer/rawlist@5.3.1(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/search@4.1.9(@types/node@24.12.4)': + '@inquirer/search@4.2.1(@types/node@24.12.4)': dependencies: - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/select@5.1.5(@types/node@24.12.4)': + '@inquirer/select@5.2.1(@types/node@24.12.4)': dependencies: - '@inquirer/ansi': 2.0.5 - '@inquirer/core': 11.1.10(@types/node@24.12.4) - '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 @@ -10513,6 +10532,10 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/type@4.0.7(@types/node@24.12.4)': + optionalDependencies: + '@types/node': 24.12.4 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -10580,58 +10603,58 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.57.5(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.57.5(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10688,7 +10711,7 @@ snapshots: '@listr2/prompt-adapter-inquirer@4.2.3(@inquirer/prompts@8.4.2(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1)': dependencies: '@inquirer/prompts': 8.4.2(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) listr2: 10.2.1 transitivePeerDependencies: - '@types/node' @@ -10723,7 +10746,7 @@ snapshots: cors: 2.8.6 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.8 + eventsource-parser: 3.1.0 express: 5.2.1 express-rate-limit: 8.5.2(express@5.2.1) hono: 4.12.23 @@ -10736,22 +10759,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': optional: true - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': optional: true - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': optional: true - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': optional: true - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': optional: true - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': optional: true '@mswjs/interceptors@0.41.9': @@ -10856,12 +10879,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@npmcli/agent@4.0.0': + '@npmcli/agent@4.0.2': dependencies: agent-base: 7.1.4 http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) - lru-cache: 11.5.0 + lru-cache: 11.5.1 socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color @@ -10875,7 +10898,7 @@ snapshots: '@gar/promise-retry': 1.0.3 '@npmcli/promise-spawn': 9.0.1 ini: 6.0.0 - lru-cache: 11.5.0 + lru-cache: 11.5.1 npm-pick-manifest: 11.0.3 proc-log: 6.1.0 semver: 7.7.4 @@ -10916,7 +10939,7 @@ snapshots: dependencies: '@octokit/auth-oauth-app': 9.0.3 '@octokit/auth-oauth-user': 6.0.2 - '@octokit/request': 10.0.9 + '@octokit/request': 10.0.10 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 toad-cache: 3.7.1 @@ -10927,14 +10950,14 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.3 '@octokit/auth-oauth-user': 6.0.2 - '@octokit/request': 10.0.9 + '@octokit/request': 10.0.10 '@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.9 + '@octokit/request': 10.0.10 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -10942,7 +10965,7 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.3 '@octokit/oauth-methods': 6.0.2 - '@octokit/request': 10.0.9 + '@octokit/request': 10.0.10 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -10952,7 +10975,7 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.9 + '@octokit/request': 10.0.10 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 before-after-hook: 4.0.0 @@ -10965,12 +10988,12 @@ snapshots: '@octokit/graphql-schema@15.26.1': dependencies: - graphql: 16.14.0 - graphql-tag: 2.12.6(graphql@16.14.0) + graphql: 16.14.1 + graphql-tag: 2.12.6(graphql@16.14.1) '@octokit/graphql@9.0.3': dependencies: - '@octokit/request': 10.0.9 + '@octokit/request': 10.0.10 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -10979,7 +11002,7 @@ snapshots: '@octokit/oauth-methods@6.0.2': dependencies: '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/request': 10.0.9 + '@octokit/request': 10.0.10 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 @@ -11003,13 +11026,12 @@ snapshots: dependencies: '@octokit/types': 16.0.0 - '@octokit/request@10.0.9': + '@octokit/request@10.0.10': dependencies: '@octokit/endpoint': 11.0.3 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 content-type: 2.0.0 - fast-content-type-parse: 3.0.0 json-with-bigint: 3.5.8 universal-user-agent: 7.0.3 @@ -11320,9 +11342,9 @@ snapshots: optionalDependencies: rollup: 4.60.2 - '@rollup/plugin-commonjs@29.0.2(rollup@4.60.2)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.60.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + '@rollup/pluginutils': 5.4.0(rollup@4.60.2) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.4) @@ -11334,13 +11356,13 @@ snapshots: '@rollup/plugin-json@6.1.0(rollup@4.60.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + '@rollup/pluginutils': 5.4.0(rollup@4.60.2) optionalDependencies: rollup: 4.60.2 '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + '@rollup/pluginutils': 5.4.0(rollup@4.60.2) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 @@ -11356,6 +11378,14 @@ snapshots: optionalDependencies: rollup: 4.60.2 + '@rollup/pluginutils@5.4.0(rollup@4.60.2)': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.2 + '@rollup/rollup-android-arm-eabi@4.60.2': optional: true @@ -11453,7 +11483,7 @@ snapshots: '@sigstore/bundle': 4.0.0 '@sigstore/core': 3.2.1 '@sigstore/protobuf-specs': 0.5.1 - make-fetch-happen: 15.0.5 + make-fetch-happen: 15.0.6 proc-log: 6.1.0 transitivePeerDependencies: - supports-color @@ -11486,7 +11516,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.3.0(jiti@2.7.0))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@2.7.0)) - '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/types': 8.60.1 eslint: 10.3.0(jiti@2.7.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11874,7 +11904,7 @@ snapshots: '@typescript-eslint/types@8.59.1': {} - '@typescript-eslint/types@8.59.4': {} + '@typescript-eslint/types@8.60.1': {} '@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3)': dependencies: @@ -12093,7 +12123,7 @@ snapshots: dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.5 - ast-v8-to-istanbul: 1.0.2 + ast-v8-to-istanbul: 1.0.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 @@ -12435,7 +12465,7 @@ snapshots: dependencies: tslib: 2.8.1 - ast-v8-to-istanbul@1.0.2: + ast-v8-to-istanbul@1.0.3: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -12517,13 +12547,13 @@ snapshots: balanced-match@4.0.4: {} - bare-events@2.8.3: {} + bare-events@2.9.1: {} - bare-fs@4.7.1: + bare-fs@4.7.2: dependencies: - bare-events: 2.8.3 - bare-path: 3.0.0 - bare-stream: 2.13.1(bare-events@2.8.3) + bare-events: 2.9.1 + bare-path: 3.0.1 + bare-stream: 2.13.1(bare-events@2.9.1) bare-url: 2.4.3 fast-fifo: 1.3.2 transitivePeerDependencies: @@ -12532,28 +12562,28 @@ snapshots: bare-os@3.9.1: {} - bare-path@3.0.0: + bare-path@3.0.1: dependencies: bare-os: 3.9.1 - bare-stream@2.13.1(bare-events@2.8.3): + bare-stream@2.13.1(bare-events@2.9.1): dependencies: - streamx: 2.25.0 + streamx: 2.26.0 teex: 1.0.1 optionalDependencies: - bare-events: 2.8.3 + bare-events: 2.9.1 transitivePeerDependencies: - react-native-b4a bare-url@2.4.3: dependencies: - bare-path: 3.0.0 + bare-path: 3.0.1 base64-js@1.5.1: {} base64id@2.0.0: {} - baseline-browser-mapping@2.10.32: {} + baseline-browser-mapping@2.10.33: {} basic-ftp@5.3.1: {} @@ -12629,7 +12659,7 @@ snapshots: boolbase@1.0.0: {} - brace-expansion@1.1.14: + brace-expansion@1.1.15: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 @@ -12710,10 +12740,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.32 + baseline-browser-mapping: 2.10.33 caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.361 - node-releases: 2.0.46 + electron-to-chromium: 1.5.366 + node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) bs-recipes@1.3.4: {} @@ -12746,7 +12776,7 @@ snapshots: '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 glob: 13.0.6 - lru-cache: 11.5.0 + lru-cache: 11.5.1 minipass: 7.1.3 minipass-collect: 2.0.1 minipass-flush: 1.0.7 @@ -13010,7 +13040,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 parse-json: 5.2.0 optionalDependencies: typescript: 6.0.3 @@ -13258,7 +13288,7 @@ snapshots: ejs@5.0.2: {} - electron-to-chromium@1.5.361: {} + electron-to-chromium@1.5.366: {} emoji-regex@10.6.0: {} @@ -13311,7 +13341,7 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.22.0: + enhanced-resolve@5.22.1: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -13368,7 +13398,7 @@ snapshots: has-property-descriptors: 1.0.2 has-proto: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 internal-slot: 1.1.0 is-array-buffer: 3.0.5 is-callable: 1.2.7 @@ -13397,9 +13427,9 @@ snapshots: typed-array-buffer: 1.0.3 typed-array-byte-length: 1.0.3 typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 + typed-array-length: 1.0.8 unbox-primitive: 1.1.0 - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 es-define-property@1.0.1: {} @@ -13416,11 +13446,11 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.4 es-shim-unscopables@1.1.0: dependencies: - hasown: 2.0.3 + hasown: 2.0.4 es-to-primitive@1.3.0: dependencies: @@ -13514,7 +13544,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.1(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.3.0(jiti@2.7.0)): + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.59.1(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.3.0(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: @@ -13535,8 +13565,8 @@ snapshots: doctrine: 2.1.0 eslint: 10.3.0(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.1(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.3.0(jiti@2.7.0)) - hasown: 2.0.3 + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.59.1(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.3.0(jiti@2.7.0)) + hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 minimatch: 3.1.5 @@ -13578,7 +13608,7 @@ snapshots: '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.5.5 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -13654,17 +13684,17 @@ snapshots: events-universal@1.0.1: dependencies: - bare-events: 2.8.3 + bare-events: 2.9.1 transitivePeerDependencies: - bare-abort-controller events@3.3.0: {} - eventsource-parser@3.0.8: {} + eventsource-parser@3.1.0: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.8 + eventsource-parser: 3.1.0 expect-type@1.3.0: {} @@ -13796,8 +13826,6 @@ snapshots: extsprintf@1.3.0: {} - fast-content-type-parse@3.0.0: {} - fast-deep-equal@3.1.3: {} fast-fifo@1.3.2: {} @@ -13985,7 +14013,7 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.3 + hasown: 2.0.4 mime-types: 2.1.35 formdata-polyfill@4.0.10: @@ -14029,7 +14057,7 @@ snapshots: call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 - hasown: 2.0.3 + hasown: 2.0.4 is-callable: 1.2.7 functions-have-names@1.2.3: {} @@ -14068,7 +14096,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 math-intrinsics: 1.1.0 get-npm-tarball-url@2.1.0: {} @@ -14170,7 +14198,7 @@ snapshots: node-fetch: 3.3.2 object-hash: 3.0.0 proto3-json-serializer: 3.0.4 - protobufjs: 7.6.1 + protobufjs: 7.6.2 retry-request: 8.0.2(supports-color@10.2.2) rimraf: 5.0.10 transitivePeerDependencies: @@ -14197,17 +14225,17 @@ snapshots: graceful-fs@4.2.11: {} - graphql-tag@2.12.6(graphql@16.14.0): + graphql-tag@2.12.6(graphql@16.14.1): dependencies: - graphql: 16.14.0 + graphql: 16.14.1 tslib: 2.8.1 - graphql@16.14.0: {} + graphql@16.14.1: {} - grpc-gcp@1.0.1(protobufjs@7.6.1): + grpc-gcp@1.0.1(protobufjs@7.6.2): dependencies: '@grpc/grpc-js': 1.14.4 - protobufjs: 7.6.1 + protobufjs: 7.6.2 gunzip-maybe@1.4.2: dependencies: @@ -14247,7 +14275,7 @@ snapshots: dependencies: has-symbols: 1.1.0 - hasown@2.0.3: + hasown@2.0.4: dependencies: function-bind: 1.1.2 @@ -14255,7 +14283,7 @@ snapshots: hosted-git-info@9.0.3: dependencies: - lru-cache: 11.5.0 + lru-cache: 11.5.1 hpack.js@2.1.6: dependencies: @@ -14420,7 +14448,7 @@ snapshots: immutable@3.8.3: {} - immutable@5.1.5: {} + immutable@5.1.6: {} import-fresh@3.3.1: dependencies: @@ -14445,7 +14473,7 @@ snapshots: internal-slot@1.1.0: dependencies: es-errors: 1.3.0 - hasown: 2.0.3 + hasown: 2.0.4 side-channel: 1.1.0 ip-address@10.2.0: {} @@ -14487,7 +14515,7 @@ snapshots: is-core-module@2.16.2: dependencies: - hasown: 2.0.3 + hasown: 2.0.4 is-data-view@1.0.2: dependencies: @@ -14582,7 +14610,7 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.4 is-set@2.0.3: {} @@ -14605,7 +14633,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 is-typedarray@1.0.0: {} @@ -14734,6 +14762,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.2.0: + dependencies: + argparse: 2.0.1 + jsbn@0.1.1: {} jsdom@29.1.1: @@ -14748,12 +14780,12 @@ snapshots: decimal.js: 10.6.0 html-encoding-sniffer: 6.0.0 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.0 + lru-cache: 11.5.1 parse5: 8.0.1 saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.1 - undici: 7.25.0 + undici: 7.27.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -14890,7 +14922,7 @@ snapshots: rimraf: 3.0.2 socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) source-map: 0.6.1 - tmp: 0.2.5 + tmp: 0.2.7 ua-parser-js: 0.7.41 yargs: 16.2.0 transitivePeerDependencies: @@ -14905,7 +14937,7 @@ snapshots: kind-of@6.0.3: {} - launch-editor@2.13.2: + launch-editor@2.14.1: dependencies: picocolors: 1.1.1 shell-quote: 1.8.4 @@ -15051,7 +15083,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.5.0: {} + lru-cache@11.5.1: {} lru-cache@5.1.1: dependencies: @@ -15079,10 +15111,10 @@ snapshots: dependencies: semver: 7.7.4 - make-fetch-happen@15.0.5: + make-fetch-happen@15.0.6: dependencies: '@gar/promise-retry': 1.0.3 - '@npmcli/agent': 4.0.0 + '@npmcli/agent': 4.0.2 '@npmcli/redact': 4.0.0 cacache: 20.0.4 http-cache-semantics: 4.2.0 @@ -15104,16 +15136,16 @@ snapshots: media-typer@1.1.0: {} - memfs@4.57.2(tslib@2.8.1): + memfs@4.57.5(tslib@2.8.1): dependencies: - '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -15176,7 +15208,7 @@ snapshots: minimatch@3.1.5: dependencies: - brace-expansion: 1.1.14 + brace-expansion: 1.1.15 minimatch@7.4.6: dependencies: @@ -15242,21 +15274,21 @@ snapshots: ms@2.1.3: {} - msgpackr-extract@3.0.3: + msgpackr-extract@3.0.4: dependencies: node-gyp-build-optional-packages: 5.2.2 optionalDependencies: - '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 optional: true msgpackr@1.11.12: optionalDependencies: - msgpackr-extract: 3.0.3 + msgpackr-extract: 3.0.4 optional: true multicast-dns@7.2.5: @@ -15376,12 +15408,12 @@ snapshots: nopt: 9.0.0 proc-log: 6.1.0 semver: 7.7.4 - tar: 7.5.15 + tar: 7.5.16 tinyglobby: 0.2.16 - undici: 6.25.0 + undici: 6.26.0 which: 6.0.1 - node-releases@2.0.46: {} + node-releases@2.0.47: {} nopt@9.0.0: dependencies: @@ -15424,7 +15456,7 @@ snapshots: dependencies: '@npmcli/redact': 4.0.0 jsonparse: 1.3.1 - make-fetch-happen: 15.0.5 + make-fetch-happen: 15.0.6 minipass: 7.1.3 minipass-fetch: 5.0.2 minizlib: 3.1.0 @@ -15628,7 +15660,7 @@ snapshots: proc-log: 6.1.0 sigstore: 4.1.1 ssri: 13.0.1 - tar: 7.5.15 + tar: 7.5.16 transitivePeerDependencies: - supports-color @@ -15680,7 +15712,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.0 + lru-cache: 11.5.1 minipass: 7.1.3 path-to-regexp@0.1.13: {} @@ -15735,7 +15767,7 @@ snapshots: real-require: 0.2.0 safe-stable-stringify: 2.5.0 sonic-boom: 4.2.1 - thread-stream: 3.1.0 + thread-stream: 3.2.0 piscina@5.1.4: optionalDependencies: @@ -15844,9 +15876,9 @@ snapshots: proto3-json-serializer@3.0.4: dependencies: - protobufjs: 7.6.1 + protobufjs: 7.6.2 - protobufjs@7.6.1: + protobufjs@7.6.2: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -16289,7 +16321,7 @@ snapshots: sass@1.99.0: dependencies: chokidar: 4.0.3 - immutable: 5.1.5 + immutable: 5.1.6 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -16686,7 +16718,7 @@ snapshots: transitivePeerDependencies: - supports-color - streamx@2.25.0: + streamx@2.26.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -16786,8 +16818,8 @@ snapshots: pump: 3.0.4 tar-stream: 3.2.0 optionalDependencies: - bare-fs: 4.7.1 - bare-path: 3.0.0 + bare-fs: 4.7.2 + bare-path: 3.0.1 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -16797,7 +16829,7 @@ snapshots: dependencies: b4a: 1.8.1 fast-fifo: 1.3.2 - streamx: 2.25.0 + streamx: 2.26.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -16805,15 +16837,15 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.8.1 - bare-fs: 4.7.1 + bare-fs: 4.7.2 fast-fifo: 1.3.2 - streamx: 2.25.0 + streamx: 2.26.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer - react-native-b4a - tar@7.5.15: + tar@7.5.16: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -16832,12 +16864,12 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.25.0 + streamx: 2.26.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - terser-webpack-plugin@5.6.0(esbuild@0.28.0)(postcss@8.5.13)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): + terser-webpack-plugin@5.6.1(esbuild@0.28.0)(postcss@8.5.13)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -16848,7 +16880,7 @@ snapshots: esbuild: 0.28.0 postcss: 8.5.13 - terser-webpack-plugin@5.6.0(esbuild@0.28.0)(webpack@5.106.2(esbuild@0.28.0)): + terser-webpack-plugin@5.6.1(esbuild@0.28.0)(webpack@5.106.2(esbuild@0.28.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -16875,7 +16907,7 @@ snapshots: dependencies: tslib: 2.8.1 - thread-stream@3.1.0: + thread-stream@3.2.0: dependencies: real-require: 0.2.0 @@ -16896,7 +16928,7 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.2.2: {} + tinyexec@1.2.4: {} tinyglobby@0.2.16: dependencies: @@ -16907,17 +16939,17 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.3.1: {} + tldts-core@7.4.2: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.3.1: + tldts@7.4.2: dependencies: - tldts-core: 7.3.1 + tldts-core: 7.4.2 - tmp@0.2.5: {} + tmp@0.2.7: {} to-regex-range@5.0.1: dependencies: @@ -16933,7 +16965,7 @@ snapshots: tough-cookie@6.0.1: dependencies: - tldts: 7.3.1 + tldts: 7.4.2 tr46@0.0.3: {} @@ -16974,7 +17006,7 @@ snapshots: dependencies: '@tufjs/models': 4.1.0 debug: 4.4.3(supports-color@10.2.2) - make-fetch-happen: 15.0.5 + make-fetch-happen: 15.0.6 transitivePeerDependencies: - supports-color @@ -17027,7 +17059,7 @@ snapshots: is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 - typed-array-length@1.0.7: + typed-array-length@1.0.8: dependencies: call-bind: 1.0.9 for-each: 0.3.5 @@ -17062,9 +17094,9 @@ snapshots: undici-types@7.16.0: {} - undici@6.25.0: {} + undici@6.26.0: {} - undici@7.25.0: {} + undici@7.27.0: {} undici@8.2.0: {} @@ -17245,7 +17277,7 @@ snapshots: picomatch: 4.0.4 std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.2.2 + tinyexec: 1.2.4 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) @@ -17299,7 +17331,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): dependencies: colorette: 2.0.20 - memfs: 4.57.2(tslib@2.8.1) + memfs: 4.57.5(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17312,7 +17344,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2(esbuild@0.28.0)): dependencies: colorette: 2.0.20 - memfs: 4.57.2(tslib@2.8.1) + memfs: 4.57.5(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17324,7 +17356,7 @@ snapshots: webpack-dev-middleware@8.0.3(tslib@2.8.1)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): dependencies: - memfs: 4.57.2(tslib@2.8.1) + memfs: 4.57.5(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17354,7 +17386,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.4.0 - launch-editor: 2.13.2 + launch-editor: 2.14.1 open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.3 @@ -17393,7 +17425,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.4.0 - launch-editor: 2.13.2 + launch-editor: 2.14.1 open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.3 @@ -17437,7 +17469,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.0 + enhanced-resolve: 5.22.1 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17448,7 +17480,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.28.0)(webpack@5.106.2(esbuild@0.28.0)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(webpack@5.106.2(esbuild@0.28.0)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: @@ -17477,7 +17509,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.0 + enhanced-resolve: 5.22.1 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17488,7 +17520,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.28.0)(postcss@8.5.13)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(postcss@8.5.13)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: @@ -17550,7 +17582,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 which-collection@1.0.2: dependencies: @@ -17559,7 +17591,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.20: + which-typed-array@1.1.21: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 From c8001229453211b37cd7bb12ed26a2deb9257fd5 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 09:21:32 -0400 Subject: [PATCH 10/23] fix(@schematics/angular): fix browserMode option mapping in refactor-jasmine-vitest The jasmine-vitest refactor schematic previously mapped the `browserMode` option to `options.browerMode` (with a spelling typo). Because of the index signature `[property: string]: any` in the generated options Schema type, the compiler did not emit any error, which resulted in the option silently resolving to `undefined` at runtime and disabling browser-mode transformations. (cherry picked from commit 21cb6284df0647daf365433ea735990744ad4edc) --- .../angular/refactor/jasmine-vitest/index.ts | 2 +- .../refactor/jasmine-vitest/index_spec.ts | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/index.ts b/packages/schematics/angular/refactor/jasmine-vitest/index.ts index 493bb0eb1800..e163a88c6207 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/index.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/index.ts @@ -121,7 +121,7 @@ export default function (options: Schema): Rule { const content = tree.readText(file); const newContent = transformJasmineToVitest(file, content, reporter, { addImports: !!options.addImports, - browserMode: !!options.browerMode, + browserMode: !!options.browserMode, fakeAsync: !!options.fakeAsync, }); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts index a1abb7562ee8..2581d8bbacc9 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts @@ -238,4 +238,46 @@ describe('Jasmine to Vitest Schematic', () => { expect(logs).toContain('- 1 TODO(s) added for manual review:'); expect(logs).toContain(' - 1x spyOnAllFunctions'); }); + + it('should not transform toHaveClass when browserMode is true', async () => { + const specFilePath = 'projects/bar/src/app/app.spec.ts'; + const content = ` + describe('AppComponent', () => { + it('should check class', () => { + expect(element).toHaveClass('active'); + }); + }); + `; + appTree.overwrite(specFilePath, content); + + const tree = await schematicRunner.runSchematic( + 'refactor-jasmine-vitest', + { project: 'bar', browserMode: true }, + appTree, + ); + + const result = tree.readContent(specFilePath); + expect(result).toContain("expect(element).toHaveClass('active');"); + }); + + it('should transform toHaveClass when browserMode is false', async () => { + const specFilePath = 'projects/bar/src/app/app.spec.ts'; + const content = ` + describe('AppComponent', () => { + it('should check class', () => { + expect(element).toHaveClass('active'); + }); + }); + `; + appTree.overwrite(specFilePath, content); + + const tree = await schematicRunner.runSchematic( + 'refactor-jasmine-vitest', + { project: 'bar', browserMode: false }, + appTree, + ); + + const result = tree.readContent(specFilePath); + expect(result).toContain("expect(element.classList.contains('active')).toBe(true);"); + }); }); From bd413b0eb156184ea432cbb7d4e6d7f6f70813ab Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 4 Jun 2026 13:36:33 -0400 Subject: [PATCH 11/23] fix(@angular/build): restrict application builder output paths to output directory Ensure all file writes and deletions produced by the application builder are strictly scoped to the configured `outputPath` base directory. This prevents accidental writes and overwrites of files outside of the output directory (e.g. if the `browser` directory option is configured with relative path segments like `..` that escape the base output folder). (cherry picked from commit 8358805d31232229fb86bde9498a5ccef5048c6c) --- .../build/src/builders/application/index.ts | 83 ++++++++++++------- .../tests/options/output-path_spec.ts | 22 +++++ packages/angular/build/src/utils/path.ts | 7 +- packages/angular/build/src/utils/path_spec.ts | 41 +++++++++ 4 files changed, 118 insertions(+), 35 deletions(-) create mode 100644 packages/angular/build/src/utils/path_spec.ts diff --git a/packages/angular/build/src/builders/application/index.ts b/packages/angular/build/src/builders/application/index.ts index f127ef4bdc7f..b31fc0a8f81b 100644 --- a/packages/angular/build/src/builders/application/index.ts +++ b/packages/angular/build/src/builders/application/index.ts @@ -15,6 +15,7 @@ import { createJsonBuildManifest, emitFilesToDisk } from '../../tools/esbuild/ut import { colors as ansiColors } from '../../utils/color'; import { deleteOutputDir } from '../../utils/delete-output-dir'; import { bazelEsbuildPluginPath, useJSONBuildLogs } from '../../utils/environment-options'; +import { isSubDirectory } from '../../utils/path'; import { purgeStaleBuildCache } from '../../utils/purge-cache'; import { assertCompatibleAngularVersion } from '../../utils/version'; import { runEsBuildBuildAction } from './build-action'; @@ -197,45 +198,57 @@ export async function* buildApplication( // Writes the output files to disk and ensures the containing directories are present const directoryExists = new Set(); - await emitFilesToDisk(Object.entries(result.files), async ([filePath, file]) => { - if ( - outputOptions.ignoreServer && - (file.type === BuildOutputFileType.ServerApplication || - file.type === BuildOutputFileType.ServerRoot) - ) { - return; - } + try { + await emitFilesToDisk(Object.entries(result.files), async ([filePath, file]) => { + if ( + outputOptions.ignoreServer && + (file.type === BuildOutputFileType.ServerApplication || + file.type === BuildOutputFileType.ServerRoot) + ) { + return; + } - const fullFilePath = generateFullPath(filePath, file.type, outputOptions); + const fullFilePath = generateFullPath(filePath, file.type, outputOptions); - // Ensure output subdirectories exist - const fileBasePath = path.dirname(fullFilePath); - if (fileBasePath && !directoryExists.has(fileBasePath)) { - await fs.mkdir(fileBasePath, { recursive: true }); - directoryExists.add(fileBasePath); - } + // Ensure output subdirectories exist + const fileBasePath = path.dirname(fullFilePath); + if (fileBasePath && !directoryExists.has(fileBasePath)) { + await fs.mkdir(fileBasePath, { recursive: true }); + directoryExists.add(fileBasePath); + } - if (file.origin === 'memory') { - // Write file contents - await fs.writeFile(fullFilePath, file.contents); - } else { - // Copy file contents - await fs.cp(file.inputPath, fullFilePath, { - mode: fs.constants.COPYFILE_FICLONE, - preserveTimestamps: true, - }); - } - }); + if (file.origin === 'memory') { + // Write file contents + await fs.writeFile(fullFilePath, file.contents); + } else { + // Copy file contents + await fs.cp(file.inputPath, fullFilePath, { + mode: fs.constants.COPYFILE_FICLONE, + preserveTimestamps: true, + }); + } + }); + } catch (error) { + context.logger.error(error instanceof Error ? error.message : String(error)); + yield { success: false }; + continue; + } // Delete any removed files if incremental if (result.kind === ResultKind.Incremental && result.removed?.length) { - await Promise.all( - result.removed.map((file) => { - const fullFilePath = generateFullPath(file.path, file.type, outputOptions); + try { + await Promise.all( + result.removed.map((file) => { + const fullFilePath = generateFullPath(file.path, file.type, outputOptions); - return fs.rm(fullFilePath, { force: true, maxRetries: 3 }); - }), - ); + return fs.rm(fullFilePath, { force: true, maxRetries: 3 }); + }), + ); + } catch (error) { + context.logger.error(error instanceof Error ? error.message : String(error)); + yield { success: false }; + continue; + } } yield { success: true }; @@ -268,6 +281,12 @@ function generateFullPath( // NOTE: 'base' is a fully resolved path at this point const fullFilePath = path.join(outputOptions.base, typeDirectory, filePath); + if (!isSubDirectory(outputOptions.base, fullFilePath)) { + throw new Error( + `The output file path "${fullFilePath}" is outside of the configured output path "${outputOptions.base}".`, + ); + } + return fullFilePath; } diff --git a/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts b/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts index b6c72b9bee58..3fc98c83ed36 100644 --- a/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts @@ -260,6 +260,28 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { }), ); }); + + it('should error when browser directory escapes the output path base', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: [], + outputPath: { + base: 'dist', + browser: '..', + }, + ssr: false, + }); + + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); + expect(result?.success).toBeFalse(); + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringMatching( + `The output file path .* is outside of the configured output path`, + ), + }), + ); + }); }); }); }); diff --git a/packages/angular/build/src/utils/path.ts b/packages/angular/build/src/utils/path.ts index eafef4ee9f2b..e969d420e429 100644 --- a/packages/angular/build/src/utils/path.ts +++ b/packages/angular/build/src/utils/path.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { normalize, posix, resolve } from 'node:path'; +import { isAbsolute, posix, relative, resolve } from 'node:path'; import { platform } from 'node:process'; const WINDOWS_PATH_SEPERATOR_REGEXP = /\\/g; @@ -44,8 +44,9 @@ export function toPosixPath(path: string): string { * @returns `true` if the child path is within the parent directory, `false` otherwise. */ export function isSubDirectory(parent: string, child: string): boolean { - const normalizedParent = normalize(parent); + const resolvedParent = resolve(parent); const resolvedChild = resolve(parent, child); + const relativePath = toPosixPath(relative(resolvedParent, resolvedChild)); - return resolvedChild.startsWith(normalizedParent); + return relativePath !== '..' && !relativePath.startsWith('../') && !isAbsolute(relativePath); } diff --git a/packages/angular/build/src/utils/path_spec.ts b/packages/angular/build/src/utils/path_spec.ts new file mode 100644 index 000000000000..84c7d8ac31c4 --- /dev/null +++ b/packages/angular/build/src/utils/path_spec.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { isSubDirectory } from './path'; + +describe('isSubDirectory', () => { + it('should return true for a direct child', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/baz')).toBeTrue(); + }); + + it('should return true for a nested child', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/baz/qux/file.txt')).toBeTrue(); + }); + + it('should return true if paths are identical', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar')).toBeTrue(); + }); + + it('should return false for a sibling directory starting with same prefix', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar-outside')).toBeFalse(); + expect(isSubDirectory('/foo/bar', '/foo/bar-outside/file.txt')).toBeFalse(); + }); + + it('should return false for directory outside parent via traversal', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/../outside')).toBeFalse(); + }); + + it('should return false for parent directory', () => { + expect(isSubDirectory('/foo/bar', '/foo')).toBeFalse(); + }); + + it('should return true for children containing directory names starting with double dots', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/..baz')).toBeTrue(); + expect(isSubDirectory('/foo/bar', '/foo/bar/..baz/qux')).toBeTrue(); + }); +}); From a9b6bd9042d6b859c384a6fc782541fca30dfb68 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 09:29:21 -0400 Subject: [PATCH 12/23] fix(@schematics/angular): safely comment out multiline statements in refactor-jasmine-vitest When refactoring unsupported or empty statements (such as `pending()`, `expect().nothing()`, and certain `jasmine` member assignments), the schematic previously commented out the code using a single-line comment prefix on the full text of the node. If the statement spanned multiple lines, only the first line was commented, leaving subsequent lines uncommented. This resulted in invalid syntax or unexpected compile errors. (cherry picked from commit 59e5e967a35af4d9b828f7ca05bb41926271d62e) --- .../transformers/jasmine-lifecycle.ts | 10 ++-------- .../transformers/jasmine-matcher.ts | 10 ++-------- .../transformers/jasmine-misc.ts | 10 ++-------- .../jasmine-vitest/utils/comment-helpers.ts | 20 +++++++++++++++++++ .../utils/comment-helpers_spec.ts | 17 +++++++++++++++- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts index 78ddd1e99316..eb58a7f9d5b9 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts @@ -15,7 +15,7 @@ import ts from 'typescript'; import { createPropertyAccess } from '../utils/ast-helpers'; -import { addTodoComment } from '../utils/comment-helpers'; +import { addCommentedNodeText, addTodoComment } from '../utils/comment-helpers'; import { RefactorContext } from '../utils/refactor-context'; const FOCUSED_SKIPPED_RENAMES = new Map([ @@ -77,7 +77,6 @@ export function transformPending( ) { hasPending = true; const replacement = ts.factory.createEmptyStatement(); - const originalText = bodyNode.getFullText().trim(); reporter.reportTransformation( sourceFile, @@ -87,12 +86,7 @@ export function transformPending( const category = 'pending'; reporter.recordTodo(category, sourceFile, bodyNode); addTodoComment(replacement, category); - ts.addSyntheticLeadingComment( - replacement, - ts.SyntaxKind.SingleLineCommentTrivia, - ` ${originalText}`, - true, - ); + addCommentedNodeText(replacement, bodyNode); return replacement; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts index c1e669b144ef..1e0a87dc80f2 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts @@ -21,7 +21,7 @@ import { createPropertyAccess, } from '../utils/ast-helpers'; import { getJasmineMethodName, isJasmineCallExpression } from '../utils/ast-validation'; -import { addTodoComment } from '../utils/comment-helpers'; +import { addCommentedNodeText, addTodoComment } from '../utils/comment-helpers'; import { RefactorContext } from '../utils/refactor-context'; const SUGAR_MATCHER_CHANGES = new Map([ @@ -607,18 +607,12 @@ export function transformExpectNothing( // The statement is `expect().nothing()`, which can be removed. const replacement = ts.factory.createEmptyStatement(); - const originalText = node.getFullText().trim(); reporter.reportTransformation(sourceFile, node, 'Removed `expect().nothing()` statement.'); const category = 'expect-nothing'; reporter.recordTodo(category, sourceFile, node); addTodoComment(replacement, category); - ts.addSyntheticLeadingComment( - replacement, - ts.SyntaxKind.SingleLineCommentTrivia, - ` ${originalText}`, - true, - ); + addCommentedNodeText(replacement, node); return replacement; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts index 6832e36b9273..f71353cc9783 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts @@ -16,7 +16,7 @@ import ts from 'typescript'; import { addVitestValueImport } from '../utils/ast-helpers'; import { getJasmineMethodName, isJasmineCallExpression } from '../utils/ast-validation'; -import { addTodoComment } from '../utils/comment-helpers'; +import { addCommentedNodeText, addTodoComment } from '../utils/comment-helpers'; import { RefactorContext } from '../utils/refactor-context'; import { createViCallExpression } from '../utils/refactor-helpers'; import { TodoCategory } from '../utils/todo-notes'; @@ -143,7 +143,6 @@ export function transformJasmineMembers(node: ts.Node, refactorCtx: RefactorCont case 'MAX_PRETTY_PRINT_DEPTH': case 'MAX_PRETTY_PRINT_CHARS': { const replacement = ts.factory.createEmptyStatement(); - const originalText = node.getFullText().trim(); reporter.reportTransformation( sourceFile, @@ -153,12 +152,7 @@ export function transformJasmineMembers(node: ts.Node, refactorCtx: RefactorCont const category = 'unsupported-jasmine-member'; reporter.recordTodo(category, sourceFile, node); addTodoComment(replacement, category, { name: memberName }); - ts.addSyntheticLeadingComment( - replacement, - ts.SyntaxKind.SingleLineCommentTrivia, - ` ${originalText}`, - true, - ); + addCommentedNodeText(replacement, node); return replacement; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts index 2ece945e2951..02a9255deb3a 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts @@ -70,3 +70,23 @@ export function addTodoComment( true, ); } + +/** + * Safely comments out the full text of a node line-by-line and attaches + * it to a target node. This prevents multi-line statements from breaking + * syntax when converted to single-line comments. + * @param targetNode The node to which the comments will be added. + * @param nodeToComment The original node whose text will be commented out. + */ +export function addCommentedNodeText(targetNode: ts.Node, nodeToComment: ts.Node): void { + const originalText = nodeToComment.getFullText().trim(); + const lines = originalText.split('\n'); + for (const line of lines) { + ts.addSyntheticLeadingComment( + targetNode, + ts.SyntaxKind.SingleLineCommentTrivia, + ` ${line.trim()}`, + true, + ); + } +} diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts index ddfb1b8b7ad1..4f44b2664368 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts @@ -7,7 +7,7 @@ */ import ts from 'typescript'; -import { addTodoComment } from './comment-helpers'; +import { addCommentedNodeText, addTodoComment } from './comment-helpers'; describe('addTodoComment', () => { function createTestHarness(sourceText: string) { @@ -65,4 +65,19 @@ describe('addTodoComment', () => { expect(result.trim().startsWith('// TODO')).toBe(true); expect(result).toContain('const mySpy = jasmine.createSpy()'); }); + + describe('addCommentedNodeText', () => { + it('should comment out a multiline node line-by-line', () => { + const sourceText = `expect()\n .nothing();`; + const sourceFile = ts.createSourceFile('test.ts', sourceText, ts.ScriptTarget.Latest, true); + const statement = sourceFile.statements[0]; + const replacement = ts.factory.createEmptyStatement(); + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + + addCommentedNodeText(replacement, statement); + + const result = printer.printNode(ts.EmitHint.Unspecified, replacement, sourceFile); + expect(result).toContain('// expect()\n// .nothing();'); + }); + }); }); From 4510dae021ab25bb852eeed6415dbd52cfabfce5 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 10:21:30 -0400 Subject: [PATCH 13/23] perf(@angular/cli): optimize update schematic registry query counts by fetching package metadata lazily Optimize the ng update registry requests by only querying package metadata for packages that are actually being updated, while resolving other dependencies locally from disk (with fallback to registry for uninstalled/mocked packages). This reduces network query counts by 80-90% during ng update. (cherry picked from commit 5e7508a128d7da885917aa68cd121fa8a54d35f7) --- .../angular/cli/src/commands/update/cli.ts | 2 + .../src/commands/update/schematic/index.ts | 419 +++++++++++++----- .../commands/update/schematic/index_spec.ts | 2 +- .../src/commands/update/schematic/schema.json | 4 + 4 files changed, 318 insertions(+), 109 deletions(-) diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index de6d7f53fea0..62416b1c1ee7 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -256,6 +256,7 @@ export default class UpdateCommandModule extends CommandModule(); const packagesToUpdate = [...infoMap.entries()] .map(([name, info]) => { - let tag = options.next - ? info.npmPackageJson['dist-tags']['next'] - ? 'next' - : 'latest' - : 'latest'; - let version = info.npmPackageJson['dist-tags'][tag]; - let target = info.npmPackageJson.versions[version]; + const distTags = info.npmPackageJson['dist-tags'] ?? {}; + let tag = options.next ? (distTags['next'] ? 'next' : 'latest') : 'latest'; + let version = distTags[tag] ?? info.installed.version; + const versions = info.npmPackageJson.versions ?? {}; + let target = versions[version]; const versionDiff = semver.diff(info.installed.version, version); if ( @@ -426,13 +427,13 @@ function _usageMessage( installedMajorVersion < toInstallMajorVersion - 1 ) { const nextMajorVersion = `${installedMajorVersion + 1}.`; - const nextMajorVersions = Object.keys(info.npmPackageJson.versions) + const nextMajorVersions = Object.keys(versions) .filter((v) => v.startsWith(nextMajorVersion)) .sort((a, b) => (a > b ? -1 : 1)); if (nextMajorVersions.length) { version = nextMajorVersions[0]; - target = info.npmPackageJson.versions[version]; + target = versions[version]; tag = ''; } } @@ -525,11 +526,147 @@ function _usageMessage( return; } +/** + * Resolves a semver range or npm dist-tag to a specific version based on the package's registry metadata. + * It prioritizes non-deprecated versions and handles fallback to deprecated versions if necessary. + * + * @private + */ +function resolvePackageVersion( + metadata: NpmRepositoryPackageJson, + range: string, + next = false, +): string | null { + // Check if range matches an npm dist-tag directly (e.g. "latest", "next") + const distTags = metadata['dist-tags'] ?? {}; + if (distTags[range]) { + return distTags[range]; + } + // If 'next' is requested (e.g. via the --next CLI flag) but the package doesn't publish + // a 'next' pre-release tag, fallback to 'latest'. + if (range === 'next') { + return distTags['latest'] ?? null; + } + + // Split deprecated and non-deprecated versions from registry metadata + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + for (const [v, { deprecated }] of Object.entries(metadata.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + + // Find the highest satisfying version, prioritizing non-deprecated versions + return ( + semver.maxSatisfying(packageVersionsNonDeprecated, range, { + includePrerelease: next || undefined, + }) ?? + semver.maxSatisfying(packageVersionsDeprecated, range, { + includePrerelease: next || undefined, + }) + ); +} + +/** + * Checks if Yarn Plug'n'Play is active in the current workspace. + * + * @private + */ +function isPnpActive(workspaceRoot: string): boolean { + return ( + process.versions.pnp !== undefined || + existsSync(path.join(workspaceRoot, '.pnp.cjs')) || + existsSync(path.join(workspaceRoot, '.pnp.js')) + ); +} + +/** + * Resolves and reads the installed package.json manifest for a package. + * It checks the virtual schematic Tree first (vital for unit tests/mocks), + * and falls back to physical disk resolution using createRequire only if Yarn PnP is active. + * + * @private + */ +function getInstalledPackageJson( + tree: Tree, + packageName: string, + workspaceRoot: string, +): PackageManifest | null { + // First, check the virtual tree (critical for testing mocks) + const pkgJsonPath = `/node_modules/${packageName}/package.json`; + if (tree.exists(pkgJsonPath)) { + try { + return tree.readJson(pkgJsonPath) as PackageManifest; + } catch {} + } + + // In Yarn PnP, mock package trees are not written to node_modules in the virtual tree, + // so we resolve the manifest physically from Yarn's zip cache via createRequire. + // Note: This fallback resolution is strictly gated on Yarn PnP being active. Because schematics + // operate on a virtual file system (Tree), running disk lookups in non-PnP + // environments could cause tests to resolve dependencies from this monorepo's own node_modules + // instead of the simulated virtual file system. + if (isPnpActive(workspaceRoot)) { + try { + const workspaceRequire = createRequire(path.join(workspaceRoot, 'package.json')); + const manifestPath = workspaceRequire.resolve(`${packageName}/package.json`); + const content = readFileSync(manifestPath, 'utf8'); + + return JSON.parse(content) as PackageManifest; + } catch {} + } + + return null; +} + +function getInstalledVersion( + tree: Tree, + packageName: string, + workspaceRoot: string, +): string | null { + const pkgJson = getInstalledPackageJson(tree, packageName, workspaceRoot); + + return pkgJson?.version ?? null; +} + +function _buildLocalPackageInfo( + tree: Tree, + name: string, + allDependencies: ReadonlyMap, + workspaceRoot: string, + logger: logging.LoggerApi, +): PackageInfo { + const packageJsonRange = allDependencies.get(name); + if (!packageJsonRange) { + throw new SchematicsException(`Package ${JSON.stringify(name)} was not found in package.json.`); + } + + const localPkgJson = getInstalledPackageJson(tree, name, workspaceRoot); + if (!localPkgJson) { + throw new SchematicsException(`Package ${name} is not installed.`); + } + + return { + name, + npmPackageJson: {} as NpmRepositoryPackageJson, + installed: { + version: localPkgJson.version as VersionRange, + packageJson: localPkgJson, + updateMetadata: _getUpdateMetadata(localPkgJson, logger), + }, + packageJsonRange, + }; +} + function _buildPackageInfo( tree: Tree, packages: Map, allDependencies: ReadonlyMap, npmPackageJson: NpmRepositoryPackageJson, + workspaceRoot: string, logger: logging.LoggerApi, ): PackageInfo { const name = npmPackageJson.name; @@ -538,21 +675,13 @@ function _buildPackageInfo( throw new SchematicsException(`Package ${JSON.stringify(name)} was not found in package.json.`); } - // Find out the currently installed version. Either from the package.json or the node_modules/ - // TODO: figure out a way to read package-lock.json and/or yarn.lock. - const pkgJsonPath = `/node_modules/${name}/package.json`; - const pkgJsonExists = tree.exists(pkgJsonPath); - - let installedVersion: string | undefined | null; - if (pkgJsonExists) { - const { version } = tree.readJson(pkgJsonPath) as PackageManifest; - installedVersion = version; - } + const localPkgJson = getInstalledPackageJson(tree, name, workspaceRoot); + let installedVersion = localPkgJson?.version; const packageVersionsNonDeprecated: string[] = []; const packageVersionsDeprecated: string[] = []; - for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions)) { + for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions ?? {})) { if (deprecated) { packageVersionsDeprecated.push(version); } else { @@ -576,7 +705,8 @@ function _buildPackageInfo( ); } - const installedPackageJson = npmPackageJson.versions[installedVersion] || pkgJsonExists; + const versions = npmPackageJson.versions ?? {}; + const installedPackageJson = versions[installedVersion] || localPkgJson; if (!installedPackageJson) { throw new SchematicsException( `An unexpected error happened; package ${name} has no version ${installedVersion}.`, @@ -585,10 +715,11 @@ function _buildPackageInfo( let targetVersion: VersionRange | undefined = packages.get(name); if (targetVersion) { - if (npmPackageJson['dist-tags'][targetVersion]) { - targetVersion = npmPackageJson['dist-tags'][targetVersion] as VersionRange; + const distTags = npmPackageJson['dist-tags'] ?? {}; + if (distTags[targetVersion]) { + targetVersion = distTags[targetVersion] as VersionRange; } else if (targetVersion == 'next') { - targetVersion = npmPackageJson['dist-tags']['latest'] as VersionRange; + targetVersion = distTags['latest'] as VersionRange; } else { targetVersion = findSatisfyingVersion(targetVersion); } @@ -602,19 +733,18 @@ function _buildPackageInfo( const target: PackageVersionInfo | undefined = targetVersion ? { version: targetVersion, - packageJson: npmPackageJson.versions[targetVersion], - updateMetadata: _getUpdateMetadata(npmPackageJson.versions[targetVersion], logger), + packageJson: versions[targetVersion], + updateMetadata: _getUpdateMetadata(versions[targetVersion], logger), } : undefined; - // Check if there's an installed version. return { name, npmPackageJson, installed: { version: installedVersion as VersionRange, - packageJson: installedPackageJson, - updateMetadata: _getUpdateMetadata(installedPackageJson, logger), + packageJson: installedPackageJson as PackageManifest, + updateMetadata: _getUpdateMetadata(installedPackageJson as PackageManifest, logger), }, target, packageJsonRange, @@ -665,16 +795,34 @@ function _addPackageGroup( return; } - const info = _buildPackageInfo(tree, packages, allDependencies, npmPackageJson, logger); + const distTags = npmPackageJson['dist-tags'] ?? {}; + let version = maybePackage; + if (distTags[version]) { + version = distTags[version] as VersionRange; + } else if (version === 'next') { + version = distTags['latest'] as VersionRange; + } else { + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + const versions = npmPackageJson.versions ?? {}; + for (const [v, { deprecated }] of Object.entries(versions)) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + version = + ((semver.maxSatisfying(packageVersionsNonDeprecated, version) ?? + semver.maxSatisfying(packageVersionsDeprecated, version)) as VersionRange | null) ?? + version; + } - const version = - (info.target && info.target.version) || - npmPackageJson['dist-tags'][maybePackage] || - maybePackage; - if (!npmPackageJson.versions[version]) { + const versions = npmPackageJson.versions ?? {}; + if (!versions[version]) { return; } - const ngUpdateMetadata = npmPackageJson.versions[version]['ng-update']; + const ngUpdateMetadata = versions[version]['ng-update']; if (!ngUpdateMetadata) { return; } @@ -721,51 +869,64 @@ function _addPackageGroup( * be ignored by the --force flag). * @private */ -function _addPeerDependencies( +async function _addPeerDependencies( tree: Tree, packages: Map, allDependencies: ReadonlyMap, npmPackageJson: NpmRepositoryPackageJson, - npmPackageJsonMap: Map, + workspaceRoot: string, + fetchMetadata: (name: string) => Promise, logger: logging.LoggerApi, -): void { +): Promise { const maybePackage = packages.get(npmPackageJson.name); if (!maybePackage) { return; } - - const info = _buildPackageInfo(tree, packages, allDependencies, npmPackageJson, logger); - - const version = - (info.target && info.target.version) || - npmPackageJson['dist-tags'][maybePackage] || - maybePackage; - if (!npmPackageJson.versions[version]) { + const distTags = npmPackageJson['dist-tags'] ?? {}; + const version = distTags[maybePackage] || maybePackage; + const versions = npmPackageJson.versions ?? {}; + const packageJson = versions[version]; + if (!packageJson) { return; } - const packageJson = npmPackageJson.versions[version]; - const error = false; - for (const [peer, range] of Object.entries(packageJson.peerDependencies || {})) { if (packages.has(peer)) { continue; } - const peerPackageJson = npmPackageJsonMap.get(peer); - if (peerPackageJson) { - const peerInfo = _buildPackageInfo(tree, packages, allDependencies, peerPackageJson, logger); - if (semver.satisfies(peerInfo.installed.version, range)) { + const installedVersion = getInstalledVersion(tree, peer, workspaceRoot); + if (installedVersion) { + if (semver.satisfies(installedVersion, range)) { continue; } + } else { + const packageJsonRange = allDependencies.get(peer); + if (packageJsonRange) { + const peerMetadata = await fetchMetadata(peer); + if (peerMetadata) { + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + for (const [v, { deprecated }] of Object.entries(peerMetadata.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + const resolvedInstalledVersion = + semver.maxSatisfying(packageVersionsNonDeprecated, packageJsonRange) ?? + semver.maxSatisfying(packageVersionsDeprecated, packageJsonRange); + + if (resolvedInstalledVersion && semver.satisfies(resolvedInstalledVersion, range)) { + continue; + } + } + } } packages.set(peer, range as VersionRange); } - - if (error) { - throw new SchematicsException('An error occured, see above.'); - } } function _getAllDependencies(tree: Tree): Array { @@ -846,67 +1007,109 @@ export default function (options: UpdateSchema): Rule { ); const packages = _buildPackageList(options, npmDeps, logger); - // Grab all package.json from the npm repository. This requires a lot of HTTP calls so we - // try to parallelize as many as possible. - const allPackageMetadata = await Promise.all( - Array.from(npmDeps.keys()).map((depName) => - getNpmPackageJson(depName, logger, { + const workspaceRoot = options.workspaceRoot ?? process.cwd(); + const npmPackageJsonMap = new Map(); + + const getOrFetchPackageMetadata = async ( + packageName: string, + ): Promise => { + let metadata = npmPackageJsonMap.get(packageName); + if (!metadata) { + const raw = await getNpmPackageJson(packageName, logger, { registry: options.registry, usingYarn, verbose: options.verbose, - }), - ), - ); - - // Build a map of all dependencies and their packageJson. - const npmPackageJsonMap = allPackageMetadata.reduce((acc, npmPackageJson) => { - // If the package was not found on the registry. It could be private, so we will just - // ignore. If the package was part of the list, we will error out, but will simply ignore - // if it's either not requested (so just part of package.json. silently). - if (!npmPackageJson.name) { - if (npmPackageJson.requestedName && packages.has(npmPackageJson.requestedName)) { - throw new SchematicsException( - `Package ${JSON.stringify(npmPackageJson.requestedName)} was not found on the ` + - 'registry. Cannot continue as this may be an error.', - ); + }); + if (raw.name) { + metadata = raw as NpmRepositoryPackageJson; + npmPackageJsonMap.set(packageName, metadata); } - } else { - // If a name is present, it is assumed to be fully populated - acc.set(npmPackageJson.name, npmPackageJson as NpmRepositoryPackageJson); } - return acc; - }, new Map()); - - // Augment the command line package list with packageGroups and forward peer dependencies. - // Each added package may uncover new package groups and peer dependencies, so we must - // repeat this process until the package list stabilizes. - let lastPackagesSize; - do { - lastPackagesSize = packages.size; + return metadata ?? null; + }; - let lastGroupSize; + if (packages.size === 0) { + // User ran just `ng update` to see the outdated package list. + // We must fetch metadata for all npm dependencies to generate the usage message. + await Promise.all( + Array.from(npmDeps.keys()).map(async (depName) => { + await getOrFetchPackageMetadata(depName); + }), + ); + } else { + // User requested updates. We resolve dependencies lazily. + let lastPackagesSize; do { - lastGroupSize = packages.size; - npmPackageJsonMap.forEach((npmPackageJson) => { - _addPackageGroup(tree, packages, npmDeps, npmPackageJson, logger); - }); - } while (packages.size > lastGroupSize); - - // This is done in seperate loop to ensure that package groups are added before peer dependencies. - npmPackageJsonMap.forEach((npmPackageJson) => { - _addPeerDependencies(tree, packages, npmDeps, npmPackageJson, npmPackageJsonMap, logger); - }); - } while (packages.size > lastPackagesSize); + lastPackagesSize = packages.size; + + let lastGroupSize; + do { + lastGroupSize = packages.size; + for (const name of Array.from(packages.keys())) { + const metadata = await getOrFetchPackageMetadata(name); + const spec = packages.get(name); + if (metadata && spec) { + const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + if (resolvedVersion) { + packages.set(name, resolvedVersion as VersionRange); + } + _addPackageGroup(tree, packages, npmDeps, metadata, logger); + } + } + } while (packages.size > lastGroupSize); + + for (const name of Array.from(packages.keys())) { + const metadata = await getOrFetchPackageMetadata(name); + const spec = packages.get(name); + if (metadata && spec) { + const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + if (resolvedVersion) { + packages.set(name, resolvedVersion as VersionRange); + } + await _addPeerDependencies( + tree, + packages, + npmDeps, + metadata, + workspaceRoot, + getOrFetchPackageMetadata, + logger, + ); + } + } + } while (packages.size > lastPackagesSize); + } // Build the PackageInfo for each module. const packageInfoMap = new Map(); - npmPackageJsonMap.forEach((npmPackageJson) => { - packageInfoMap.set( - npmPackageJson.name, - _buildPackageInfo(tree, packages, npmDeps, npmPackageJson, logger), - ); - }); + for (const depName of npmDeps.keys()) { + const isUpdating = packages.has(depName); + const localPkgJson = getInstalledPackageJson(tree, depName, workspaceRoot); + + if (isUpdating || !localPkgJson) { + // If updating OR not installed locally, resolve via registry metadata + const metadata = await getOrFetchPackageMetadata(depName); + if (metadata) { + packageInfoMap.set( + depName, + _buildPackageInfo(tree, packages, npmDeps, metadata, workspaceRoot, logger), + ); + } else { + // Fallback if metadata could not be fetched + packageInfoMap.set( + depName, + _buildLocalPackageInfo(tree, depName, npmDeps, workspaceRoot, logger), + ); + } + } else { + // If not updating and installed locally, resolve purely locally + packageInfoMap.set( + depName, + _buildLocalPackageInfo(tree, depName, npmDeps, workspaceRoot, logger), + ); + } + } // Now that we have all the information, check the flags. if (packages.size > 0) { diff --git a/packages/angular/cli/src/commands/update/schematic/index_spec.ts b/packages/angular/cli/src/commands/update/schematic/index_spec.ts index 11b2a0b5855e..7e8ca436150d 100644 --- a/packages/angular/cli/src/commands/update/schematic/index_spec.ts +++ b/packages/angular/cli/src/commands/update/schematic/index_spec.ts @@ -387,5 +387,5 @@ describe('@schematics/update', () => { expect(dependencies['@angular/cdk']).toMatch(version20Regexp); expect(dependencies['@angular/common']).toMatch(version20Regexp); expect(dependencies['@angular/core']).toMatch(version20Regexp); - }); + }, 45000); }); diff --git a/packages/angular/cli/src/commands/update/schematic/schema.json b/packages/angular/cli/src/commands/update/schematic/schema.json index 4768df46f2d5..63bf2df87813 100644 --- a/packages/angular/cli/src/commands/update/schematic/schema.json +++ b/packages/angular/cli/src/commands/update/schematic/schema.json @@ -58,6 +58,10 @@ "type": "string", "default": "npm", "enum": ["npm", "yarn", "pnpm", "bun"] + }, + "workspaceRoot": { + "description": "The path to the workspace root directory.", + "type": "string" } }, "required": [] From e3cab4dddade2538125e8a2f345f42c95e26aeae Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 18:59:03 -0400 Subject: [PATCH 14/23] fix(@angular/build): prevent concurrent stylesheet bundling esbuild context leaks When multiple components in the same file define identical inline styles, concurrent calls to the stylesheet bundler invoke Cache.getOrCreate concurrently with the same key. Because getOrCreate is not concurrency-safe, multiple BundlerContext instances are created. Additionally, if multiple bundle() requests occur concurrently on a BundlerContext when the esbuild context is not yet initialized, they both invoke context(), causing one to overwrite and leak the other. Leaked esbuild contexts keep the Node event loop active forever, hanging the test runner. Resolve the Cache race by using an internal Map of in-flight promises to share the same active request, along with a version counter to detect mid-flight writes and safely retry. Resolve the BundlerContext race by memoizing and sharing the active performBundle promise. Fixes #33317 (cherry picked from commit 7786de1a1fdf232a9c665f76d0f8a5861f148622) --- .../src/tools/esbuild/bundler-context.ts | 24 ++- .../angular/build/src/tools/esbuild/cache.ts | 101 +++++++++++- .../build/src/tools/esbuild/cache_spec.ts | 144 ++++++++++++++++++ 3 files changed, 261 insertions(+), 8 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/cache_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index dd2764c8c608..7fe28e5a51d4 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -59,6 +59,8 @@ export class BundlerContext { #esbuildContext?: BuildContext<{ metafile: true; write: false }>; #esbuildOptions?: BuildOptions & { metafile: true; write: false }; #esbuildResult?: BundleContextResult; + #activeBundlePromise?: Promise; + #disposed = false; #optionsFactory: BundlerOptionsFactory; #shouldCacheResult: boolean; #loadCache?: MemoryLoadResultCache; @@ -177,7 +179,18 @@ export class BundlerContext { return this.#esbuildResult; } - const result = await this.#performBundle(); + if (!force && this.#activeBundlePromise) { + return this.#activeBundlePromise; + } + + const bundlePromise = this.#performBundle().finally(() => { + if (this.#activeBundlePromise === bundlePromise) { + this.#activeBundlePromise = undefined; + } + }); + this.#activeBundlePromise = bundlePromise; + + const result = await bundlePromise; if (this.#shouldCacheResult) { this.#esbuildResult = result; } @@ -207,7 +220,12 @@ export class BundlerContext { } else { // Create a build context and perform the build. // Context creation does not perform a build. - this.#esbuildContext = await context(this.#esbuildOptions); + const esbuildContext = await context(this.#esbuildOptions); + if (this.#disposed) { + await esbuildContext.dispose(); + throw new Error('BundlerContext was disposed during build.'); + } + this.#esbuildContext = esbuildContext; result = await this.#esbuildContext.rebuild(); } } catch (failure) { @@ -446,9 +464,11 @@ export class BundlerContext { * @returns A promise that resolves when disposal is complete. */ async dispose(): Promise { + this.#disposed = true; try { this.#esbuildOptions = undefined; this.#esbuildResult = undefined; + this.#activeBundlePromise = undefined; this.#loadCache = undefined; await this.#esbuildContext?.dispose(); } finally { diff --git a/packages/angular/build/src/tools/esbuild/cache.ts b/packages/angular/build/src/tools/esbuild/cache.ts index 5bd0dc84d73f..0634ec5268e8 100644 --- a/packages/angular/build/src/tools/esbuild/cache.ts +++ b/packages/angular/build/src/tools/esbuild/cache.ts @@ -44,11 +44,26 @@ export interface CacheStore { * to use a cache. */ export class Cache = CacheStore> { + // In-flight creator promises to deduplicate concurrent requests for the same key. + readonly #requests = new Map>(); + // Track how many writes occurred for a key to detect mutations during await gaps. + readonly #writeCounts = new Map(); + // Count the number of active, pending getOrCreate operations per key to avoid memory leaks. + readonly #pendingGets = new Map(); + constructor( protected readonly store: S, readonly namespace?: string, ) {} + #incrementWrite(key: string) { + // Only track write counts if there is a pending getOrCreate operation active for the key. + // This ensures that write counts are not leaked when no concurrent gets are running. + if (this.#pendingGets.has(key)) { + this.#writeCounts.set(key, (this.#writeCounts.get(key) || 0) + 1); + } + } + /** * Prefixes a key with the cache namespace if present. * @param key A key string to prefix. @@ -72,14 +87,75 @@ export class Cache = CacheStore> { */ async getOrCreate(key: string, creator: () => V | Promise): Promise { const namespacedKey = this.withNamespace(key); - let value = await this.store.get(namespacedKey); - if (value === undefined) { - value = await creator(); - await this.store.set(namespacedKey, value); + // 1. If another call is already running the creator for this key, share its promise. + let activeRequest = this.#requests.get(namespacedKey); + if (activeRequest !== undefined) { + return activeRequest; } - return value; + // Increment pending gets count to enable write-tracking for this key. + const currentPending = this.#pendingGets.get(namespacedKey) || 0; + this.#pendingGets.set(namespacedKey, currentPending + 1); + + try { + const startWriteCount = this.#writeCounts.get(namespacedKey) || 0; + + // 2. Query the backing store. Since store.get can be async, we yield to the event loop. + const value = await this.store.get(namespacedKey); + + // If a write (e.g. put) occurred during the store.get await gap, we must abort + // the current execution and restart to ensure we return the newly written value. + if ((this.#writeCounts.get(namespacedKey) || 0) !== startWriteCount) { + return this.getOrCreate(key, creator); + } + + if (value !== undefined) { + return value; + } + + // 3. Recheck active request after the await gap in case another concurrent call + // initiated a creator during the store.get wait. + activeRequest = this.#requests.get(namespacedKey); + if (activeRequest !== undefined) { + return activeRequest; + } + + // 4. Run the creator to produce the new value, and store its promise in #requests. + activeRequest = Promise.resolve(creator()).then( + async (newValue) => { + // Ensure this request is still the active one before writing back to the store + // (prevents overwriting newer data if put() was called before resolution). + if (this.#requests.get(namespacedKey) === activeRequest) { + this.#incrementWrite(namespacedKey); + await this.store.set(namespacedKey, newValue); + this.#requests.delete(namespacedKey); + } + + return newValue; + }, + (error) => { + // Clean up the active request if the creator fails. + if (this.#requests.get(namespacedKey) === activeRequest) { + this.#requests.delete(namespacedKey); + } + throw error; + }, + ); + + this.#requests.set(namespacedKey, activeRequest); + + return activeRequest; + } finally { + // Clean up write counts and pending gets once all concurrent gets for this key finish. + const current = this.#pendingGets.get(namespacedKey) || 0; + if (current <= 1) { + this.#pendingGets.delete(namespacedKey); + this.#writeCounts.delete(namespacedKey); + } else { + this.#pendingGets.set(namespacedKey, current - 1); + } + } } /** @@ -100,7 +176,19 @@ export class Cache = CacheStore> { * @param value A value to put in the cache. */ async put(key: string, value: V): Promise { - await this.store.set(this.withNamespace(key), value); + const namespacedKey = this.withNamespace(key); + this.#requests.delete(namespacedKey); + this.#incrementWrite(namespacedKey); + await this.store.set(namespacedKey, value); + } + + /** + * Clears the base class internal state (requests, write counts, and pending gets). + */ + protected clearInternal(): void { + this.#requests.clear(); + this.#writeCounts.clear(); + this.#pendingGets.clear(); } } @@ -116,6 +204,7 @@ export class MemoryCache extends Cache> { * Removes all entries from the cache instance. */ clear() { + this.clearInternal(); this.store.clear(); } diff --git a/packages/angular/build/src/tools/esbuild/cache_spec.ts b/packages/angular/build/src/tools/esbuild/cache_spec.ts new file mode 100644 index 000000000000..a30852836eff --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/cache_spec.ts @@ -0,0 +1,144 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { MemoryCache } from './cache'; + +describe('MemoryCache', () => { + let cache: MemoryCache; + + beforeEach(() => { + cache = new MemoryCache(); + }); + + it('should return cached value on subsequent getOrCreate calls', async () => { + let callCount = 0; + const creator = () => { + callCount++; + + return 'value'; + }; + + const val1 = await cache.getOrCreate('key', creator); + const val2 = await cache.getOrCreate('key', creator); + + expect(val1).toBe('value'); + expect(val2).toBe('value'); + expect(callCount).toBe(1); + }); + + it('should call creator only once for concurrent getOrCreate calls with the same key', async () => { + let callCount = 0; + let resolveCreator!: (value: string) => void; + const promise = new Promise((resolve) => { + resolveCreator = resolve; + }); + + const creator = () => { + callCount++; + + return promise; + }; + + const p1 = cache.getOrCreate('key', creator); + const p2 = cache.getOrCreate('key', creator); + + resolveCreator('concurrent-value'); + + const [val1, val2] = await Promise.all([p1, p2]); + + expect(val1).toBe('concurrent-value'); + expect(val2).toBe('concurrent-value'); + expect(callCount).toBe(1); + }); + + it('should call creator multiple times for concurrent getOrCreate calls with different keys', async () => { + let callCount = 0; + const creator = (val: string) => { + callCount++; + + return Promise.resolve(val); + }; + + const p1 = cache.getOrCreate('key1', () => creator('value1')); + const p2 = cache.getOrCreate('key2', () => creator('value2')); + + const [val1, val2] = await Promise.all([p1, p2]); + + expect(val1).toBe('value1'); + expect(val2).toBe('value2'); + expect(callCount).toBe(2); + }); + + it('should clean up active request if creator throws/rejects', async () => { + let callCount = 0; + let rejectCreator!: (err: Error) => void; + const promise = new Promise((_, reject) => { + rejectCreator = reject; + }); + + const creator = () => { + callCount++; + + return promise; + }; + + const p1 = cache.getOrCreate('key', creator); + const p2 = cache.getOrCreate('key', creator); + + rejectCreator(new Error('creator error')); + + await expectAsync(p1).toBeRejectedWithError('creator error'); + await expectAsync(p2).toBeRejectedWithError('creator error'); + + // Subsequent call should trigger the creator again + const p3 = cache.getOrCreate('key', () => { + callCount++; + + return Promise.resolve('new-value'); + }); + const val3 = await p3; + expect(val3).toBe('new-value'); + expect(callCount).toBe(2); + }); + + it('should override/clear active requests when put is called', async () => { + let resolveCreator!: (value: string) => void; + const promise = new Promise((resolve) => { + resolveCreator = resolve; + }); + + let creatorStarted!: (value: void) => void; + const creatorStartedPromise = new Promise((resolve) => { + creatorStarted = resolve; + }); + + const creator = () => { + creatorStarted(); + + return promise; + }; + + const p1 = cache.getOrCreate('key', creator); + + // Wait for the creator to be called so that the active request is created + await creatorStartedPromise; + + // Call put before the creator promise resolves + await cache.put('key', 'override-value'); + + resolveCreator('original-value'); + + const val1 = await p1; + // p1 was already returned, so it resolves to original-value + expect(val1).toBe('original-value'); + + // Subsequent getOrCreate should return the put/overridden value, not the resolved original-value + const val2 = await cache.getOrCreate('key', () => 'should-not-run'); + expect(val2).toBe('override-value'); + }); +}); From e9b106e6628c07af567a11d9c45950f09910cfb5 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 8 Jun 2026 15:34:58 +0000 Subject: [PATCH 15/23] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 6 +- MODULE.bazel.lock | 35 +++-- package.json | 2 +- pnpm-lock.yaml | 341 ++++++++++++++++++++++------------------------ 4 files changed, 185 insertions(+), 199 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 1d86371622b6..b10a76173410 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "582ffa9559d60f99fd1d3e50ae32c4223f013fea", + commit = "02e0d38eb29b2721128ca7e93ee694e68d4f06f6", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "b490e5cc7fd2aa57136a1962047bd89454f3df94", + commit = "e78f06f32bc0780cfda374af155a1b5dc84fa14d", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "96a315fb4737861718aa59a7e7361408db704148", + commit = "c7e596a4a34f651113c42a9da3f82acc0a01484e", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 53f5ff646cb4..dc32a6881872 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -24,7 +24,6 @@ "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", - "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/MODULE.bazel": "e3685502155d3cc65f3bf98e714f7435de67d7f8f355d63478a80197310311fc", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/MODULE.bazel": "c3d34345c51a4d90cf678d3b251c6f345b63d5e2e6b0253dbdda467a01efc31f", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/source.json": "3538ab18ac72ba3eaa3db0e4ec5171e04322768723afaa1149c0d822fe5411e2", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", @@ -593,7 +592,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "WLnUVJj/ND5g3OI+Y8YJwgtWXfoXpunqLGs7GRZ3PqI=", + "bzlTransitiveDigest": "lQlRwI+HZTXohoZ41oufeudyNMhYrxQizk07ADXimPI=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -602,9 +601,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7db2d5ced82b7f4c62ed593ff2a0e486dde48ae2b09609ab74fe30dad6eadbab", + "sha256": "fd4df6dcadda8641af4f5d79137b23f1b1271a1cfcc0b96f52cb1b8bcd7c01d5", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -620,9 +619,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "87e67dc147587e0c6b7ae5e6d14b778e7782c8273d1798a2841b7b6b8cbcb669", + "sha256": "4136f1a9524ac5130dd29fe9eef82094139f079520af0b28f0d360f4f3f550ed", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -638,9 +637,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "42675dfaf8e89174fafecf300fdba58bc8410c31b7d9d2300505dce3358cff9c", + "sha256": "f2cb9d22ad425a23e1d58dab7ac91e546386099a5acb811ca5749d40bf2d9886", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -656,9 +655,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f9b135b3d1ca7e80dcced8ece4975a918f1d37d2b1f74793902e3b1ab3fa4ea6", + "sha256": "684055979848753211b24215d25993c453ee26cdb2d84d7bfb24f84118e02198", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -674,9 +673,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "39c2d4425b848f2e09940b4060f50484ca83f18b9d3bdbe2f42495d4a1d38f71", + "sha256": "d9e12133a8af192f8a28f2ef0d86ac54f7458c71e28bddf95947d5636472d508", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -690,9 +689,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "48ece94ee9b286f47c6662f3d2640a4a035af2e4f8101f8a971a909bc552bd36", + "sha256": "7432080f1c3fc8131d58870e93ca9a96c807fedc04deaaf5c1a60942f3c1d321", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -706,9 +705,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "736ec9b51a4d6fe1622d1940df29e3b183fe5d09f7f06d68141c2330f76a9790", + "sha256": "0bfbda9352bbae72755b463f656a6f335481bc02be1ba8edfe1fb74a08ce0d7b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -722,9 +721,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "77b5c787237dcac62686c125e702d0bddc28466e9660f79a77d8389cd1d94513", + "sha256": "766efed7d9c6a3aa89733d59b64316849775002bdde7e247318c8129bbd6d747", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/package.json b/package.json index ae1d2f42bb10..0430bc3fcf35 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.0.0", "@angular/localize": "22.0.0", "@angular/material": "22.0.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c", "@angular/platform-browser": "22.0.0", "@angular/platform-server": "22.0.0", "@angular/router": "22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75a4b26ab553..d341397968f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.0.0 version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2)) '@angular/platform-browser': specifier: 22.0.0 version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -333,7 +333,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.5 - version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) packages/angular/build: dependencies: @@ -357,7 +357,7 @@ importers: version: 6.0.12(@types/node@24.12.4) '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + version: 2.3.0(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)) beasties: specifier: 0.4.2 version: 0.4.2 @@ -408,7 +408,7 @@ importers: version: 0.2.16 vite: specifier: 7.3.2 - version: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + version: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) watchpack: specifier: 2.5.1 version: 2.5.1 @@ -442,7 +442,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.5 - version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.4 @@ -1011,9 +1011,9 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29': - resolution: {gitHosted: true, integrity: sha512-JAec9kjT065fvyeoiFW/iLaTTZ0QTpg6oiMVoV51l0o7HkIWoNIvIOyVk1WELR6Y2vEw0pNMdQQAlYEiQDshMA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29} - version: 0.0.0-b64a291ca373bc91e5ee876488710c026157bf91 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c': + resolution: {gitHosted: true, integrity: sha512-DolaJQq/Bl29sdXrd8YUw+a/T0Xf2hzug0mbuWk4poeLAQ7GQpx1C+fw1TyRvu89HONzhLDYj8RMGkESZlYxwQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c} + version: 0.0.0-e78f06f32bc0780cfda374af155a1b5dc84fa14d hasBin: true '@angular/platform-browser@22.0.0': @@ -2050,8 +2050,8 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.12.0': - resolution: {integrity: sha512-b+OL4vdyiSLZL/7dLd67V55CjKJvU9MpNmwnday7eA6GG2+J4iwUEsEHgw0/jKY3A41FfkF0SrnYFvtKbQZ65A==} + '@firebase/ai@2.13.0': + resolution: {integrity: sha512-nJJDQKqjAcbkZdZGT/5WTVLrGZ+pYhWbwKC90nNzmvtoRTtnOJaNS34fhKSHQeB9SALgD2kxuWT5I4AkytdZ/Q==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2070,8 +2070,8 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-check-compat@0.4.3': - resolution: {integrity: sha512-L3AKIRTJxT9b7cDUH3OyV8gWTnmW3vYkwdzRsukWt4kbPBTct12xalnyvHDkm1lKkr+cQq/4uzBx1bOWsQ2ciw==} + '@firebase/app-check-compat@0.4.4': + resolution: {integrity: sha512-9iP0MvmaVagulNXmrca96U3tqNAI3j98wsC1z7rj62nnOTajlrHM//jjB9VoHqRw6/islMskp6RsKnM7vhLDqA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2082,25 +2082,25 @@ packages: '@firebase/app-check-types@0.5.4': resolution: {integrity: sha512-xV7JsIyzVr15aA7f3Pi0rB9gdBuVubs89FGA8VkRYA4g0l78poADgdfrScgf7NndSg9mm7cR7PJyY0+t22KaGw==} - '@firebase/app-check@0.11.3': - resolution: {integrity: sha512-aJ4DfubWfTO8/2vhEhIAizOoOmiycESTU32e+OUgbWcS/G3PA4Vxlr/9zaiN2wfUG2AptQ7DTvj00tyuFZP5Bg==} + '@firebase/app-check@0.11.4': + resolution: {integrity: sha512-G8EsbVJV9gSfoibx0dNoNOUrvr+PkL7J//+W/BST/oUassimkZeq9bjj3bKkB0pn4og5GMQ9qs7FefwP00kkgg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.12': - resolution: {integrity: sha512-Pe513OBerK/CIBxz4/za9atd5MsZtd6DzHz4cmqkvkrcDWhQChAoHBpZ3McuZNuSP8YZiKwfX/J1frR07l15/w==} + '@firebase/app-compat@0.5.13': + resolution: {integrity: sha512-pn3FvXwUR34kWPccDQfCKsNZcM2wD1OS+J1jeEgzM1ZNXoxR2NaF6e5DjDuRrnTwR6LN2XQQt0IqE6yKmgpCQg==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.5': resolution: {integrity: sha512-YevqTjvo7Iujsa9Dwowmd6dSoElhzmD63ZSrq6bzjvQ6POjYgNjOFHLmNIgJs48eNO093NCERibuFnxbfOvU7A==} - '@firebase/app@0.14.12': - resolution: {integrity: sha512-FT+HoNp1NdaZ/N26hCwV3WbxS1m6gTn3p2QRBQ3KH7YqyCQqJx0iT7126RgVk68/Rq+9DeL/zCFnHZ0C4u1nLQ==} + '@firebase/app@0.14.13': + resolution: {integrity: sha512-H89Jeyp31+EZk9GPu6vaeL9mEmoXgM3nASB7UPBYYS/lqAks21mO1BU1dF8NbsVTL6tgGZkGUtiGJgxtDiwHkw==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.6': - resolution: {integrity: sha512-KDJ/GAf/rt7galOpn3DRb2buFfGkZCsHTryKjXDG0eeRnok4+2B4nnkMOMdjRnPkElmcJv2Ao0vEA6kp5m98PQ==} + '@firebase/auth-compat@0.6.7': + resolution: {integrity: sha512-XgKnOgY1Siq7gylAmLkYtHAlRxNeWEAspH+nO3gJZJnfHqoTHbr9UjJ3nHNFALYXV5CfpQlyPROyB2ztySBHBQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2114,8 +2114,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.1': - resolution: {integrity: sha512-/1nkKY/MicI+I9WWcx6R4NKs77AaW9NQ0IwsFdUBomWrW0/cXEmopfM2dtLm2oI1qG6z6vom3CXZDHJIJXoMuw==} + '@firebase/auth@1.13.2': + resolution: {integrity: sha512-B4w0iS7MxRg28oIh2fJFTE6cM0lYdBrW19eHpc42jqEcloUjlYyVrpPqZvqA4+v9KFEVSKEs2SfWyta7hbzkJQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2128,8 +2128,8 @@ packages: resolution: {integrity: sha512-wFofIaa2879ogD/WvkjYXJxRmfnL0scen6ORgaC3na1FNOR9ASIUANQdhqQcmWu/h77/pVHY7ch5flewa5Bcew==} engines: {node: '>=20.0.0'} - '@firebase/data-connect@0.7.0': - resolution: {integrity: sha512-ar9sNOJh5poQCSMSVlnVE8eo8+usTD1POWDCv65omkKUvnFMcdXaQ7J/e7WGKqJzcEMgiezSX/TZiKHZkItMbQ==} + '@firebase/data-connect@0.7.1': + resolution: {integrity: sha512-2LbUU8mmSA63HknxQMmWHjpzuNLBKflvVwQc2tpoVKg0biWleNEJX031ELks0vzFs+dDjOUkCJR72RP6mQHFOg==} peerDependencies: '@firebase/app': 0.x @@ -2144,8 +2144,8 @@ packages: resolution: {integrity: sha512-XwWCa+E4TvNGpGwXrycLRNfdogADwFcvuhyow6wDWma9W54roaQIhe+4PM0KiLsIftBdSCGI7OKCXrdSRHbIhw==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.9': - resolution: {integrity: sha512-NPtBuFr79BbIQJXFWhW4xFC6rBksK8/ewqCTYbbAYfZBDDx0/iHTUj4WpKi5D4d0Pn2Md/3T/e5V9379G5N/Zg==} + '@firebase/firestore-compat@0.4.10': + resolution: {integrity: sha512-yMP3FADDjikdrQv4YmvL4EkIny6Hw+N+a2O5T40rlHiniyMpRPxgYkKiFOvMZnsqKLqBVnKqCAElC0pa/IZtdw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2156,14 +2156,14 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.14.1': - resolution: {integrity: sha512-PouS0NJZ3NYOZE/tPDvXa8VUeJ10Ll//7jIdFvMYdhQkd/P3O7nlqhyoTmY0h8Xa9hxg+H0j6gxUytJcoZ9YOg==} + '@firebase/firestore@4.15.0': + resolution: {integrity: sha512-Fj9osqYkz2Rqr7kW3/A8BRd8CyJ7yA5K8YjhihRdyJWbL+FsELVcR6DpoCplrp1IyU+xeGgTubo1UOySXpY+EA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/functions-compat@0.4.4': - resolution: {integrity: sha512-Be+MwhseVf/eFAZwGrFJGok6S7cmsLrAPK8MgyM8LjM0MewTsx2n01WOOca9jio1UsCZOJ0aVyQobnINcdNuIQ==} + '@firebase/functions-compat@0.4.5': + resolution: {integrity: sha512-10qlUXGY25G5/1g9UihqksPp2po+ZqSE7LEizsrdUP7vrTmkysXxGSZCDyojSEp6mQe/ecRDdDDI+z4XRdb4wQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2171,8 +2171,8 @@ packages: '@firebase/functions-types@0.6.4': resolution: {integrity: sha512-zV6kgqtduR4rUAdC/ilS7kmb93XD7bEZoJDlVBZqlOw2uGGGCNBQBuleww2rr0Ulr3L9o2TDjumEt68/l1f9DQ==} - '@firebase/functions@0.13.4': - resolution: {integrity: sha512-oB5rpm2Emxn2+IS1gRelAeT/5tSZMwM/KhqC5LnJsmTNnS1ZDhD7ZMZNgCI8vchTW6PbaXIwEnpUryGuIQsNbg==} + '@firebase/functions@0.13.5': + resolution: {integrity: sha512-bWCx713f4kE/uFV7gdFOLBS7lDoiZj48MRkbAqe35gkXcCeWF4QjRNO07Jhmve7EJIoQOBczL29y2r8VRuN1kw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2196,16 +2196,16 @@ packages: resolution: {integrity: sha512-vZKLsqE1ABOy8OjQiE7cUTFn4gvaqlk88yp8N94Pk/sDpq61YqZGqmVFZTvOyflTwuYFcWirBdYGoJgbDaXKYQ==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.26': - resolution: {integrity: sha512-fn0XvWOfK4tsDLSipwJUW9Cp6ahWA6z+iJHxZ0pHp9MzMSUNQx85yuxZAuI7gkGXfqs7+DqEDHyyS7jDGswrmQ==} + '@firebase/messaging-compat@0.2.27': + resolution: {integrity: sha512-JNOiu1PPgdHzEPEtoFiNxQuu0x9bm4bfETSQCpGfcTlgWkhlSK7uh7nlsjC10TQLUNgYetLmuutaYTh8aeYLVA==} peerDependencies: '@firebase/app-compat': 0.x - '@firebase/messaging-interop-types@0.2.4': - resolution: {integrity: sha512-wrzITQq+xw5LtygX7O0fu43/k9ABQ4x5H9/sR5m1SbNnhIRI5xd3+raSNJaJkYC4BUhM9A4ZNSnyR2sjhxnb2Q==} + '@firebase/messaging-interop-types@0.2.5': + resolution: {integrity: sha512-tUEKnaAP2Y/MNIqgnriPpV6e5l13Vs/+p2yrd6NGlncPJT9O3a8muYZtdnWe+IJ4fgKLHJVC79n/asxk/N5Msw==} - '@firebase/messaging@0.12.26': - resolution: {integrity: sha512-lHVTO9uLofymHVWkYeUtMddIPcmJvSzVbHRB88W6XKfxbcKF+p3QrfqKhDxremSB4NQjUla1Gwn7d9umSMmt/w==} + '@firebase/messaging@0.13.0': + resolution: {integrity: sha512-GZoo0uGRvEbszo83xcgbjJp4FpkmBEr4l8Z4hi8gl+P1Spn/MTK3HapanMzSX4yUHuTEiF5hasWRxOaz+o5sxQ==} peerDependencies: '@firebase/app': 0.x @@ -2222,16 +2222,16 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.24': - resolution: {integrity: sha512-EWZTt6fJ7YmPHodQNsSxAIDZY2x8P5kRPvXAc5CmzzBm+NyPFhODbfDsNllDXDL8jlzp50bVWjDY+BXepZS9Mg==} + '@firebase/remote-config-compat@0.2.25': + resolution: {integrity: sha512-FnA5S4IxFJAAFrCnYzWlO0FCaizlYdqhe42ygFMA+wE/mUP+w36iXzHyKj1OO1A+2gyMFjeRHyg8HhkJ6c5vRA==} peerDependencies: '@firebase/app-compat': 0.x '@firebase/remote-config-types@0.5.1': resolution: {integrity: sha512-cX/1LT6KQwkXzck2eSzeKnuvXZCyr8qaPpDcikoJs7jmI+oBOXixpDLeDtWj1U6GNMkIoXrEDNoyT2Ypcyp5/A==} - '@firebase/remote-config@0.8.3': - resolution: {integrity: sha512-ggGKAaLy9YNOvpFoQZgm5p5SiFw3ZFtwti08dojnBQmQicpThTxvG5xZMSpCTYMj2o3gM/yK9CVd2w+kZub8YA==} + '@firebase/remote-config@0.8.4': + resolution: {integrity: sha512-lslywR5lGvHWTu4z/MPoYs3UwS3CKdeY+ELXY87087VsOpBpkD+9Orra23tA9GW683arPTDOM3CM6eKmtiOO3g==} peerDependencies: '@firebase/app': 0.x @@ -2295,8 +2295,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.6.0': - resolution: {integrity: sha512-HjoW3mPuEn7pnuKABJl9VbDoWDSF4nbwYKYvYYor7YjPeDxrrBxHzu2d1Prcd+BAuC4w+85UP6y7ZdcrQAoO7g==} + '@google/genai@2.7.0': + resolution: {integrity: sha512-tv0DRtcndt2oEhBYy+5mA0TaXH98+L1Gt0AP9unBfH7DP20KhB7+O3QqAN1Lz+laMARGTHS7BFQSNpLbl4gm1g==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2458,9 +2458,9 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.4.3': - resolution: {integrity: sha512-ai5LseTw9HhegupIgmo4cn7RpnCGznjjXu4OI+7jMR8vu7T1ZCCNMzFFAovUCjL1fl0cceksIN1++yQE59SmZw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/prompts@8.5.2': + resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2494,15 +2494,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.0.5': - resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.0.7': resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -5442,8 +5433,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.13.0: - resolution: {integrity: sha512-iutR8ejvAqk6qUClnsPz3U3VIjTWp243AX4cD3iifak5t56to1J29xUIQgSDDzaAqKvhshZerzSahwMQj2TlvA==} + firebase@12.14.0: + resolution: {integrity: sha512-aEZ/lniDR1hOCYpx/x/V8Nrrqq9pepKDNkqP/4WGZFC69gTv6F59Z4/54W/SUP4L/hFlrRNmWj35aweQq+IHow==} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -7562,8 +7553,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.8.0: - resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + semver@7.8.1: + resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} engines: {node: '>=10'} hasBin: true @@ -8074,8 +8065,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.22.3: - resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} + tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} engines: {node: '>=18.0.0'} hasBin: true @@ -8847,14 +8838,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) '@google-cloud/spanner': 8.0.0(supports-color@10.2.2) - '@google/genai': 2.6.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.4.3(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@google/genai': 2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.5.2(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) '@octokit/auth-app': 8.2.0 '@octokit/core': 7.0.6 '@octokit/graphql': 9.0.3 @@ -8884,7 +8875,7 @@ snapshots: ejs: 5.0.2 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.13.0 + firebase: 12.14.0 folder-hash: 4.1.3(supports-color@10.2.2) jasmine: 6.2.0 jasmine-core: 6.2.0 @@ -8893,9 +8884,9 @@ snapshots: minimatch: 10.2.5 multimatch: 8.0.0 nock: 14.0.15 - semver: 7.8.0 + semver: 7.8.1 supports-color: 10.2.2 - tsx: 4.22.3 + tsx: 4.22.4 typed-graphqlify: 3.1.6 typescript: 6.0.3 utf-8-validate: 6.0.6 @@ -9948,9 +9939,9 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@firebase/ai@2.12.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/ai@2.13.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/app-check-interop-types': 0.3.4 '@firebase/app-types': 0.9.5 '@firebase/component': 0.7.3 @@ -9958,11 +9949,11 @@ snapshots: '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.28(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/analytics-compat@0.2.28(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/analytics': 0.10.22(@firebase/app@0.14.12) + '@firebase/analytics': 0.10.22(@firebase/app@0.14.13) '@firebase/analytics-types': 0.8.4 - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -9971,20 +9962,20 @@ snapshots: '@firebase/analytics-types@0.8.4': {} - '@firebase/analytics@0.10.22(@firebase/app@0.14.12)': + '@firebase/analytics@0.10.22(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.3(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/app-check-compat@0.4.4(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-check': 0.11.3(@firebase/app@0.14.12) + '@firebase/app-check': 0.11.4(@firebase/app@0.14.13) '@firebase/app-check-types': 0.5.4 - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -9996,17 +9987,17 @@ snapshots: '@firebase/app-check-types@0.5.4': {} - '@firebase/app-check@0.11.3(@firebase/app@0.14.12)': + '@firebase/app-check@0.11.4(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/app-compat@0.5.12': + '@firebase/app-compat@0.5.13': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -10016,7 +10007,7 @@ snapshots: dependencies: '@firebase/logger': 0.5.1 - '@firebase/app@0.14.12': + '@firebase/app@0.14.13': dependencies: '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 @@ -10024,10 +10015,10 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.6(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/auth-compat@0.6.7(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 - '@firebase/auth': 1.13.1(@firebase/app@0.14.12) + '@firebase/app-compat': 0.5.13 + '@firebase/auth': 1.13.2(@firebase/app@0.14.13) '@firebase/auth-types': 0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 @@ -10044,9 +10035,9 @@ snapshots: '@firebase/app-types': 0.9.5 '@firebase/util': 1.15.1 - '@firebase/auth@1.13.1(@firebase/app@0.14.12)': + '@firebase/auth@1.13.2(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -10057,9 +10048,9 @@ snapshots: '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/data-connect@0.7.0(@firebase/app@0.14.12)': + '@firebase/data-connect@0.7.1(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/auth-interop-types': 0.2.5 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 @@ -10090,11 +10081,11 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.9(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/firestore-compat@0.4.10(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/firestore': 4.14.1(@firebase/app@0.14.12) + '@firebase/firestore': 4.15.0(@firebase/app@0.14.13) '@firebase/firestore-types': 3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10107,9 +10098,9 @@ snapshots: '@firebase/app-types': 0.9.5 '@firebase/util': 1.15.1 - '@firebase/firestore@4.14.1(@firebase/app@0.14.12)': + '@firebase/firestore@4.15.0(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -10118,11 +10109,11 @@ snapshots: '@grpc/proto-loader': 0.7.15 tslib: 2.8.1 - '@firebase/functions-compat@0.4.4(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/functions-compat@0.4.5(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/functions': 0.13.4(@firebase/app@0.14.12) + '@firebase/functions': 0.13.5(@firebase/app@0.14.13) '@firebase/functions-types': 0.6.4 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10131,21 +10122,21 @@ snapshots: '@firebase/functions-types@0.6.4': {} - '@firebase/functions@0.13.4(@firebase/app@0.14.12)': + '@firebase/functions@0.13.5(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/app-check-interop-types': 0.3.4 '@firebase/auth-interop-types': 0.2.5 '@firebase/component': 0.7.3 - '@firebase/messaging-interop-types': 0.2.4 + '@firebase/messaging-interop-types': 0.2.5 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/installations-compat@0.2.22(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/installations-compat@0.2.22(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/installations-types': 0.5.4(@firebase/app-types@0.9.5) '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10157,9 +10148,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.5 - '@firebase/installations@0.6.22(@firebase/app@0.14.12)': + '@firebase/installations@0.6.22(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 idb: 7.1.1 @@ -10169,34 +10160,34 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.26(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/messaging-compat@0.2.27(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/messaging': 0.12.26(@firebase/app@0.14.12) + '@firebase/messaging': 0.13.0(@firebase/app@0.14.13) '@firebase/util': 1.15.1 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' - '@firebase/messaging-interop-types@0.2.4': {} + '@firebase/messaging-interop-types@0.2.5': {} - '@firebase/messaging@0.12.26(@firebase/app@0.14.12)': + '@firebase/messaging@0.13.0(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) - '@firebase/messaging-interop-types': 0.2.4 + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) + '@firebase/messaging-interop-types': 0.2.5 '@firebase/util': 1.15.1 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.25(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/performance-compat@0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 - '@firebase/performance': 0.7.12(@firebase/app@0.14.12) + '@firebase/performance': 0.7.12(@firebase/app@0.14.13) '@firebase/performance-types': 0.2.4 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10205,22 +10196,22 @@ snapshots: '@firebase/performance-types@0.2.4': {} - '@firebase/performance@0.7.12(@firebase/app@0.14.12)': + '@firebase/performance@0.7.12(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.24(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/remote-config-compat@0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 - '@firebase/remote-config': 0.8.3(@firebase/app@0.14.12) + '@firebase/remote-config': 0.8.4(@firebase/app@0.14.13) '@firebase/remote-config-types': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10229,20 +10220,20 @@ snapshots: '@firebase/remote-config-types@0.5.1': {} - '@firebase/remote-config@0.8.3(@firebase/app@0.14.12)': + '@firebase/remote-config@0.8.4(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/storage-compat@0.4.3(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/storage-compat@0.4.3(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/storage': 0.14.3(@firebase/app@0.14.12) + '@firebase/storage': 0.14.3(@firebase/app@0.14.13) '@firebase/storage-types': 0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10255,9 +10246,9 @@ snapshots: '@firebase/app-types': 0.9.5 '@firebase/util': 1.15.1 - '@firebase/storage@0.14.3(@firebase/app@0.14.12)': + '@firebase/storage@0.14.3(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10331,7 +10322,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.6.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': + '@google/genai@2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.6.2(supports-color@10.2.2) p-retry: 4.6.2 @@ -10489,7 +10480,7 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/prompts@8.4.3(@types/node@24.12.4)': + '@inquirer/prompts@8.5.2(@types/node@24.12.4)': dependencies: '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) '@inquirer/confirm': 6.1.1(@types/node@24.12.4) @@ -10528,10 +10519,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/type@4.0.5(@types/node@24.12.4)': - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/type@4.0.7(@types/node@24.12.4)': optionalDependencies: '@types/node': 24.12.4 @@ -12115,9 +12102,9 @@ snapshots: lodash: 4.18.1 minimatch: 7.4.9 - '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: @@ -12131,7 +12118,7 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) '@vitest/expect@4.1.5': dependencies: @@ -12142,13 +12129,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.5(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.5(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) '@vitest/pretty-format@4.1.5': dependencies: @@ -13942,35 +13929,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.13.0: + firebase@12.14.0: dependencies: - '@firebase/ai': 2.12.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/analytics': 0.10.22(@firebase/app@0.14.12) - '@firebase/analytics-compat': 0.2.28(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/app': 0.14.12 - '@firebase/app-check': 0.11.3(@firebase/app@0.14.12) - '@firebase/app-check-compat': 0.4.3(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/app-compat': 0.5.12 + '@firebase/ai': 2.13.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/analytics': 0.10.22(@firebase/app@0.14.13) + '@firebase/analytics-compat': 0.2.28(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/app': 0.14.13 + '@firebase/app-check': 0.11.4(@firebase/app@0.14.13) + '@firebase/app-check-compat': 0.4.4(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/app-compat': 0.5.13 '@firebase/app-types': 0.9.5 - '@firebase/auth': 1.13.1(@firebase/app@0.14.12) - '@firebase/auth-compat': 0.6.6(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/data-connect': 0.7.0(@firebase/app@0.14.12) + '@firebase/auth': 1.13.2(@firebase/app@0.14.13) + '@firebase/auth-compat': 0.6.7(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/data-connect': 0.7.1(@firebase/app@0.14.13) '@firebase/database': 1.1.3 '@firebase/database-compat': 2.1.4 - '@firebase/firestore': 4.14.1(@firebase/app@0.14.12) - '@firebase/firestore-compat': 0.4.9(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/functions': 0.13.4(@firebase/app@0.14.12) - '@firebase/functions-compat': 0.4.4(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) - '@firebase/installations-compat': 0.2.22(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/messaging': 0.12.26(@firebase/app@0.14.12) - '@firebase/messaging-compat': 0.2.26(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/performance': 0.7.12(@firebase/app@0.14.12) - '@firebase/performance-compat': 0.2.25(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/remote-config': 0.8.3(@firebase/app@0.14.12) - '@firebase/remote-config-compat': 0.2.24(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/storage': 0.14.3(@firebase/app@0.14.12) - '@firebase/storage-compat': 0.4.3(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) + '@firebase/firestore': 4.15.0(@firebase/app@0.14.13) + '@firebase/firestore-compat': 0.4.10(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/functions': 0.13.5(@firebase/app@0.14.13) + '@firebase/functions-compat': 0.4.5(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) + '@firebase/installations-compat': 0.2.22(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/messaging': 0.13.0(@firebase/app@0.14.13) + '@firebase/messaging-compat': 0.2.27(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/performance': 0.7.12(@firebase/app@0.14.13) + '@firebase/performance-compat': 0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/remote-config': 0.8.4(@firebase/app@0.14.13) + '@firebase/remote-config-compat': 0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/storage': 0.14.3(@firebase/app@0.14.13) + '@firebase/storage-compat': 0.4.3(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) '@firebase/util': 1.15.1 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -16356,7 +16343,7 @@ snapshots: semver@7.7.4: {} - semver@7.8.0: {} + semver@7.8.1: {} send@0.19.2: dependencies: @@ -16992,7 +16979,7 @@ snapshots: tslib@2.8.1: {} - tsx@4.22.3: + tsx@4.22.4: dependencies: esbuild: 0.28.0 optionalDependencies: @@ -17242,7 +17229,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0): + vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -17257,13 +17244,13 @@ snapshots: less: 4.6.4 sass: 1.99.0 terser: 5.46.2 - tsx: 4.22.3 + tsx: 4.22.4 yaml: 2.9.0 - vitest@4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0): + vitest@4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.5(vite@7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.5 '@vitest/runner': 4.1.5 '@vitest/snapshot': 4.1.5 @@ -17280,7 +17267,7 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.2(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 From 918102a9373085394c41f10d9f5df3e3c17b263f Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:47:20 -0400 Subject: [PATCH 16/23] fix(@angular/cli): isolate temporary package installation from parent pnpm workspace Write an empty pnpm-workspace.yaml file inside the temporary installation directory when using pnpm. This acts as a workspace boundary, preventing pnpm from searching up the directory tree and modifying the parent workspace's lockfile during ng update. (cherry picked from commit 167aea1098f00e604e4b383f7d897b76bfd824de) --- .../src/package-managers/package-manager.ts | 77 +++++++++++++ .../package-managers/package-manager_spec.ts | 109 ++++++++++++++++++ .../src/package-managers/testing/mock-host.ts | 21 +++- .../e2e/tests/update/update-pnpm-workspace.ts | 33 ++++++ 4 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 tests/e2e/tests/update/update-pnpm-workspace.ts diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index 33b8b07d48e3..46adbd118b9b 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -647,6 +647,25 @@ export class PackageManager { // Writing an empty package.json file beforehand prevents this. await this.host.writeFile(join(workingDirectory, 'package.json'), '{}'); + // To prevent pnpm from traversing up the directory tree and modifying the project's workspace lockfile, + // copy the project's `pnpm-workspace.yaml` (excluding monorepo local overrides/packages) + // to the temporary directory if it exists, or write an empty one to act as a workspace boundary. + if (this.name === 'pnpm') { + try { + const workspaceConfigPath = join(this.cwd, 'pnpm-workspace.yaml'); + const content = await this.host.readFile(workspaceConfigPath); + await this.host.writeFile( + join(workingDirectory, 'pnpm-workspace.yaml'), + sanitizePnpmWorkspace(content), + ); + } catch { + await this.host.writeFile( + join(workingDirectory, 'pnpm-workspace.yaml'), + "packages:\n - '.'\n", + ); + } + } + // Copy configuration files if the package manager requires it (e.g., bun). if (this.descriptor.copyConfigFromProject) { for (const configFile of this.descriptor.configFiles) { @@ -675,3 +694,61 @@ export class PackageManager { return { workingDirectory, cleanup }; } } + +/** + * Sanitizes a `pnpm-workspace.yaml` file content to be safely used inside + * a temporary installation directory. + * + * This function removes monorepo-specific settings that would fail or cause + * unintended behaviors in a standalone, temporary project environment: + * 1. Removes the `overrides:` block, as it may contain `workspace:` protocol + * resolutions which cannot be resolved in a standalone folder. + * 2. Rewrites the `packages:` block to include only the current directory (`'.'`), + * isolating the temporary installation from other projects in the monorepo. + * + * All other settings (such as `minimumReleaseAge`, package extensions, etc.) + * are preserved intact. + * + * @param content The original `pnpm-workspace.yaml` content. + * @returns The sanitized YAML content. + */ +function sanitizePnpmWorkspace(content: string): string { + const lines = content.split(/\r?\n/); + const result: string[] = []; + let inBlockToRemove = false; + let blockIndent = 0; + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) { + result.push(line); + continue; + } + + // Determine the current line's indentation level. + const indent = line.length - line.trimStart().length; + + // If we are currently parsing a block to remove, skip any lines with larger indentation. + if (inBlockToRemove) { + if (indent > blockIndent) { + continue; + } + inBlockToRemove = false; + } + + // Identify blocks we want to remove or customize (e.g. 'overrides' or 'packages'). + if (trimmed.startsWith('overrides:') || trimmed.startsWith('packages:')) { + inBlockToRemove = true; + blockIndent = indent; + if (trimmed.startsWith('packages:')) { + // Replace packages list to restrict it strictly to the current standalone folder. + result.push(line.replace(/packages:.*/, "packages:\n - '.'")); + } + continue; + } + + result.push(line); + } + + return result.join('\n'); +} diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index 8d439d9b3b75..176b604eeca6 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -86,6 +86,115 @@ describe('PackageManager', () => { }); }); + describe('acquireTempPackage', () => { + it('should copy and sanitize pnpm-workspace.yaml when package manager is pnpm and workspace file exists', async () => { + const pnpmDescriptor = SUPPORTED_PACKAGE_MANAGERS['pnpm']; + const testHost = new MockHost({ '/tmp/project/node_modules': true }); + const pm = new PackageManager(testHost, '/tmp/project', pnpmDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const mockWorkspaceContent = [ + 'packages:', + ' - .', + ' - packages/*', + 'minimumReleaseAge: 1440', + 'minimumReleaseAgeExclude:', + " - '@angular/*'", + 'overrides:', + " '@angular/build': workspace:*", + 'packageExtensions:', + ' vitest:', + ' peerDependencies:', + " '@vitest/coverage-v8': '*'", + ].join('\n'); + const readFileSpy = spyOn(testHost, 'readFile').and.resolveTo(mockWorkspaceContent); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + expect(readFileSpy).toHaveBeenCalledWith('/tmp/project/pnpm-workspace.yaml'); + + const expectedSanitizedContent = [ + 'packages:', + " - '.'", + 'minimumReleaseAge: 1440', + 'minimumReleaseAgeExclude:', + " - '@angular/*'", + 'packageExtensions:', + ' vitest:', + ' peerDependencies:', + " '@vitest/coverage-v8': '*'", + ].join('\n'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', + expectedSanitizedContent, + ); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + '{}', + ); + }); + + it('should write empty pnpm-workspace.yaml as fallback when package manager is pnpm and workspace file does not exist', async () => { + const pnpmDescriptor = SUPPORTED_PACKAGE_MANAGERS['pnpm']; + const testHost = new MockHost({ '/tmp/project/node_modules': true }); + const pm = new PackageManager(testHost, '/tmp/project', pnpmDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const readFileSpy = spyOn(testHost, 'readFile').and.throwError( + new Error('ENOENT: no such file or directory'), + ); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + expect(readFileSpy).toHaveBeenCalledWith('/tmp/project/pnpm-workspace.yaml'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + '{}', + ); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', + "packages:\n - '.'\n", + ); + }); + + it('should NOT write pnpm-workspace.yaml when package manager is npm', async () => { + const npmDescriptor = SUPPORTED_PACKAGE_MANAGERS['npm']; + const testHost = new MockHost({ '/tmp/project/node_modules': true }); + const pm = new PackageManager(testHost, '/tmp/project', npmDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + '{}', + ); + expect(writeFileSpy).not.toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', + '', + ); + }); + }); + describe('initializationError', () => { it('should throw initializationError when running commands', async () => { const error = new Error('Not installed'); diff --git a/packages/angular/cli/src/package-managers/testing/mock-host.ts b/packages/angular/cli/src/package-managers/testing/mock-host.ts index 46e71be3cf60..9051cfae3b04 100644 --- a/packages/angular/cli/src/package-managers/testing/mock-host.ts +++ b/packages/angular/cli/src/package-managers/testing/mock-host.ts @@ -51,27 +51,36 @@ export class MockHost implements Host { } as Stats); } - runCommand(): Promise<{ stdout: string; stderr: string }> { + runCommand( + command: string, + args: readonly string[], + options?: { + timeout?: number; + stdio?: 'pipe' | 'ignore'; + cwd?: string; + env?: Record; + }, + ): Promise<{ stdout: string; stderr: string }> { throw new Error('Method not implemented.'); } - createTempDirectory(): Promise { + createTempDirectory(baseDir?: string): Promise { throw new Error('Method not implemented.'); } - deleteDirectory(): Promise { + deleteDirectory(path: string): Promise { throw new Error('Method not implemented.'); } - writeFile(): Promise { + writeFile(path: string, content: string): Promise { throw new Error('Method not implemented.'); } - readFile(): Promise { + readFile(path: string): Promise { throw new Error('Method not implemented.'); } - copyFile(): Promise { + copyFile(src: string, dest: string): Promise { throw new Error('Method not implemented.'); } } diff --git a/tests/e2e/tests/update/update-pnpm-workspace.ts b/tests/e2e/tests/update/update-pnpm-workspace.ts new file mode 100644 index 000000000000..29aff7bff42a --- /dev/null +++ b/tests/e2e/tests/update/update-pnpm-workspace.ts @@ -0,0 +1,33 @@ +import { createProjectFromAsset } from '../../utils/assets'; +import { readFile, writeFile } from '../../utils/fs'; +import { getActivePackageManager } from '../../utils/packages'; +import { ng } from '../../utils/process'; + +export default async function () { + if (getActivePackageManager() !== 'pnpm') { + return; + } + + let restoreRegistry: (() => Promise) | undefined; + + try { + // Setup project from older asset using the public registry + restoreRegistry = await createProjectFromAsset('20.0-project', true); + + // Create pnpm-workspace.yaml inside the project directory + await writeFile('pnpm-workspace.yaml', "packages:\n - '.'\n"); + + // Run ng update on @angular/cli to trigger the update from version 20 to the next major version + await ng('update', '@angular/cli@21', '@angular/core@21'); + + // Verify that the pnpm lockfile does not contain references to the temporary package directory + const lockfileContent = await readFile('pnpm-lock.yaml'); + if (lockfileContent.includes('angular-cli-tmp-packages-')) { + throw new Error( + 'pnpm-lock.yaml contains reference to temporary package directory, isolation failed!', + ); + } + } finally { + await restoreRegistry?.(); + } +} From 12199df00f2e3e8436ada13e04799e5825eb3f7b Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:19:59 -0400 Subject: [PATCH 17/23] fix(@schematics/angular): use null objects and callbacks in karma-to-vitest migration The karma-to-vitest migration schematic previously used plain JavaScript objects as dictionaries when processing custom build options and analyzing Karma AST configurations. In environments where the input workspace files contain custom keys such as "__proto__", these assignments would leak properties onto the global Object prototype. (cherry picked from commit f6b01f3b7c4227dec9dc56ad1cfab5a98e4ef49a) --- .../migrate-karma-to-vitest/karma-config-analyzer.ts | 2 +- .../migrate-karma-to-vitest/karma-config-comparer.ts | 5 ++--- .../angular/migrations/migrate-karma-to-vitest/migration.ts | 6 +++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts index d39e1a16bab6..8a1c49c58f61 100644 --- a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts +++ b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts @@ -142,7 +142,7 @@ export function analyzeKarmaConfig(content: string): KarmaConfigAnalysis { case ts.SyntaxKind.ArrayLiteralExpression: return (node as ts.ArrayLiteralExpression).elements.map(extractValue); case ts.SyntaxKind.ObjectLiteralExpression: { - const obj: { [key: string]: KarmaConfigValue } = {}; + const obj: { [key: string]: KarmaConfigValue } = Object.create(null); for (const prop of (node as ts.ObjectLiteralExpression).properties) { if (isSupportedPropertyAssignment(prop)) { // Recursively extract values for nested objects. diff --git a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts index 0c11a7196f1c..f7bef0213b1f 100644 --- a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts +++ b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts @@ -46,11 +46,10 @@ export async function generateDefaultKarmaConfig( // TODO: Replace this with the actual schematic templating logic. template = template - .replace( - /<%= relativePathToWorkspaceRoot %>/g, + .replace(/<%= relativePathToWorkspaceRoot %>/g, () => path.normalize(relativePathToWorkspaceRoot).replace(/\\/g, '/'), ) - .replace(/<%= folderName %>/g, projectName); + .replace(/<%= folderName %>/g, () => projectName); const devkitPluginRegex = /<% if \(needDevkitPlugin\) { %>(.*?)<% } %>/gs; const replacement = needDevkitPlugin ? '$1' : ''; diff --git a/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts b/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts index 7d2306428b32..fc5b11fb5eb0 100644 --- a/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts +++ b/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts @@ -32,6 +32,7 @@ async function processTestTargetOptions( let needsIstanbul = false; for (const [configName, options] of allTargetOptions(testTarget, false)) { const configKey = configName || ''; + if (!customBuildOptions[configKey]) { // Match Karma behavior where AOT was disabled by default customBuildOptions[configKey] = { @@ -276,7 +277,10 @@ function updateProjects(tree: Tree, context: SchematicContext): Rule { tsConfigsToUpdate.add(join(project.root, 'tsconfig.spec.json')); // Store custom build options to move to a new build configuration if needed - const customBuildOptions: Record> = {}; + const customBuildOptions: Record< + string, + Record + > = Object.create(null); const projectCoverageInfo = await processTestTargetOptions( testTarget, From 56ac3484f13560cb90aff9e1d504a2f8afd345e6 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 9 Jun 2026 06:16:33 +0000 Subject: [PATCH 18/23] build: lock file maintenance See associated pull request for more information. --- pnpm-lock.yaml | 484 +++++++++++++++++++++++++++---------------------- 1 file changed, 269 insertions(+), 215 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d341397968f3..ed16bfd9a69c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -144,7 +144,7 @@ importers: version: 4.17.24 '@types/node': specifier: ^22.12.0 - version: 22.19.19 + version: 22.19.20 '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 @@ -273,7 +273,7 @@ importers: version: 6.4.1(rollup@4.60.2)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.6 - version: 0.5.6(@types/node@22.19.19)(rollup@4.60.2) + version: 0.5.6(@types/node@22.19.20)(rollup@4.60.2) semver: specifier: 7.7.4 version: 7.7.4 @@ -1648,8 +1648,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.4': - resolution: {integrity: sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==} + '@csstools/css-syntax-patches-for-csstree@1.1.5': + resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -2267,28 +2267,28 @@ packages: '@glideapps/ts-necessities@2.2.3': resolution: {integrity: sha512-gXi0awOZLHk3TbW55GZLCPP6O+y/b5X1pBXKBVckFONSwF1z1E5ND2BGJsghQFah+pW7pkkyFb2VhUQI2qhL5w==} - '@google-cloud/common@6.0.0': - resolution: {integrity: sha512-IXh04DlkLMxWgYLIUYuHHKXKOUwPDzDgke1ykkkJPe48cGIS9kkL2U/o0pm4ankHLlvzLF/ma1eO86n/bkumIA==} + '@google-cloud/common@6.0.1': + resolution: {integrity: sha512-1uvKzbmAWUdchIYRsg0f4rUmezOamWuVBSWAPAhnYoUE5OiPEx6v6JOxFIdr3MsrqV+6fyLV3EI1vMPlHoeRvw==} engines: {node: '>=18'} - '@google-cloud/precise-date@5.0.0': - resolution: {integrity: sha512-9h0Gvw92EvPdE8AK8AgZPbMnH5ftDyPtKm7/KUfcJVaPEPjwGDsJd1QV0H8esBDV4II41R/2lDWH1epBqIoKUw==} + '@google-cloud/precise-date@5.0.1': + resolution: {integrity: sha512-9HlRbOcDb8b2tSsOvljPD/Rm+Jn9KxMVB6sLf85CBnoIYdCFTNO1FIizQ13P75itXpSXsLuMlg1XK5opHKVzjg==} engines: {node: '>=18'} '@google-cloud/projectify@4.0.0': resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} engines: {node: '>=14.0.0'} - '@google-cloud/projectify@5.0.0': - resolution: {integrity: sha512-XXQLaIcLrOAMWvRrzz+mlUGtN6vlVNja3XQbMqRi/V7XJTAVwib3VcKd7oRwyZPkp7rBVlHGcaqdyGRrcnkhlA==} + '@google-cloud/projectify@5.0.1': + resolution: {integrity: sha512-yAIqOAlDwx1nPmmA0WICFMSGttVuWX97HpphN71JQ7G+tD/Q6lHbiCTcMJ9r2+PwX6sIwK3ahO4FdSNt5pwhFg==} engines: {node: '>=18'} '@google-cloud/promisify@4.1.0': resolution: {integrity: sha512-G/FQx5cE/+DqBbOpA5jKsegGwdPniU6PuIEMt+qxWgFxvxuFOzVmp6zYchtYuwAWV5/8Dgs0yAmjvNZv3uXLQg==} engines: {node: '>=18'} - '@google-cloud/promisify@5.0.0': - resolution: {integrity: sha512-N8qS6dlORGHwk7WjGXKOSsLjIjNINCPicsOX6gyyLiYk7mq3MtII96NZ9N2ahwA2vnkLmZODOIH9rlNniYWvCQ==} + '@google-cloud/promisify@5.0.1': + resolution: {integrity: sha512-Ste6NGraHq30ge3Sdq7m+pZE6lRUlkt2YgsEdq/vcoEgdbdZ/7h37Z1dMvivjhlbgrcmYRvlLF9FgI7tXm5wjg==} engines: {node: '>=18'} '@google-cloud/spanner@8.0.0': @@ -2576,50 +2576,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.57.5': - resolution: {integrity: sha512-wl7eAKUwOcEZ8lL2/C38+w6VnNtBiNmvzKstlKPqRV/ymzg/7Aal5H74HEazSM2khYn9XG20I3fRp0Wr7xIbHA==} + '@jsonjoy.com/fs-core@4.57.6': + resolution: {integrity: sha512-uI++Wx6VkBJqVmkb4ZeExwAVpZiA2Do5NrEtXoDk0Pdvce3ytFXJoviT1sLOj16+qDIMnD5nWPfOhVpnDmRJKg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.57.5': - resolution: {integrity: sha512-zIUMYeOgAdhA1M3JvceA2Fli7qas2WJrv6qmruXbq81bgIRKUM1LueJ1G0VRPk4D8wfOceBpayWQZqSEXA0AGA==} + '@jsonjoy.com/fs-fsa@4.57.6': + resolution: {integrity: sha512-pKkw/yC5CzSZKhIIUIsH1przOa+K5jGmZIg1sWaSF24JojyrUFbjcQv7QrcGAudriei6HQ6R0BFj+V8NbQinJw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.57.5': - resolution: {integrity: sha512-maev+EH0kBJt7R6GZQgRmL5cHvs46PS71Y5M1FfZKN2/JVSAZPpdrLS+z7KYrvPn4oIYMKcG/XAhircG3eP88g==} + '@jsonjoy.com/fs-node-builtins@4.57.6': + resolution: {integrity: sha512-V4DgEFT3Cg5S9fCMOZSCVdTxdJWWLBO0WnAazV7hnCM96u5zXHyW/ubDAfcSVwqjkMJ50W1Y44IXtxRoIwaCVg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.57.5': - resolution: {integrity: sha512-6IQi4TNoR1d+cSRZisWh6eqQ2mq32qgwESjVeXDs2pMWa+H/pZ24kSJKrDkyooUIfk1OIe40Dv9bnqc0FMcFjQ==} + '@jsonjoy.com/fs-node-to-fsa@4.57.6': + resolution: {integrity: sha512-+JptNw3iifihxH2rEXrninDzX4FFVW8JD/wPR8GbJPAeL9CQUSblrlumOPB5gZuS7tYRX+PJPLtT7XzKoRhv/Q==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.57.5': - resolution: {integrity: sha512-u8GXaNr2VeQvHBXbJ9byY6GWP5z3HK3kCmdEPwVzjcgpEyAPjNnl0alP3Ylo6Aa4JSS8Ssc/F4+q69/03J2bUA==} + '@jsonjoy.com/fs-node-utils@4.57.6': + resolution: {integrity: sha512-foyUrfS7WmYEUzqYXSNxmJBcSj04TABrkpFabwO9SCDCpVCfJ+qG+2sk5FjfiflG2n0SDFZDCJ6vYlJAEpxJFg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.57.5': - resolution: {integrity: sha512-F6kdnfsmK6q+WEjGhCOd/2iJpcmffj8q3qgXUG1/gHMXaThZp30Ienk3eMT+GfOpEbuVqoPvqNe8IwiPlDk/QQ==} + '@jsonjoy.com/fs-node@4.57.6': + resolution: {integrity: sha512-Kbn1jdkvDN4F2+BhoB6mMu7NCbhP0bgA5NcI1aJj/Q5UcU+I1JLLW+dEQean33iV4tXv35AzBVKPICnDltBpxw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.57.5': - resolution: {integrity: sha512-fTcwBpqk9CEmzYd4Un4WxemvWbS69dGFEQgYmCQ0q02xsMzsZcTKzd3kduB46DBhjRTK77ga4HIQe08Oyn86kg==} + '@jsonjoy.com/fs-print@4.57.6': + resolution: {integrity: sha512-96eAn4Dudtt67LTeuU47yUD+pg9/G/oKpI10zei9ljk3X3WK4lYKc+n3cpaPCAbKPzoyfxl0mXm8f8Y7BOSFXw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.57.5': - resolution: {integrity: sha512-oAUUlG+E4uBw5sFERdMu3FRqt0hEM6jVCIKWkj194xiWppfShAqbMK5G3PahBXfGiTtlJjYErUWDbX3UhQhldw==} + '@jsonjoy.com/fs-snapshot@4.57.6': + resolution: {integrity: sha512-V57CMzbOgTzUWGOWQ8GzHQdpJP6JnrYVNCtTBNxVYEnlVRvo4uEJqHhtAT8vhDFrIuJOXLrTL1Fki4h5oI7xxg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -3714,8 +3714,8 @@ packages: '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} - '@types/node@22.19.19': - resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==} + '@types/node@22.19.20': + resolution: {integrity: sha512-6tELRwSDYWW9EdZhbeZmYGZ1/7Djkt+Ah3/ScEYT9cDord7UJzasR/4D3VONg9tQI5CDp+/CZC1AXj2pCFOvpw==} '@types/node@24.12.4': resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} @@ -4374,8 +4374,8 @@ packages: bare-events: optional: true - bare-url@2.4.3: - resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==} + bare-url@2.4.5: + resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4384,8 +4384,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.33: - resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} + baseline-browser-mapping@2.10.34: + resolution: {integrity: sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4535,8 +4535,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001797: + resolution: {integrity: sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -4755,8 +4755,8 @@ packages: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} - cosmiconfig@9.0.1: - resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + cosmiconfig@9.0.2: + resolution: {integrity: sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -5022,8 +5022,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.366: - resolution: {integrity: sha512-OlRuhb688YTCzzU3gXPLn6nGyd+F+53INE1qaKKlu6kETErE8FYsyDh0XqXEU+uBRn0MpCzz2vfNwORhkap8qg==} + electron-to-chromium@1.5.368: + resolution: {integrity: sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5063,8 +5063,8 @@ packages: resolution: {integrity: sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.22.1: - resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} + enhanced-resolve@5.23.0: + resolution: {integrity: sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==} engines: {node: '>=10.13.0'} ent@2.2.2: @@ -5527,14 +5527,22 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - gaxios@7.1.4: - resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + gaxios@7.1.3: + resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} + engines: {node: '>=18'} + + gaxios@7.1.5: + resolution: {integrity: sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==} engines: {node: '>=18'} gcp-metadata@8.1.2: resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} engines: {node: '>=18'} + gcp-metadata@8.1.3: + resolution: {integrity: sha512-ziTrzUhhpL9Zk5k0HHzgP/KIpWDJT0VMBC/ynt/QIBvTW+UUcSivQRl6VlwTf/EilDxtSWklHoRsKy1c4k+59w==} + engines: {node: '>=18'} + generator-function@2.0.1: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} @@ -5624,12 +5632,16 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - google-auth-library@10.6.2: - resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + google-auth-library@10.5.0: + resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} + engines: {node: '>=18'} + + google-auth-library@10.7.0: + resolution: {integrity: sha512-QpTAbNJ36TliZLx3TTtahR8HG0hN9RllL1e3FymOvQSIKK8JmgV58H924ub2wa2DsS3ANjjP1Aw1N+Ramc8hqQ==} engines: {node: '>=18'} - google-gax@5.0.6: - resolution: {integrity: sha512-1kGbqVQBZPAAu4+/R1XxPQKP0ydbNYoLAr4l0ZO2bMV0kLyLW4I1gAk++qBLWt7DPORTzmWRMsCZe86gDjShJA==} + google-gax@5.0.7: + resolution: {integrity: sha512-EhiqaWWJ+9h7sCcKJTsoo6tMcjokVHhWsbSuWCnZJT4vIBP3y4mAoFLnt9SzgkVZeq24ZsFaArr06nnYYku2yA==} engines: {node: '>=18'} google-logging-utils@1.1.3: @@ -5663,6 +5675,10 @@ packages: peerDependencies: protobufjs: '*' + gtoken@8.0.0: + resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==} + engines: {node: '>=18'} + gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} hasBin: true @@ -6484,8 +6500,8 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} - memfs@4.57.5: - resolution: {integrity: sha512-qT8bQJyjF6+DsDI9X1yMwUyIkYHrZI8D2PaWjze8aUUbGUkcNlxppcRZF/0VWesIPHtgx6T2mLx3qPmTQxUd6A==} + memfs@4.57.6: + resolution: {integrity: sha512-WQK+DGjKCnPdpSyJUXphz+COF2uEhhsxQ3VIWBSbzpbbXuch3h4FePMqXrXGdLjsTgo4JFzBFsP6AWd9pVazGw==} peerDependencies: tslib: '2' @@ -6650,8 +6666,8 @@ packages: resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} hasBin: true - msgpackr@1.11.12: - resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} + msgpackr@1.11.13: + resolution: {integrity: sha512-pWaxg0k1iiNdkAayUQ7Zlz/vYNfVefUttmHxqFcQjjtyqFa3w4x5rginOEzy/GvbWhBDD9K65/ZXyq8qz8utaQ==} multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} @@ -6762,8 +6778,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@12.3.0: - resolution: {integrity: sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==} + node-gyp@12.4.0: + resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true @@ -6854,8 +6870,9 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.2: + resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==} + engines: {node: '>=12.20.0'} on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} @@ -7393,8 +7410,8 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} - retry-request@8.0.2: - resolution: {integrity: sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==} + retry-request@8.0.3: + resolution: {integrity: sha512-qqoc4kkGgP9cmQDWELlOpAmfgJOg0Yi7MT82ZjiPWu451ayju4itwomjM4/dBEliify8C1b3tSaeCOldugtwPQ==} engines: {node: '>=18'} retry@0.13.1: @@ -7807,8 +7824,8 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamx@2.26.0: - resolution: {integrity: sha512-VvNG1K72Po/xwJzxZFnZ++Tbrv4lwSptsbkFuzXCJAYZvCK5nnxsvXU6ajqkv7chyiI1Y0YXq2Jh8Iy8Y7NF/A==} + streamx@2.27.0: + resolution: {integrity: sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -7829,12 +7846,12 @@ packages: resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} engines: {node: '>=20'} - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + string.prototype.trim@1.2.11: + resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + string.prototype.trimend@1.0.10: + resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==} engines: {node: '>= 0.4'} string.prototype.trimstart@1.0.8: @@ -7902,8 +7919,8 @@ packages: resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} - teeny-request@10.1.2: - resolution: {integrity: sha512-Xj0ZAQ0CeuQn6UxCDPLbFRlgcSTUEyO3+wiepr2grjIjyL/lMMs1Z4OwXn8kLvn/V1OuaEP0UY7Na6UDNNsYrQ==} + teeny-request@10.1.3: + resolution: {integrity: sha512-5yDliI1uWkYPo7W+Zvrxg6YmoWuj5iC5EydewqrRTvc68nyMTZhlPPlLg6cptUGfbQAb+N9XDPDPzF6N081lug==} engines: {node: '>=18'} teex@1.0.1: @@ -8160,8 +8177,8 @@ packages: resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==} engines: {node: '>=18.17'} - undici@7.27.0: - resolution: {integrity: sha512-+t2Z/GwkZQDtu00813aP66ygViGtPHKhhoFZpQKpKrE+9jIgES+Zw+mFNaDWOVRKiuJjuqKHzD3B1sfGg8+ZOQ==} + undici@7.27.2: + resolution: {integrity: sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==} engines: {node: '>=20.18.1'} undici@8.2.0: @@ -8445,8 +8462,8 @@ packages: webpack-cli: optional: true - websocket-driver@0.7.4: - resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + websocket-driver@0.7.5: + resolution: {integrity: sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==} engines: {node: '>=0.8.0'} websocket-extensions@0.1.4: @@ -8476,8 +8493,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.21: - resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==} + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} engines: {node: '>= 0.4'} which@1.3.1: @@ -9682,7 +9699,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.4(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -10263,36 +10280,36 @@ snapshots: '@glideapps/ts-necessities@2.2.3': {} - '@google-cloud/common@6.0.0(supports-color@10.2.2)': + '@google-cloud/common@6.0.1(supports-color@10.2.2)': dependencies: '@google-cloud/projectify': 4.0.0 '@google-cloud/promisify': 4.1.0 arrify: 2.0.1 duplexify: 4.1.3 extend: 3.0.2 - google-auth-library: 10.6.2(supports-color@10.2.2) + google-auth-library: 10.7.0(supports-color@10.2.2) html-entities: 2.6.0 - retry-request: 8.0.2(supports-color@10.2.2) - teeny-request: 10.1.2(supports-color@10.2.2) + retry-request: 8.0.3(supports-color@10.2.2) + teeny-request: 10.1.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - '@google-cloud/precise-date@5.0.0': {} + '@google-cloud/precise-date@5.0.1': {} '@google-cloud/projectify@4.0.0': {} - '@google-cloud/projectify@5.0.0': {} + '@google-cloud/projectify@5.0.1': {} '@google-cloud/promisify@4.1.0': {} - '@google-cloud/promisify@5.0.0': {} + '@google-cloud/promisify@5.0.1': {} '@google-cloud/spanner@8.0.0(supports-color@10.2.2)': dependencies: - '@google-cloud/common': 6.0.0(supports-color@10.2.2) - '@google-cloud/precise-date': 5.0.0 - '@google-cloud/projectify': 5.0.0 - '@google-cloud/promisify': 5.0.0 + '@google-cloud/common': 6.0.1(supports-color@10.2.2) + '@google-cloud/precise-date': 5.0.1 + '@google-cloud/projectify': 5.0.1 + '@google-cloud/promisify': 5.0.1 '@grpc/proto-loader': 0.7.15 '@opentelemetry/api': 1.9.1 '@opentelemetry/context-async-hooks': 2.7.1(@opentelemetry/api@1.9.1) @@ -10305,26 +10322,26 @@ snapshots: duplexify: 4.1.3 events-intercept: 2.0.0 extend: 3.0.2 - google-auth-library: 10.6.2(supports-color@10.2.2) - google-gax: 5.0.6(supports-color@10.2.2) + google-auth-library: 10.7.0(supports-color@10.2.2) + google-gax: 5.0.7(supports-color@10.2.2) grpc-gcp: 1.0.1(protobufjs@7.6.2) is: 3.3.2 lodash.snakecase: 4.1.1 merge-stream: 2.0.0 p-queue: 6.6.2 protobufjs: 7.6.2 - retry-request: 8.0.2(supports-color@10.2.2) + retry-request: 8.0.3(supports-color@10.2.2) split-array-stream: 2.0.0 stack-trace: 0.0.10 stream-events: 1.0.5 - teeny-request: 10.1.2(supports-color@10.2.2) + teeny-request: 10.1.3(supports-color@10.2.2) through2: 4.0.2 transitivePeerDependencies: - supports-color '@google/genai@2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': dependencies: - google-auth-library: 10.6.2(supports-color@10.2.2) + google-auth-library: 10.7.0(supports-color@10.2.2) p-retry: 4.6.2 protobufjs: 7.6.2 ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -10343,7 +10360,7 @@ snapshots: '@grpc/grpc-js@1.9.16': dependencies: '@grpc/proto-loader': 0.7.15 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@grpc/proto-loader@0.7.15': dependencies: @@ -10590,58 +10607,58 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.57.6(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.6(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.57.6(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10919,7 +10936,7 @@ snapshots: '@npmcli/node-gyp': 5.0.0 '@npmcli/package-json': 7.0.5 '@npmcli/promise-spawn': 9.0.1 - node-gyp: 12.3.0 + node-gyp: 12.4.0 proc-log: 6.1.0 '@octokit/auth-app@8.2.0': @@ -11558,16 +11575,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/browser-sync@2.29.1': dependencies: '@types/micromatch': 2.3.35 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/serve-static': 2.2.0 chokidar: 3.6.0 @@ -11578,26 +11595,26 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 4.19.8 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/connect@3.4.38': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/cors@2.8.19': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/deep-eql@4.0.2': {} '@types/duplexify@3.6.5': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ejs@3.1.5': {} @@ -11621,14 +11638,14 @@ snapshots: '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -11650,13 +11667,13 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/http-errors@2.0.5': {} '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ini@4.1.1': {} @@ -11672,7 +11689,7 @@ snapshots: '@types/karma@6.3.9': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 log4js: 6.9.1 transitivePeerDependencies: - supports-color @@ -11681,7 +11698,7 @@ snapshots: '@types/loader-utils@3.0.0(esbuild@0.28.0)': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 webpack: 5.106.2(esbuild@0.28.0) transitivePeerDependencies: - '@minify-html/node' @@ -11708,10 +11725,10 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 form-data: 4.0.5 - '@types/node@22.19.19': + '@types/node@22.19.20': dependencies: undici-types: 6.21.0 @@ -11723,7 +11740,7 @@ snapshots: '@types/npm-registry-fetch@8.0.9': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/node-fetch': 2.6.13 '@types/npm-package-arg': 6.1.4 '@types/npmlog': 7.0.0 @@ -11731,11 +11748,11 @@ snapshots: '@types/npmlog@7.0.0': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/pacote@11.1.8': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/npm-registry-fetch': 8.0.9 '@types/npmlog': 7.0.0 '@types/ssri': 7.1.5 @@ -11746,12 +11763,12 @@ snapshots: '@types/progress@2.0.7': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/pumpify@1.4.5': dependencies: '@types/duplexify': 3.6.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/qs@6.15.1': {} @@ -11761,7 +11778,7 @@ snapshots: '@types/responselike@1.0.0': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/retry@0.12.0': {} @@ -11772,11 +11789,11 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/send@1.2.1': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/serve-index@1.9.4': dependencies: @@ -11785,38 +11802,38 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ssri@7.1.5': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/stack-trace@0.0.33': {} '@types/tar-stream@3.1.4': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/watchpack@2.4.5': dependencies: '@types/graceful-fs': 4.1.9 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/which@3.0.4': {} '@types/ws@8.18.1': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/yargs-parser@21.0.3': {} @@ -11828,7 +11845,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 optional: true '@typescript-eslint/eslint-plugin@8.59.1(@typescript-eslint/parser@8.59.1(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)': @@ -12115,7 +12132,7 @@ snapshots: istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.3 - obug: 2.1.1 + obug: 2.1.2 std-env: 4.1.0 tinyrainbow: 3.1.0 vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.5)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0) @@ -12475,7 +12492,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.13): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001793 + caniuse-lite: 1.0.30001797 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.13 @@ -12541,7 +12558,7 @@ snapshots: bare-events: 2.9.1 bare-path: 3.0.1 bare-stream: 2.13.1(bare-events@2.9.1) - bare-url: 2.4.3 + bare-url: 2.4.5 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -12555,14 +12572,14 @@ snapshots: bare-stream@2.13.1(bare-events@2.9.1): dependencies: - streamx: 2.26.0 + streamx: 2.27.0 teex: 1.0.1 optionalDependencies: bare-events: 2.9.1 transitivePeerDependencies: - react-native-b4a - bare-url@2.4.3: + bare-url@2.4.5: dependencies: bare-path: 3.0.1 @@ -12570,7 +12587,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.10.33: {} + baseline-browser-mapping@2.10.34: {} basic-ftp@5.3.1: {} @@ -12727,9 +12744,9 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.33 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.366 + baseline-browser-mapping: 2.10.34 + caniuse-lite: 1.0.30001797 + electron-to-chromium: 1.5.368 node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) @@ -12802,7 +12819,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001797: {} caseless@0.12.0: {} @@ -13023,7 +13040,7 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig@9.0.1(typescript@6.0.3): + cosmiconfig@9.0.2(typescript@6.0.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 @@ -13275,7 +13292,7 @@ snapshots: ejs@5.0.2: {} - electron-to-chromium@1.5.366: {} + electron-to-chromium@1.5.368: {} emoji-regex@10.6.0: {} @@ -13314,7 +13331,7 @@ snapshots: engine.io@6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ws': 8.18.1 accepts: 1.3.8 base64id: 2.0.0 @@ -13328,7 +13345,7 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.22.1: + enhanced-resolve@5.23.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -13408,15 +13425,15 @@ snapshots: safe-regex-test: 1.1.0 set-proto: 1.0.0 stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 + string.prototype.trim: 1.2.11 + string.prototype.trimend: 1.0.10 string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.3 typed-array-byte-length: 1.0.3 typed-array-byte-offset: 1.0.4 typed-array-length: 1.0.8 unbox-primitive: 1.1.0 - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 es-define-property@1.0.1: {} @@ -13561,7 +13578,7 @@ snapshots: object.groupby: 1.0.3 object.values: 1.2.1 semver: 6.3.1 - string.prototype.trimend: 1.0.9 + string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: '@typescript-eslint/parser': 8.59.1(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3) @@ -13847,7 +13864,7 @@ snapshots: faye-websocket@0.11.4: dependencies: - websocket-driver: 0.7.4 + websocket-driver: 0.7.5 fd-slicer@1.1.0: dependencies: @@ -14049,7 +14066,16 @@ snapshots: functions-have-names@1.2.3: {} - gaxios@7.1.4(supports-color@10.2.2): + gaxios@7.1.3(supports-color@10.2.2): + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + node-fetch: 3.3.2 + rimraf: 5.0.10 + transitivePeerDependencies: + - supports-color + + gaxios@7.1.5(supports-color@10.2.2): dependencies: extend: 3.0.2 https-proxy-agent: 7.0.6(supports-color@10.2.2) @@ -14059,7 +14085,15 @@ snapshots: gcp-metadata@8.1.2(supports-color@10.2.2): dependencies: - gaxios: 7.1.4(supports-color@10.2.2) + gaxios: 7.1.5(supports-color@10.2.2) + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + gcp-metadata@8.1.3(supports-color@10.2.2): + dependencies: + gaxios: 7.1.3(supports-color@10.2.2) google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -14164,29 +14198,41 @@ snapshots: define-properties: 1.2.1 gopd: 1.2.0 - google-auth-library@10.6.2(supports-color@10.2.2): + google-auth-library@10.5.0(supports-color@10.2.2): + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.5(supports-color@10.2.2) + gcp-metadata: 8.1.3(supports-color@10.2.2) + google-logging-utils: 1.1.3 + gtoken: 8.0.0(supports-color@10.2.2) + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-auth-library@10.7.0(supports-color@10.2.2): dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.1.4(supports-color@10.2.2) + gaxios: 7.1.5(supports-color@10.2.2) gcp-metadata: 8.1.2(supports-color@10.2.2) google-logging-utils: 1.1.3 jws: 4.0.1 transitivePeerDependencies: - supports-color - google-gax@5.0.6(supports-color@10.2.2): + google-gax@5.0.7(supports-color@10.2.2): dependencies: '@grpc/grpc-js': 1.14.4 '@grpc/proto-loader': 0.8.1 duplexify: 4.1.3 - google-auth-library: 10.6.2(supports-color@10.2.2) + google-auth-library: 10.5.0(supports-color@10.2.2) google-logging-utils: 1.1.3 node-fetch: 3.3.2 object-hash: 3.0.0 proto3-json-serializer: 3.0.4 protobufjs: 7.6.2 - retry-request: 8.0.2(supports-color@10.2.2) + retry-request: 8.0.3(supports-color@10.2.2) rimraf: 5.0.10 transitivePeerDependencies: - supports-color @@ -14224,6 +14270,13 @@ snapshots: '@grpc/grpc-js': 1.14.4 protobufjs: 7.6.2 + gtoken@8.0.0(supports-color@10.2.2): + dependencies: + gaxios: 7.1.5(supports-color@10.2.2) + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + gunzip-maybe@1.4.2: dependencies: browserify-zlib: 0.1.4 @@ -14620,7 +14673,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 is-typedarray@1.0.0: {} @@ -14731,7 +14784,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14760,7 +14813,7 @@ snapshots: '@asamuzakjp/css-color': 5.1.11 '@asamuzakjp/dom-selector': 7.1.1 '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.4(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) '@exodus/bytes': 1.15.1 css-tree: 3.2.1 data-urls: 7.0.0 @@ -14772,7 +14825,7 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.1 - undici: 7.27.0 + undici: 7.27.2 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -14974,7 +15027,7 @@ snapshots: lmdb@3.5.4: dependencies: '@harperfast/extended-iterable': 1.0.3 - msgpackr: 1.11.12 + msgpackr: 1.11.13 node-addon-api: 6.1.0 node-gyp-build-optional-packages: 5.2.2 ordered-binary: 1.6.1 @@ -15123,16 +15176,16 @@ snapshots: media-typer@1.1.0: {} - memfs@4.57.5(tslib@2.8.1): + memfs@4.57.6(tslib@2.8.1): dependencies: - '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.6(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -15273,7 +15326,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 optional: true - msgpackr@1.11.12: + msgpackr@1.11.13: optionalDependencies: msgpackr-extract: 3.0.4 optional: true @@ -15387,7 +15440,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-gyp@12.3.0: + node-gyp@12.4.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 @@ -15502,7 +15555,7 @@ snapshots: obuf@1.1.2: {} - obug@2.1.1: {} + obug@2.1.2: {} on-exit-leak-free@2.1.2: {} @@ -15786,7 +15839,7 @@ snapshots: postcss-loader@8.2.1(postcss@8.5.13)(typescript@6.0.3)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): dependencies: - cosmiconfig: 9.0.1(typescript@6.0.3) + cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 postcss: 8.5.13 semver: 7.7.4 @@ -15877,7 +15930,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.1 - '@types/node': 22.19.19 + '@types/node': 22.19.20 long: 5.3.2 proxy-addr@2.0.7: @@ -15944,7 +15997,7 @@ snapshots: dependencies: '@puppeteer/browsers': 2.13.0 chromium-bidi: 14.0.0(devtools-protocol@0.0.1595872) - cosmiconfig: 9.0.1(typescript@6.0.3) + cosmiconfig: 9.0.2(typescript@6.0.3) devtools-protocol: 0.0.1595872 puppeteer-core: 24.42.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.2 @@ -16151,10 +16204,10 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 - retry-request@8.0.2(supports-color@10.2.2): + retry-request@8.0.3(supports-color@10.2.2): dependencies: extend: 3.0.2 - teeny-request: 10.1.2(supports-color@10.2.2) + teeny-request: 10.1.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -16211,12 +16264,12 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.29.7 - rollup-plugin-sourcemaps2@0.5.6(@types/node@22.19.19)(rollup@4.60.2): + rollup-plugin-sourcemaps2@0.5.6(@types/node@22.19.20)(rollup@4.60.2): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.60.2) rollup: 4.60.2 optionalDependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 rollup@4.60.2: dependencies: @@ -16551,7 +16604,7 @@ snapshots: dependencies: faye-websocket: 0.11.4 uuid: 8.3.2 - websocket-driver: 0.7.4 + websocket-driver: 0.7.5 socks-proxy-agent@8.0.5: dependencies: @@ -16705,7 +16758,7 @@ snapshots: transitivePeerDependencies: - supports-color - streamx@2.26.0: + streamx@2.27.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -16739,7 +16792,7 @@ snapshots: get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 - string.prototype.trim@1.2.10: + string.prototype.trim@1.2.11: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 @@ -16748,8 +16801,9 @@ snapshots: es-abstract: 1.24.2 es-object-atoms: 1.1.2 has-property-descriptors: 1.0.2 + safe-regex-test: 1.1.0 - string.prototype.trimend@1.0.9: + string.prototype.trimend@1.0.10: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 @@ -16816,7 +16870,7 @@ snapshots: dependencies: b4a: 1.8.1 fast-fifo: 1.3.2 - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -16826,7 +16880,7 @@ snapshots: b4a: 1.8.1 bare-fs: 4.7.2 fast-fifo: 1.3.2 - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -16840,7 +16894,7 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - teeny-request@10.1.2(supports-color@10.2.2): + teeny-request@10.1.3(supports-color@10.2.2): dependencies: http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) @@ -16851,7 +16905,7 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -17083,7 +17137,7 @@ snapshots: undici@6.26.0: {} - undici@7.27.0: {} + undici@7.27.2: {} undici@8.2.0: {} @@ -17259,7 +17313,7 @@ snapshots: es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.2 pathe: 2.0.3 picomatch: 4.0.4 std-env: 4.1.0 @@ -17318,7 +17372,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): dependencies: colorette: 2.0.20 - memfs: 4.57.5(tslib@2.8.1) + memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17331,7 +17385,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2(esbuild@0.28.0)): dependencies: colorette: 2.0.20 - memfs: 4.57.5(tslib@2.8.1) + memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17343,7 +17397,7 @@ snapshots: webpack-dev-middleware@8.0.3(tslib@2.8.1)(webpack@5.106.2(esbuild@0.28.0)(postcss@8.5.13)): dependencies: - memfs: 4.57.5(tslib@2.8.1) + memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17456,7 +17510,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.1 + enhanced-resolve: 5.23.0 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17496,7 +17550,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.1 + enhanced-resolve: 5.23.0 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17524,7 +17578,7 @@ snapshots: - postcss - uglify-js - websocket-driver@0.7.4: + websocket-driver@0.7.5: dependencies: http-parser-js: 0.5.10 safe-buffer: 5.2.1 @@ -17569,7 +17623,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 which-collection@1.0.2: dependencies: @@ -17578,7 +17632,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.21: + which-typed-array@1.1.22: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 From da81e55123b9d302b0f06166a716d3139147e735 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 9 Jun 2026 14:48:24 +0000 Subject: [PATCH 19/23] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 2 +- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index b10a76173410..8b1f6eb797d6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -26,7 +26,7 @@ git_override( bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "e78f06f32bc0780cfda374af155a1b5dc84fa14d", + commit = "cef5e36af124e7442d7e2868be3f8c0bba496952", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/package.json b/package.json index 0430bc3fcf35..db8f7b5285e8 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.0.0", "@angular/localize": "22.0.0", "@angular/material": "22.0.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#68eef04ac1e37b69e3e61d3e32802e0a6046d54c", "@angular/platform-browser": "22.0.0", "@angular/platform-server": "22.0.0", "@angular/router": "22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed16bfd9a69c..a16b16320684 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.0.0 version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#68eef04ac1e37b69e3e61d3e32802e0a6046d54c + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2)) '@angular/platform-browser': specifier: 22.0.0 version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -1011,9 +1011,9 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c': - resolution: {gitHosted: true, integrity: sha512-DolaJQq/Bl29sdXrd8YUw+a/T0Xf2hzug0mbuWk4poeLAQ7GQpx1C+fw1TyRvu89HONzhLDYj8RMGkESZlYxwQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c} - version: 0.0.0-e78f06f32bc0780cfda374af155a1b5dc84fa14d + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c': + resolution: {gitHosted: true, integrity: sha512-T6Drp02fXuaD+9yiRcv4bXTKsMROEIuCATiKQSgcILd02lT9FoyqBzNHdNHzHEYNtOZeLhMn+hkhooTTAlcpPw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c} + version: 0.0.0-cef5e36af124e7442d7e2868be3f8c0bba496952 hasBin: true '@angular/platform-browser@22.0.0': @@ -8855,7 +8855,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.2))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) From 3275b45559bb5c0a82b3f408bb1e6ec034382dab Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 10 Jun 2026 07:30:32 -0400 Subject: [PATCH 20/23] test(@angular/cli): remove unscoped authentication test cases from registry tests Modern package managers do not support unscoped authentication, and Yarn Classic's metadata command (yarn info) does not propagate unscoped credentials correctly, leading to 403 Forbidden failures on secure registries during ng update and ng add. This commit removes the unscoped authentication test cases from both add and update secure registry E2E tests, and cleans up the createNpmConfigForAuthentication helper to default to scoped authentication. (cherry picked from commit ecda7061f6af9abf9e1793493dc521c79c28404a) --- .../e2e/tests/commands/add/secure-registry.ts | 26 +++---------------- .../tests/update/update-secure-registry.ts | 18 +------------ tests/e2e/utils/registry.ts | 2 +- 3 files changed, 5 insertions(+), 41 deletions(-) diff --git a/tests/e2e/tests/commands/add/secure-registry.ts b/tests/e2e/tests/commands/add/secure-registry.ts index 4a640607f8be..e585444b02e4 100644 --- a/tests/e2e/tests/commands/add/secure-registry.ts +++ b/tests/e2e/tests/commands/add/secure-registry.ts @@ -1,5 +1,5 @@ -import { expectFileNotToExist, expectFileToExist, rimraf } from '../../../utils/fs'; -import { getActivePackageManager, installWorkspacePackages } from '../../../utils/packages'; +import { expectFileNotToExist, expectFileToExist } from '../../../utils/fs'; +import { installWorkspacePackages } from '../../../utils/packages'; import { git, ng } from '../../../utils/process'; import { createNpmConfigForAuthentication } from '../../../utils/registry'; import { expectToFail } from '../../../utils/utils'; @@ -9,37 +9,17 @@ export default async function () { try { // The environment variable has priority over the .npmrc delete process.env['NPM_CONFIG_REGISTRY']; - const packageManager = getActivePackageManager(); - const supportsUnscopedAuth = packageManager === 'yarn'; const command = ['add', '@angular/pwa', '--skip-confirmation']; - // Works with unscoped registry authentication details - if (supportsUnscopedAuth) { - // Some package managers such as Bun and NPM do not support unscoped auth. - await createNpmConfigForAuthentication(false); - - await expectFileNotToExist('public/manifest.webmanifest'); - - await ng(...command); - await expectFileToExist('public/manifest.webmanifest'); - await git('clean', '-dxf'); - } - // Works with scoped registry authentication details await expectFileNotToExist('public/manifest.webmanifest'); - await createNpmConfigForAuthentication(true); + await createNpmConfigForAuthentication(); await ng(...command); await expectFileToExist('public/manifest.webmanifest'); await git('clean', '-dxf'); // Invalid authentication token - if (supportsUnscopedAuth) { - // Some package managers such as Bun and NPM do not support unscoped auth. - await createNpmConfigForAuthentication(false, true); - await expectToFail(() => ng(...command)); - } - await createNpmConfigForAuthentication(true, true); await expectToFail(() => ng(...command)); } finally { diff --git a/tests/e2e/tests/update/update-secure-registry.ts b/tests/e2e/tests/update/update-secure-registry.ts index b52d311a622f..3c0a9d468e44 100644 --- a/tests/e2e/tests/update/update-secure-registry.ts +++ b/tests/e2e/tests/update/update-secure-registry.ts @@ -6,9 +6,6 @@ import { getActivePackageManager } from '../../utils/packages'; import assert from 'node:assert'; export default async function () { - const packageManager = getActivePackageManager(); - const supportsUnscopedAuth = packageManager === 'yarn'; - // The environment variable has priority over the .npmrc delete process.env['NPM_CONFIG_REGISTRY']; const worksMessage = 'We analyzed your package.json'; @@ -20,15 +17,7 @@ export default async function () { // Valid authentication token - if (supportsUnscopedAuth) { - await createNpmConfigForAuthentication(false); - const { stdout: stdout1 } = await ng('update', ...extraArgs); - if (!stdout1.includes(worksMessage)) { - throw new Error(`Expected stdout to contain "${worksMessage}"`); - } - } - - await createNpmConfigForAuthentication(true); + await createNpmConfigForAuthentication(); const { stdout: stdout2 } = await ng('update', ...extraArgs); if (!stdout2.includes(worksMessage)) { throw new Error(`Expected stdout to contain "${worksMessage}"`); @@ -36,11 +25,6 @@ export default async function () { // Invalid authentication token - if (supportsUnscopedAuth) { - await createNpmConfigForAuthentication(false, true); - await expectToFail(() => ng('update', ...extraArgs)); - } - await createNpmConfigForAuthentication(true, true); await expectToFail(() => ng('update', ...extraArgs)); diff --git a/tests/e2e/utils/registry.ts b/tests/e2e/utils/registry.ts index fd557c116120..d8d75b566fb9 100644 --- a/tests/e2e/utils/registry.ts +++ b/tests/e2e/utils/registry.ts @@ -63,7 +63,7 @@ export async function createNpmConfigForAuthentication( * _auth="dGVzdGluZzpzM2NyZXQ="` * ``` */ - scopedAuthentication: boolean, + scopedAuthentication = true, /** When true, an incorrect token is used. Use this to validate authentication failures. */ invalidToken = false, ): Promise { From b048b5f4a83d7b20095d79654b849808e7d58fdb Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 9 Jun 2026 15:13:56 -0400 Subject: [PATCH 21/23] fix(@angular/cli): remove forceAuth and unscoped credential parsing Remove the non-standard forceAuth option and custom parsing for unscoped registry credentials (token, username, password, auth) in package-metadata.ts. Since the npm CLI does not support unscoped credentials and ignores them by default, this aligning removes the unnecessary parsing complexity. Unscoped credentials will now behave identically to any other standard configuration property, falling through to default configuration parsing. (cherry picked from commit f8c3df4e29d834014e955a6762651458e139f231) --- .../cli/src/utilities/package-metadata.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/packages/angular/cli/src/utilities/package-metadata.ts b/packages/angular/cli/src/utilities/package-metadata.ts index fd31000f989a..05a739e898ae 100644 --- a/packages/angular/cli/src/utilities/package-metadata.ts +++ b/packages/angular/cli/src/utilities/package-metadata.ts @@ -52,9 +52,7 @@ export interface PackageManifest extends Manifest, NgPackageManifestProperties { peerDependenciesMeta?: Record; } -interface PackageManagerOptions extends Record { - forceAuth?: Record; -} +type PackageManagerOptions = Record; let npmrc: PackageManagerOptions; const npmPackageJsonCache = new Map>>(); @@ -175,19 +173,6 @@ function normalizeOptions( } switch (key) { - // Unless auth options are scope with the registry url it appears that npm-registry-fetch ignores them, - // even though they are documented. - // https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/README.md - // https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/auth.js#L45-L91 - case '_authToken': - case 'token': - case 'username': - case 'password': - case '_auth': - case 'auth': - options['forceAuth'] ??= {}; - options['forceAuth'][key] = substitutedValue; - break; case 'noproxy': case 'no-proxy': options['noProxy'] = substitutedValue; From b54e9a549d30871f6017b1db4cf7a4ab5f3e02db Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:56:39 +0000 Subject: [PATCH 22/23] fix(@angular/cli): do not sort migrations of the same version alphabetically When executing update migrations, schematics targeting the same version were previously sorted alphabetically by name. This change removes the alphabetical sorting fallback, allowing migrations targeting the same version to preserve their original declaration/discovery order. --- .../src/commands/update/utilities/migration.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/angular/cli/src/commands/update/utilities/migration.ts b/packages/angular/cli/src/commands/update/utilities/migration.ts index f52726de5523..21331364bc2f 100644 --- a/packages/angular/cli/src/commands/update/utilities/migration.ts +++ b/packages/angular/cli/src/commands/update/utilities/migration.ts @@ -153,9 +153,7 @@ export async function executeMigrations( if (requiredMigrations.length) { logger.info(colors.cyan(`** Executing migrations of package '${packageName}' **\n`)); - requiredMigrations.sort( - (a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name), - ); + requiredMigrations.sort(compareMigrations); const result = await executePackageMigrations( workflow, @@ -174,9 +172,7 @@ export async function executeMigrations( if (optionalMigrations.length) { logger.info(colors.magenta(`** Optional migrations of package '${packageName}' **\n`)); - optionalMigrations.sort( - (a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name), - ); + optionalMigrations.sort(compareMigrations); const migrationsToRun = await getOptionalMigrationsToRun( logger, @@ -372,3 +368,10 @@ function getMigrationTitleAndDescription(migration: MigrationSchematicDescriptio : undefined, }; } + +function compareMigrations( + a: MigrationSchematicDescriptionWithVersion, + b: MigrationSchematicDescriptionWithVersion, +): number { + return semver.compare(a.version, b.version); +} From 5a64af99185d3c95766f2d01f3c92b4d804224c1 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 10 Jun 2026 15:34:51 -0700 Subject: [PATCH 23/23] release: cut the v22.0.1 release --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6682a19d581f..83b5ee0ff761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ + + +# 22.0.1 (2026-06-10) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------- | +| [b54e9a549](https://github.com/angular/angular-cli/commit/b54e9a549d30871f6017b1db4cf7a4ab5f3e02db) | fix | do not sort migrations of the same version alphabetically | +| [d33311612](https://github.com/angular/angular-cli/commit/d333116123c7d3d5e87713b7baac048b78f28517) | fix | fallback to local package.json for schematic detection on first run | +| [918102a93](https://github.com/angular/angular-cli/commit/918102a9373085394c41f10d9f5df3e3c17b263f) | fix | isolate temporary package installation from parent pnpm workspace | +| [b048b5f4a](https://github.com/angular/angular-cli/commit/b048b5f4a83d7b20095d79654b849808e7d58fdb) | fix | remove forceAuth and unscoped credential parsing | +| [277934035](https://github.com/angular/angular-cli/commit/277934035138c5af803e8daeebc2313f0a4cb5b3) | fix | validate registry option is a valid URL in ng add | +| [4510dae02](https://github.com/angular/angular-cli/commit/4510dae021ab25bb852eeed6415dbd52cfabfce5) | perf | optimize update schematic registry query counts by fetching package metadata lazily | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | +| [c80012294](https://github.com/angular/angular-cli/commit/c8001229453211b37cd7bb12ed26a2deb9257fd5) | fix | fix browserMode option mapping in refactor-jasmine-vitest | +| [a9b6bd904](https://github.com/angular/angular-cli/commit/a9b6bd9042d6b859c384a6fc782541fca30dfb68) | fix | safely comment out multiline statements in refactor-jasmine-vitest | +| [12199df00](https://github.com/angular/angular-cli/commit/12199df00f2e3e8436ada13e04799e5825eb3f7b) | fix | use null objects and callbacks in karma-to-vitest migration | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | +| [89d1be979](https://github.com/angular/angular-cli/commit/89d1be979f388d85e9c428bbf1df4e7fb4036dce) | fix | allow disabling Vitest isolation from builder | +| [d45b84be9](https://github.com/angular/angular-cli/commit/d45b84be9a607e49b391cb216cb6de7eca274931) | fix | exclude JSON imports from Vite dependency optimization | +| [e3cab4ddd](https://github.com/angular/angular-cli/commit/e3cab4dddade2538125e8a2f345f42c95e26aeae) | fix | prevent concurrent stylesheet bundling esbuild context leaks | +| [bd413b0eb](https://github.com/angular/angular-cli/commit/bd413b0eb156184ea432cbb7d4e6d7f6f70813ab) | fix | restrict application builder output paths to output directory | + + + # 22.0.0 (2026-06-03) diff --git a/package.json b/package.json index db8f7b5285e8..f58f3a9452e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.0.0", + "version": "22.0.1", "private": true, "description": "Software Development Kit for Angular", "keywords": [