diff --git a/examples/angular/src/app/app.config.ts b/examples/angular/src/app/app.config.ts index 9328f728..2a1861fc 100644 --- a/examples/angular/src/app/app.config.ts +++ b/examples/angular/src/app/app.config.ts @@ -26,7 +26,12 @@ import { provideFirebaseUI, provideFirebaseUIPolicies } from "@firebase-ui/angul import { initializeUI } from "@firebase-ui/core"; const firebaseConfig = { - // your Firebase config here + apiKey: "AIzaSyCvMftIUCD9lUQ3BzIrimfSfBbCUQYZf-I", + authDomain: "fir-ui-rework.firebaseapp.com", + projectId: "fir-ui-rework", + storageBucket: "fir-ui-rework.firebasestorage.app", + messagingSenderId: "200312857118", + appId: "1:200312857118:web:94e3f69b0e0a4a863f040f" }; export const appConfig: ApplicationConfig = { diff --git a/examples/angular/src/app/app.routes.server.ts b/examples/angular/src/app/app.routes.server.ts index ac75b1cd..799c88f9 100644 --- a/examples/angular/src/app/app.routes.server.ts +++ b/examples/angular/src/app/app.routes.server.ts @@ -22,39 +22,48 @@ export const serverRoutes: ServerRoute[] = [ path: "", renderMode: RenderMode.Prerender, }, - /** Key auth screen demos - good for SSG as they showcase Firebase UI components */ + /** Static auth demos - good for SSG as they showcase Firebase UI components */ { - path: "screens/sign-in-auth-screen", + path: "sign-in", renderMode: RenderMode.Prerender, }, { - path: "screens/oauth-screen", + path: "oauth", renderMode: RenderMode.Prerender, }, + /** Interactive auth routes - better as CSR for user interaction */ { - path: "screens/sign-up-auth-screen", - renderMode: RenderMode.Prerender, + path: "sign-up", + renderMode: RenderMode.Client, }, { - path: "screens/email-link-auth-screen", - renderMode: RenderMode.Prerender, + path: "forgot-password", + renderMode: RenderMode.Client, }, + /** Dynamic auth routes - good for SSR as they may need server-side data */ { - path: "screens/phone-auth-screen", - renderMode: RenderMode.Prerender, + path: "email-link", + renderMode: RenderMode.Server, }, - /** Interactive auth routes - better as CSR for user interaction */ { - path: "sign-in", - renderMode: RenderMode.Client, + path: "email-link-oauth", + renderMode: RenderMode.Server, }, { - path: "register", - renderMode: RenderMode.Client, + path: "phone", + renderMode: RenderMode.Server, }, { - path: "forgot-password", - renderMode: RenderMode.Client, + path: "phone-oauth", + renderMode: RenderMode.Server, + }, + { + path: "sign-in-oauth", + renderMode: RenderMode.Server, + }, + { + path: "sign-up-oauth", + renderMode: RenderMode.Server, }, /** All other routes will be rendered on the server (SSR) */ { diff --git a/examples/angular/src/app/app.routes.ts b/examples/angular/src/app/app.routes.ts index b5c78d86..37ef399c 100644 --- a/examples/angular/src/app/app.routes.ts +++ b/examples/angular/src/app/app.routes.ts @@ -21,72 +21,45 @@ export const routes: Routes = [ path: "", loadComponent: () => import("./home").then((m) => m.HomeComponent), }, - // Direct auth routes (matching NextJS paths) { - path: "sign-in", - loadComponent: () => import("./auth/sign-in").then((m) => m.SignInComponent), + path: "email-link", + loadComponent: () => import("./auth/email-link").then((m) => m.EmailLinkComponent), }, { - path: "register", - loadComponent: () => import("./auth/register").then((m) => m.RegisterComponent), + path: "email-link-oauth", + loadComponent: () => import("./auth/email-link-oauth").then((m) => m.EmailLinkOAuthComponent), }, { path: "forgot-password", loadComponent: () => import("./auth/forgot-password").then((m) => m.ForgotPasswordComponent), }, - // Sign-in subdirectories { - path: "sign-in/phone", - loadComponent: () => import("./auth/phone").then((m) => m.PhoneComponent), + path: "oauth", + loadComponent: () => import("./auth/oauth").then((m) => m.OAuthComponent), }, { - path: "sign-in/email", - loadComponent: () => import("./auth/email-link").then((m) => m.EmailLinkComponent), + path: "phone", + loadComponent: () => import("./auth/phone").then((m) => m.PhoneComponent), }, - // Screen routes { - path: "screens/sign-in-auth-screen", - loadComponent: () => import("./auth/sign-in-screen").then((m) => m.SignInScreenComponent), + path: "phone-oauth", + loadComponent: () => import("./auth/phone-oauth").then((m) => m.PhoneOAuthComponent), }, { - path: "screens/sign-in-auth-screen-w-handlers", - loadComponent: () => import("./auth/sign-in-handlers").then((m) => m.SignInHandlersComponent), + path: "sign-in", + loadComponent: () => import("./auth/sign-in").then((m) => m.SignInComponent), }, { - path: "screens/sign-in-auth-screen-w-oauth", + path: "sign-in-oauth", loadComponent: () => import("./auth/sign-in-oauth").then((m) => m.SignInOAuthComponent), }, { - path: "screens/email-link-auth-screen", - loadComponent: () => import("./auth/email-link-screen").then((m) => m.EmailLinkScreenComponent), - }, - { - path: "screens/email-link-auth-screen-w-oauth", - loadComponent: () => import("./auth/email-link-oauth").then((m) => m.EmailLinkOAuthComponent), - }, - { - path: "screens/phone-auth-screen", - loadComponent: () => import("./auth/phone-screen").then((m) => m.PhoneScreenComponent), - }, - { - path: "screens/phone-auth-screen-w-oauth", - loadComponent: () => import("./auth/phone-oauth").then((m) => m.PhoneOAuthComponent), - }, - { - path: "screens/sign-up-auth-screen", + path: "sign-up", loadComponent: () => import("./auth/sign-up").then((m) => m.SignUpComponent), }, { - path: "screens/sign-up-auth-screen-w-oauth", - loadComponent: () => import("./auth/register-oauth").then((m) => m.RegisterOAuthComponent), - }, - { - path: "screens/oauth-screen", - loadComponent: () => import("./auth/oauth").then((m) => m.OAuthComponent), - }, - { - path: "screens/password-reset-screen", - loadComponent: () => import("./auth/password-reset").then((m) => m.PasswordResetComponent), + path: "sign-up-oauth", + loadComponent: () => import("./auth/sign-up-oauth").then((m) => m.SignUpOAuthComponent), }, { path: "**", diff --git a/examples/angular/src/app/auth/email-link-screen/email-link-screen.component.ts b/examples/angular/src/app/auth/email-link-screen/email-link-screen.component.ts deleted file mode 100644 index e9c39aec..00000000 --- a/examples/angular/src/app/auth/email-link-screen/email-link-screen.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, OnInit, inject } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { Router, RouterModule } from "@angular/router"; -import { Auth, User, authState } from "@angular/fire/auth"; -import { EmailLinkAuthScreenComponent } from "@firebase-ui/angular"; - -@Component({ - selector: "app-email-link-screen", - standalone: true, - imports: [CommonModule, RouterModule, EmailLinkAuthScreenComponent], - template: ` `, - styles: [], -}) -export class EmailLinkScreenComponent implements OnInit { - private auth = inject(Auth); - private router = inject(Router); - - ngOnInit() { - // Check if user is already authenticated and redirect to home page - authState(this.auth).subscribe((user: User | null) => { - if (user) { - this.router.navigate(["/"]); - } - }); - } -} diff --git a/examples/angular/src/app/auth/email-link/email-link.component.ts b/examples/angular/src/app/auth/email-link/email-link.component.ts index 7d7716ef..89bbf188 100644 --- a/examples/angular/src/app/auth/email-link/email-link.component.ts +++ b/examples/angular/src/app/auth/email-link/email-link.component.ts @@ -24,7 +24,7 @@ import { EmailLinkAuthScreenComponent } from "@firebase-ui/angular"; selector: "app-email-link", standalone: true, imports: [CommonModule, RouterModule, EmailLinkAuthScreenComponent], - template: ` `, + template: ` `, styles: [], }) export class EmailLinkComponent implements OnInit { diff --git a/examples/angular/src/app/auth/forgot-password/forgot-password.component.ts b/examples/angular/src/app/auth/forgot-password/forgot-password.component.ts index 7f582aa3..683161fd 100644 --- a/examples/angular/src/app/auth/forgot-password/forgot-password.component.ts +++ b/examples/angular/src/app/auth/forgot-password/forgot-password.component.ts @@ -18,13 +18,13 @@ import { Component, OnInit, inject } from "@angular/core"; import { CommonModule } from "@angular/common"; import { Router, RouterModule } from "@angular/router"; import { Auth, User, authState } from "@angular/fire/auth"; -import { PasswordResetScreenComponent } from "@firebase-ui/angular"; +import { ForgotPasswordAuthScreenComponent } from "@firebase-ui/angular"; @Component({ selector: "app-forgot-password", standalone: true, - imports: [CommonModule, RouterModule, PasswordResetScreenComponent], - template: ` `, + imports: [CommonModule, RouterModule, ForgotPasswordAuthScreenComponent], + template: ` `, styles: [], }) export class ForgotPasswordComponent implements OnInit { @@ -39,4 +39,8 @@ export class ForgotPasswordComponent implements OnInit { } }); } + + backToSignIn() { + this.router.navigate(["/sign-in"]); + } } diff --git a/examples/angular/src/app/auth/password-reset/password-reset.component.ts b/examples/angular/src/app/auth/password-reset/password-reset.component.ts deleted file mode 100644 index fc4735de..00000000 --- a/examples/angular/src/app/auth/password-reset/password-reset.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, OnInit, inject } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { Router, RouterModule } from "@angular/router"; -import { Auth, User, authState } from "@angular/fire/auth"; -import { PasswordResetScreenComponent } from "@firebase-ui/angular"; - -@Component({ - selector: "app-password-reset", - standalone: true, - imports: [CommonModule, RouterModule, PasswordResetScreenComponent], - template: ` `, - styles: [], -}) -export class PasswordResetComponent implements OnInit { - private auth = inject(Auth); - private router = inject(Router); - - ngOnInit() { - // Check if user is already authenticated and redirect to home page - authState(this.auth).subscribe((user: User | null) => { - if (user) { - this.router.navigate(["/"]); - } - }); - } -} diff --git a/examples/angular/src/app/auth/phone-oauth/phone-oauth.component.ts b/examples/angular/src/app/auth/phone-oauth/phone-oauth.component.ts index 113e8e83..31369616 100644 --- a/examples/angular/src/app/auth/phone-oauth/phone-oauth.component.ts +++ b/examples/angular/src/app/auth/phone-oauth/phone-oauth.component.ts @@ -26,7 +26,7 @@ import { PhoneAuthScreenComponent, GoogleSignInButtonComponent } from "@firebase imports: [CommonModule, RouterModule, PhoneAuthScreenComponent, GoogleSignInButtonComponent], template: ` - + `, styles: [], diff --git a/examples/angular/src/app/auth/phone/index.ts b/examples/angular/src/app/auth/phone/index.ts index 43793a94..da351973 100644 --- a/examples/angular/src/app/auth/phone/index.ts +++ b/examples/angular/src/app/auth/phone/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export * from "./phone.component"; +export * from "./phone-screen.component"; diff --git a/examples/angular/src/app/auth/phone-screen/phone-screen.component.ts b/examples/angular/src/app/auth/phone/phone-screen.component.ts similarity index 92% rename from examples/angular/src/app/auth/phone-screen/phone-screen.component.ts rename to examples/angular/src/app/auth/phone/phone-screen.component.ts index 27e8e517..b0cdc310 100644 --- a/examples/angular/src/app/auth/phone-screen/phone-screen.component.ts +++ b/examples/angular/src/app/auth/phone/phone-screen.component.ts @@ -21,13 +21,13 @@ import { Auth, User, authState } from "@angular/fire/auth"; import { PhoneAuthScreenComponent } from "@firebase-ui/angular"; @Component({ - selector: "app-phone-screen", + selector: "app-phone", standalone: true, imports: [CommonModule, RouterModule, PhoneAuthScreenComponent], - template: ` `, + template: ` `, styles: [], }) -export class PhoneScreenComponent implements OnInit { +export class PhoneComponent implements OnInit { private auth = inject(Auth); private router = inject(Router); diff --git a/examples/angular/src/app/auth/phone/phone.component.ts b/examples/angular/src/app/auth/phone/phone.component.ts deleted file mode 100644 index 86d505fa..00000000 --- a/examples/angular/src/app/auth/phone/phone.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, OnInit, inject } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { Router, RouterModule } from "@angular/router"; -import { Auth, User, authState } from "@angular/fire/auth"; -import { PhoneAuthScreenComponent } from "@firebase-ui/angular"; - -@Component({ - selector: "app-phone", - standalone: true, - imports: [CommonModule, RouterModule, PhoneAuthScreenComponent], - template: ` `, - styles: [], -}) -export class PhoneComponent implements OnInit { - private auth = inject(Auth); - private router = inject(Router); - - ngOnInit() { - // Check if user is already authenticated and redirect to home page - authState(this.auth).subscribe((user: User | null) => { - if (user) { - this.router.navigate(["/"]); - } - }); - } -} diff --git a/examples/angular/src/app/auth/register/index.ts b/examples/angular/src/app/auth/register/index.ts index 1197c752..766d67c3 100644 --- a/examples/angular/src/app/auth/register/index.ts +++ b/examples/angular/src/app/auth/register/index.ts @@ -1,17 +1 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - export * from "./register.component"; diff --git a/examples/angular/src/app/auth/register/register.component.ts b/examples/angular/src/app/auth/register/register.component.ts index 09d866b3..a5198b45 100644 --- a/examples/angular/src/app/auth/register/register.component.ts +++ b/examples/angular/src/app/auth/register/register.component.ts @@ -18,17 +18,13 @@ import { Component, OnInit, inject } from "@angular/core"; import { CommonModule } from "@angular/common"; import { Router, RouterModule } from "@angular/router"; import { Auth, User, authState } from "@angular/fire/auth"; -import { SignUpAuthScreenComponent, GoogleSignInButtonComponent } from "@firebase-ui/angular"; +import { SignUpAuthScreenComponent } from "@firebase-ui/angular"; @Component({ selector: "app-register", standalone: true, - imports: [CommonModule, RouterModule, SignUpAuthScreenComponent, GoogleSignInButtonComponent], - template: ` - - - - `, + imports: [CommonModule, RouterModule, SignUpAuthScreenComponent], + template: ` `, styles: [], }) export class RegisterComponent implements OnInit { @@ -43,4 +39,8 @@ export class RegisterComponent implements OnInit { } }); } + + goToSignIn() { + this.router.navigate(["/sign-in"]); + } } diff --git a/examples/angular/src/app/auth/sign-in-handlers/index.ts b/examples/angular/src/app/auth/sign-in-handlers/index.ts deleted file mode 100644 index e6d50480..00000000 --- a/examples/angular/src/app/auth/sign-in-handlers/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from "./sign-in-handlers.component"; diff --git a/examples/angular/src/app/auth/sign-in-handlers/sign-in-handlers.component.ts b/examples/angular/src/app/auth/sign-in-handlers/sign-in-handlers.component.ts deleted file mode 100644 index 0bc60628..00000000 --- a/examples/angular/src/app/auth/sign-in-handlers/sign-in-handlers.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, OnInit, inject } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { Router, RouterModule } from "@angular/router"; -import { Auth, User, authState } from "@angular/fire/auth"; -import { SignInAuthScreenComponent } from "@firebase-ui/angular"; - -@Component({ - selector: "app-sign-in-handlers", - standalone: true, - imports: [CommonModule, RouterModule, SignInAuthScreenComponent], - template: ` - - `, - styles: [], -}) -export class SignInHandlersComponent implements OnInit { - private auth = inject(Auth); - private router = inject(Router); - - ngOnInit() { - // Check if user is already authenticated and redirect to home page - authState(this.auth).subscribe((user: User | null) => { - if (user) { - this.router.navigate(["/"]); - } - }); - } -} diff --git a/examples/angular/src/app/auth/sign-in-oauth/sign-in-oauth.component.ts b/examples/angular/src/app/auth/sign-in-oauth/sign-in-oauth.component.ts index b7eb9163..6b7611cc 100644 --- a/examples/angular/src/app/auth/sign-in-oauth/sign-in-oauth.component.ts +++ b/examples/angular/src/app/auth/sign-in-oauth/sign-in-oauth.component.ts @@ -25,7 +25,7 @@ import { SignInAuthScreenComponent, GoogleSignInButtonComponent } from "@firebas standalone: true, imports: [CommonModule, RouterModule, SignInAuthScreenComponent, GoogleSignInButtonComponent], template: ` - + `, @@ -43,4 +43,12 @@ export class SignInOAuthComponent implements OnInit { } }); } + + goToForgotPassword() { + this.router.navigate(["/forgot-password"]); + } + + goToRegister() { + this.router.navigate(["/sign-up"]); + } } diff --git a/examples/angular/src/app/auth/sign-in-screen/index.ts b/examples/angular/src/app/auth/sign-in-screen/index.ts deleted file mode 100644 index 9fe9f801..00000000 --- a/examples/angular/src/app/auth/sign-in-screen/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from "./sign-in-screen.component"; diff --git a/examples/angular/src/app/auth/sign-in-screen/sign-in-screen.component.ts b/examples/angular/src/app/auth/sign-in-screen/sign-in-screen.component.ts deleted file mode 100644 index b71acd1d..00000000 --- a/examples/angular/src/app/auth/sign-in-screen/sign-in-screen.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, OnInit, inject } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { Router, RouterModule } from "@angular/router"; -import { Auth, User, authState } from "@angular/fire/auth"; -import { SignInAuthScreenComponent } from "@firebase-ui/angular"; - -@Component({ - selector: "app-sign-in-screen", - standalone: true, - imports: [CommonModule, RouterModule, SignInAuthScreenComponent], - template: ` `, - styles: [], -}) -export class SignInScreenComponent implements OnInit { - private auth = inject(Auth); - private router = inject(Router); - - ngOnInit() { - // Check if user is already authenticated and redirect to home page - authState(this.auth).subscribe((user: User | null) => { - if (user) { - this.router.navigate(["/"]); - } - }); - } -} diff --git a/examples/angular/src/app/auth/sign-in/sign-in.component.ts b/examples/angular/src/app/auth/sign-in/sign-in.component.ts index ea5ecf14..7f18c085 100644 --- a/examples/angular/src/app/auth/sign-in/sign-in.component.ts +++ b/examples/angular/src/app/auth/sign-in/sign-in.component.ts @@ -25,8 +25,8 @@ import { SignInAuthScreenComponent, GoogleSignInButtonComponent } from "@firebas standalone: true, imports: [CommonModule, RouterModule, SignInAuthScreenComponent, GoogleSignInButtonComponent], template: ` - - + +
Sign in with phone number
@@ -49,4 +49,12 @@ export class SignInComponent implements OnInit { } }); } + + goToForgotPassword() { + this.router.navigate(["/forgot-password"]); + } + + goToSignUp() { + this.router.navigate(["/sign-up"]); + } } diff --git a/examples/angular/src/app/auth/phone-screen/index.ts b/examples/angular/src/app/auth/sign-up-oauth/index.ts similarity index 93% rename from examples/angular/src/app/auth/phone-screen/index.ts rename to examples/angular/src/app/auth/sign-up-oauth/index.ts index da351973..316d32b3 100644 --- a/examples/angular/src/app/auth/phone-screen/index.ts +++ b/examples/angular/src/app/auth/sign-up-oauth/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export * from "./phone-screen.component"; +export * from "./sign-up-oauth.component"; diff --git a/examples/angular/src/app/auth/register-oauth/register-oauth.component.ts b/examples/angular/src/app/auth/sign-up-oauth/sign-up-oauth.component.ts similarity index 94% rename from examples/angular/src/app/auth/register-oauth/register-oauth.component.ts rename to examples/angular/src/app/auth/sign-up-oauth/sign-up-oauth.component.ts index 52560124..fbf86ed3 100644 --- a/examples/angular/src/app/auth/register-oauth/register-oauth.component.ts +++ b/examples/angular/src/app/auth/sign-up-oauth/sign-up-oauth.component.ts @@ -21,7 +21,7 @@ import { Auth, User, authState } from "@angular/fire/auth"; import { SignUpAuthScreenComponent, GoogleSignInButtonComponent } from "@firebase-ui/angular"; @Component({ - selector: "app-register-oauth", + selector: "app-sign-up-oauth", standalone: true, imports: [CommonModule, RouterModule, SignUpAuthScreenComponent, GoogleSignInButtonComponent], template: ` @@ -31,7 +31,7 @@ import { SignUpAuthScreenComponent, GoogleSignInButtonComponent } from "@firebas `, styles: [], }) -export class RegisterOAuthComponent implements OnInit { +export class SignUpOAuthComponent implements OnInit { private auth = inject(Auth); private router = inject(Router); diff --git a/examples/angular/src/app/auth/sign-up/sign-up.component.ts b/examples/angular/src/app/auth/sign-up/sign-up.component.ts index 35037e83..c3fcfc04 100644 --- a/examples/angular/src/app/auth/sign-up/sign-up.component.ts +++ b/examples/angular/src/app/auth/sign-up/sign-up.component.ts @@ -24,7 +24,7 @@ import { SignUpAuthScreenComponent } from "@firebase-ui/angular"; selector: "app-sign-up", standalone: true, imports: [CommonModule, RouterModule, SignUpAuthScreenComponent], - template: ` `, + template: ` `, styles: [], }) export class SignUpComponent implements OnInit { @@ -39,4 +39,8 @@ export class SignUpComponent implements OnInit { } }); } + + goToSignIn() { + this.router.navigate(["/sign-in"]); + } } diff --git a/examples/angular/src/app/home/home.component.ts b/examples/angular/src/app/home/home.component.ts index 5148e35d..a56a4e49 100644 --- a/examples/angular/src/app/home/home.component.ts +++ b/examples/angular/src/app/home/home.component.ts @@ -34,51 +34,39 @@ import { Observable } from "rxjs";

Auth Screens

diff --git a/examples/angular/src/app/screens/email-link-auth-screen/email-link-auth-screen.component.ts b/examples/angular/src/app/screens/email-link-auth-screen/email-link-auth-screen.component.ts new file mode 100644 index 00000000..41e53007 --- /dev/null +++ b/examples/angular/src/app/screens/email-link-auth-screen/email-link-auth-screen.component.ts @@ -0,0 +1,28 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { EmailLinkAuthScreenComponent } from "@firebase-ui/angular"; + +@Component({ + selector: "app-email-link-auth-screen", + standalone: true, + imports: [CommonModule, EmailLinkAuthScreenComponent], + template: ` `, + styles: [], +}) +export class EmailLinkAuthScreenWrapperComponent {} diff --git a/examples/angular/src/app/screens/email-link-auth-screen/index.ts b/examples/angular/src/app/screens/email-link-auth-screen/index.ts new file mode 100644 index 00000000..3d995ddd --- /dev/null +++ b/examples/angular/src/app/screens/email-link-auth-screen/index.ts @@ -0,0 +1 @@ +export * from "./email-link-auth-screen.component"; diff --git a/examples/angular/src/app/screens/oauth-screen/index.ts b/examples/angular/src/app/screens/oauth-screen/index.ts new file mode 100644 index 00000000..6fed7e76 --- /dev/null +++ b/examples/angular/src/app/screens/oauth-screen/index.ts @@ -0,0 +1 @@ +export * from "./oauth-screen.component"; diff --git a/examples/angular/src/app/auth/register-oauth/index.ts b/examples/angular/src/app/screens/oauth-screen/oauth-screen.component.ts similarity index 60% rename from examples/angular/src/app/auth/register-oauth/index.ts rename to examples/angular/src/app/screens/oauth-screen/oauth-screen.component.ts index 9c417266..9e04f94e 100644 --- a/examples/angular/src/app/auth/register-oauth/index.ts +++ b/examples/angular/src/app/screens/oauth-screen/oauth-screen.component.ts @@ -14,4 +14,15 @@ * limitations under the License. */ -export * from "./register-oauth.component"; +import { Component } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { OAuthScreenComponent } from "@firebase-ui/angular"; + +@Component({ + selector: "app-oauth-screen", + standalone: true, + imports: [CommonModule, OAuthScreenComponent], + template: ` `, + styles: [], +}) +export class OAuthScreenWrapperComponent {} diff --git a/examples/angular/src/app/screens/phone-auth-screen/index.ts b/examples/angular/src/app/screens/phone-auth-screen/index.ts new file mode 100644 index 00000000..ae65a8ce --- /dev/null +++ b/examples/angular/src/app/screens/phone-auth-screen/index.ts @@ -0,0 +1 @@ +export * from "./phone-auth-screen.component"; diff --git a/examples/angular/src/app/auth/email-link-screen/index.ts b/examples/angular/src/app/screens/phone-auth-screen/phone-auth-screen.component.ts similarity index 59% rename from examples/angular/src/app/auth/email-link-screen/index.ts rename to examples/angular/src/app/screens/phone-auth-screen/phone-auth-screen.component.ts index 227407f4..953e105e 100644 --- a/examples/angular/src/app/auth/email-link-screen/index.ts +++ b/examples/angular/src/app/screens/phone-auth-screen/phone-auth-screen.component.ts @@ -14,4 +14,15 @@ * limitations under the License. */ -export * from "./email-link-screen.component"; +import { Component } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { PhoneAuthScreenComponent } from "@firebase-ui/angular"; + +@Component({ + selector: "app-phone-auth-screen", + standalone: true, + imports: [CommonModule, PhoneAuthScreenComponent], + template: ` `, + styles: [], +}) +export class PhoneAuthScreenWrapperComponent {} diff --git a/examples/angular/src/app/screens/sign-in-auth-screen/index.ts b/examples/angular/src/app/screens/sign-in-auth-screen/index.ts new file mode 100644 index 00000000..744e4f84 --- /dev/null +++ b/examples/angular/src/app/screens/sign-in-auth-screen/index.ts @@ -0,0 +1 @@ +export * from "./sign-in-auth-screen.component"; diff --git a/examples/angular/src/app/auth/password-reset/index.ts b/examples/angular/src/app/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts similarity index 58% rename from examples/angular/src/app/auth/password-reset/index.ts rename to examples/angular/src/app/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts index 341d2852..beefadb8 100644 --- a/examples/angular/src/app/auth/password-reset/index.ts +++ b/examples/angular/src/app/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts @@ -14,4 +14,15 @@ * limitations under the License. */ -export * from "./password-reset.component"; +import { Component } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { SignInAuthScreenComponent } from "@firebase-ui/angular"; + +@Component({ + selector: "app-sign-in-auth-screen", + standalone: true, + imports: [CommonModule, SignInAuthScreenComponent], + template: ` `, + styles: [], +}) +export class SignInAuthScreenWrapperComponent {} diff --git a/examples/angular/src/app/screens/sign-up-auth-screen/index.ts b/examples/angular/src/app/screens/sign-up-auth-screen/index.ts new file mode 100644 index 00000000..41aa2834 --- /dev/null +++ b/examples/angular/src/app/screens/sign-up-auth-screen/index.ts @@ -0,0 +1 @@ +export * from "./sign-up-auth-screen.component"; diff --git a/examples/angular/src/app/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts b/examples/angular/src/app/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts new file mode 100644 index 00000000..95bfe94c --- /dev/null +++ b/examples/angular/src/app/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts @@ -0,0 +1,28 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { SignUpAuthScreenComponent } from "@firebase-ui/angular"; + +@Component({ + selector: "app-sign-up-auth-screen", + standalone: true, + imports: [CommonModule, SignUpAuthScreenComponent], + template: ` `, + styles: [], +}) +export class SignUpAuthScreenWrapperComponent {} diff --git a/packages/angular/angular.json b/packages/angular/angular.json index 2e2d5785..d06d0a6c 100644 --- a/packages/angular/angular.json +++ b/packages/angular/angular.json @@ -1,7 +1,6 @@ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, - "newProjectRoot": "projects", "projects": { "firebase-ui-angular": { "projectType": "library", @@ -9,6 +8,9 @@ "sourceRoot": "src", "prefix": "lib", "architect": { + "test": { + "builder": "@analogjs/vitest-angular:test" + }, "build": { "builder": "@angular-devkit/build-angular:ng-packagr", "options": { diff --git a/packages/angular/package.json b/packages/angular/package.json index 0e5ec34b..41eeaa7e 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -4,6 +4,7 @@ "files": [ "dist" ], + "type": "module", "main": "./dist/fesm2022/firebase-ui-angular.mjs", "module": "./dist/fesm2022/firebase-ui-angular.mjs", "typings": "./dist/index.d.ts", @@ -28,33 +29,33 @@ "dependencies": { "@firebase-ui/core": "workspace:*", "@firebase-ui/styles": "workspace:*", - "@tanstack/angular-form": "^1.1.0", - "tslib": "^2.8.1", - "nanostores": "catalog:" + "@tanstack/angular-form": "^1.23.1", + "nanostores": "catalog:", + "tslib": "^2.8.1" }, "sideEffects": false, "devDependencies": { - "@angular/core": "catalog:", - "@angular/common": "catalog:", - "@angular/forms": "catalog:", - "@angular/router": "catalog:", - "@angular/fire": "catalog:", + "@analogjs/vitest-angular": "^1.21.1", "@angular-devkit/build-angular": "catalog:", "@angular/cli": "catalog:", + "@angular/common": "catalog:", "@angular/compiler": "catalog:", "@angular/compiler-cli": "catalog:", + "@angular/core": "catalog:", + "@angular/fire": "catalog:", + "@angular/forms": "catalog:", "@angular/platform-browser": "catalog:", "@angular/platform-browser-dynamic": "catalog:", - "firebase": "catalog:", + "@angular/router": "catalog:", + "@testing-library/angular": "^18.0.0", + "@testing-library/jest-dom": "^6.6.0", "@types/node": "catalog:", - "zone.js": "catalog:", + "firebase": "catalog:", + "jsdom": "^25.0.0", "ng-packagr": "^20.0.0", "rxjs": "catalog:", "typescript": "catalog:", - "vitest": "^2.0.0", - "@vitest/ui": "^2.0.0", - "@vitest/coverage-v8": "^2.0.0", - "jsdom": "^25.0.0", - "@testing-library/jest-dom": "^6.6.0" + "vitest": "catalog:", + "zone.js": "catalog:" } } diff --git a/packages/angular/setup-test.ts b/packages/angular/setup-test.ts new file mode 100644 index 00000000..3af99bb6 --- /dev/null +++ b/packages/angular/setup-test.ts @@ -0,0 +1,30 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "@analogjs/vitest-angular/setup-snapshots"; +import "@testing-library/jest-dom/vitest"; + +import "@angular/compiler"; +import { BrowserTestingModule, platformBrowserTesting } from "@angular/platform-browser/testing"; +import { NgModule, provideZonelessChangeDetection } from "@angular/core"; +import { getTestBed } from "@angular/core/testing"; + +@NgModule({ + providers: [provideZonelessChangeDetection()], +}) +export class ZonelessTestModule {} + +getTestBed().initTestEnvironment([BrowserTestingModule, ZonelessTestModule], platformBrowserTesting()); diff --git a/packages/angular/src/lib/auth/forms/email-link-auth-form/email-link-auth-form.component.ts b/packages/angular/src/lib/auth/forms/email-link-auth-form/email-link-auth-form.component.ts new file mode 100644 index 00000000..8078d469 --- /dev/null +++ b/packages/angular/src/lib/auth/forms/email-link-auth-form/email-link-auth-form.component.ts @@ -0,0 +1,127 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, output } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { injectForm, injectStore, TanStackAppField, TanStackField } from "@tanstack/angular-form"; +import { UserCredential } from "@angular/fire/auth"; +import { + FirebaseUIError, + completeEmailLinkSignIn, + sendSignInLinkToEmail, +} from "@firebase-ui/core"; + +import { injectEmailLinkAuthFormSchema, injectTranslation, injectUI } from "../../../provider"; +import { PoliciesComponent } from "../../../components/policies/policies.component"; +import { FormErrorMessageComponent, FormInputComponent, FormSubmitComponent } from "../../../components/form/form.component"; + +@Component({ + selector: "fui-email-link-auth-form", + standalone: true, + imports: [ + CommonModule, + PoliciesComponent, + TanStackField, + TanStackAppField, + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + ], + template: ` + @if (emailSent) { +
+ {{ emailSentMessage() }} +
+ } + + @if (!emailSent) { +
+
+ +
+ +
+ + {{ sendSignInLinkLabel() }} + + +
+ + } + `, +}) +export class EmailLinkAuthFormComponent implements OnInit { + private ui = injectUI(); + private formSchema = injectEmailLinkAuthFormSchema(); + + emailLabel = injectTranslation("labels", "emailAddress"); + sendSignInLinkLabel = injectTranslation("labels", "sendSignInLink"); + emailSentMessage = injectTranslation("messages", "signInLinkSent"); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + + emailSent = output(); + signIn = output(); + + form = injectForm({ + defaultValues: { + email: "", + }, + }); + + state = injectStore(this.form, (state) => state); + + handleSubmit(event: SubmitEvent) { + event.preventDefault(); + event.stopPropagation(); + this.form.handleSubmit(); + } + + async ngOnInit() { + this.completeSignIn(); + + this.form.update({ + validators: { + onBlur: this.formSchema(), + onSubmit: this.formSchema(), + onSubmitAsync: async ({ value }) => { + try { + await sendSignInLinkToEmail(this.ui(), value.email); + this.emailSent?.emit(); + } catch (error) { + if (error instanceof FirebaseUIError) { + return error.message; + } + + return this.unknownErrorLabel(); + } + }, + }, + }); + } + + private async completeSignIn() { + const credential = await completeEmailLinkSignIn(this.ui(), window.location.href); + + if (credential) { + this.signIn?.emit(credential); + } + } +} diff --git a/packages/angular/src/lib/auth/forms/email-link-form/email-link-form.component.ts b/packages/angular/src/lib/auth/forms/email-link-form/email-link-form.component.ts deleted file mode 100644 index 27f65d5c..00000000 --- a/packages/angular/src/lib/auth/forms/email-link-form/email-link-form.component.ts +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, inject, Input, OnInit } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { injectForm, TanStackField } from "@tanstack/angular-form"; -import { FirebaseUI } from "../../../provider"; -import { ButtonComponent } from "../../../components/button/button.component"; -import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; -import { - createEmailLinkFormSchema, - FirebaseUIError, - completeEmailLinkSignIn, - sendSignInLinkToEmail, - FirebaseUIConfiguration, -} from "@firebase-ui/core"; -import { firstValueFrom } from "rxjs"; - -@Component({ - selector: "fui-email-link-form", - standalone: true, - imports: [CommonModule, TanStackField, ButtonComponent, TermsAndPrivacyComponent], - template: ` -
- {{ emailSentMessage | async }} -
-
-
- - - -
- - - -
- - {{ sendSignInLinkLabel | async }} - -
{{ formError }}
-
-
- `, -}) -export class EmailLinkFormComponent implements OnInit { - private ui = inject(FirebaseUI); - - formError: string | null = null; - emailSent = false; - private formSchema: any; - private config: FirebaseUIConfiguration; - - form = injectForm({ - defaultValues: { - email: "", - }, - }); - - async ngOnInit() { - try { - this.config = await firstValueFrom(this.ui.config()); - - this.formSchema = createEmailLinkFormSchema(this.config); - - this.form.update({ - validators: { - onSubmit: this.formSchema, - onBlur: this.formSchema, - }, - }); - - this.completeSignIn(); - } catch (error) { - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - private async completeSignIn() { - try { - await completeEmailLinkSignIn(await firstValueFrom(this.ui.config()), window.location.href); - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - } - } - } - - async handleSubmit(event: SubmitEvent) { - event.preventDefault(); - event.stopPropagation(); - - const email = this.form.state.values.email; - - if (!email) { - return; - } - - await this.sendSignInLink(email); - } - - async sendSignInLink(email: string) { - this.formError = null; - - try { - const validationResult = this.formSchema.safeParse({ - email, - }); - - if (!validationResult.success) { - const validationErrors = validationResult.error.format(); - - if (validationErrors.email?._errors?.length) { - this.formError = validationErrors.email._errors[0]; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - return; - } - - await sendSignInLinkToEmail(await firstValueFrom(this.ui.config()), email); - - this.emailSent = true; - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - get emailLabel() { - return this.ui.translation("labels", "emailAddress"); - } - - get sendSignInLinkLabel() { - return this.ui.translation("labels", "sendSignInLink"); - } - - get emailSentMessage() { - return this.ui.translation("messages", "signInLinkSent"); - } -} diff --git a/packages/angular/src/lib/auth/forms/email-password-form/email-password-form.component.ts b/packages/angular/src/lib/auth/forms/email-password-form/email-password-form.component.ts deleted file mode 100644 index 11b5b3e0..00000000 --- a/packages/angular/src/lib/auth/forms/email-password-form/email-password-form.component.ts +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, inject, Input, OnInit } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { injectForm, TanStackField } from "@tanstack/angular-form"; -import { FirebaseUI } from "../../../provider"; -import { ButtonComponent } from "../../../components/button/button.component"; -import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; -import { createEmailFormSchema, EmailFormSchema, FirebaseUIConfiguration, FirebaseUIError, signInWithEmailAndPassword } from "@firebase-ui/core"; -import { firstValueFrom } from "rxjs"; -import { Router } from "@angular/router"; - -@Component({ - selector: "fui-email-password-form", - standalone: true, - imports: [CommonModule, TanStackField, ButtonComponent, TermsAndPrivacyComponent], - template: ` -
-
- - - -
-
- - - -
- - - -
- - {{ signInLabel | async }} - -
{{ formError }}
-
- -
- -
-
- `, -}) -export class EmailPasswordFormComponent implements OnInit { - private ui = inject(FirebaseUI); - private router = inject(Router); - - @Input({ required: true }) forgotPasswordRoute!: string; - @Input({ required: true }) registerRoute!: string; - - formError: string | null = null; - private formSchema: any; - private config: FirebaseUIConfiguration; - - form = injectForm({ - defaultValues: { - email: "", - password: "", - }, - }); - - async ngOnInit() { - try { - // Get config once - this.config = await firstValueFrom(this.ui.config()); - - // Create schema once - this.formSchema = createEmailFormSchema(this.config); - - // Apply schema to form validators - this.form.update({ - validators: { - onSubmit: this.formSchema, - onBlur: this.formSchema, - }, - }); - } catch (error) { - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - async handleSubmit(event: SubmitEvent) { - event.preventDefault(); - event.stopPropagation(); - - const email = this.form.state.values.email; - const password = this.form.state.values.password; - - if (!email || !password) { - return; - } - - await this.validateAndSignIn(email, password); - } - - async validateAndSignIn(email: string, password: string) { - try { - const validationResult = this.formSchema.safeParse({ - email, - password, - }); - - if (!validationResult.success) { - const validationErrors = validationResult.error.format(); - - if (validationErrors.email?._errors?.length) { - this.formError = validationErrors.email._errors[0]; - return; - } - - if (validationErrors.password?._errors?.length) { - this.formError = validationErrors.password._errors[0]; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - return; - } - - this.formError = null; - await signInWithEmailAndPassword(await firstValueFrom(this.ui.config()), email, password); - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - navigateTo(route: string) { - this.router.navigateByUrl(route); - } - - get emailLabel() { - return this.ui.translation("labels", "emailAddress"); - } - - get passwordLabel() { - return this.ui.translation("labels", "password"); - } - - get forgotPasswordLabel() { - return this.ui.translation("labels", "forgotPassword"); - } - - get signInLabel() { - return this.ui.translation("labels", "signIn"); - } - - get noAccountLabel() { - return this.ui.translation("prompts", "noAccount"); - } - - get registerLabel() { - return this.ui.translation("labels", "register"); - } -} diff --git a/packages/angular/src/lib/auth/forms/forgot-password-form/forgot-password-form.component.spec.ts b/packages/angular/src/lib/auth/forms/forgot-password-auth-form/forgot-password-auth-form.component.spec.ts similarity index 100% rename from packages/angular/src/lib/auth/forms/forgot-password-form/forgot-password-form.component.spec.ts rename to packages/angular/src/lib/auth/forms/forgot-password-auth-form/forgot-password-auth-form.component.spec.ts diff --git a/packages/angular/src/lib/auth/forms/forgot-password-auth-form/forgot-password-auth-form.component.ts b/packages/angular/src/lib/auth/forms/forgot-password-auth-form/forgot-password-auth-form.component.ts new file mode 100644 index 00000000..4cff2fb9 --- /dev/null +++ b/packages/angular/src/lib/auth/forms/forgot-password-auth-form/forgot-password-auth-form.component.ts @@ -0,0 +1,131 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, output, signal } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { injectForm, injectStore, TanStackAppField, TanStackField } from "@tanstack/angular-form"; +import { FirebaseUIError, sendPasswordResetEmail } from "@firebase-ui/core"; + +import { + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, +} from "../../../components/form/form.component"; +import { PoliciesComponent } from "../../../components/policies/policies.component"; +import { injectForgotPasswordAuthFormSchema, injectTranslation, injectUI } from "../../../provider"; + +@Component({ + selector: "fui-forgot-password-auth-form", + standalone: true, + imports: [ + CommonModule, + TanStackField, + TanStackAppField, + PoliciesComponent, + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, + ], + template: ` + @if (emailSent()) { +
+ {{ checkEmailForResetMessage() }} +
+ } + + @if (!emailSent()) { +
+
+ +
+ + + +
+ + {{ resetPasswordLabel() }} + + +
+ + @if (backToSignIn) { + + } + + } + `, +}) +export class ForgotPasswordAuthFormComponent implements OnInit { + private ui = injectUI(); + private formSchema = injectForgotPasswordAuthFormSchema(); + + emailSent = signal(false); + + emailLabel = injectTranslation("labels", "emailAddress"); + resetPasswordLabel = injectTranslation("labels", "resetPassword"); + backToSignInLabel = injectTranslation("labels", "backToSignIn"); + checkEmailForResetMessage = injectTranslation("messages", "checkEmailForReset"); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + + + passwordSent = output(); + backToSignIn = output(); + + form = injectForm({ + defaultValues: { + email: "", + }, + }); + + state = injectStore(this.form, (state) => state); + + async handleSubmit(event: SubmitEvent) { + event.preventDefault(); + event.stopPropagation(); + this.form.handleSubmit(); + } + + async ngOnInit() { + this.form.update({ + validators: { + onBlur: this.formSchema(), + onSubmit: this.formSchema(), + onSubmitAsync: async ({ value }) => { + try { + await sendPasswordResetEmail(this.ui(), value.email); + this.emailSent.set(true); + this.passwordSent?.emit(); + } catch (error) { + if (error instanceof FirebaseUIError) { + return error.message; + } + + return this.unknownErrorLabel(); + } + }, + }, + }); + } +} diff --git a/packages/angular/src/lib/auth/forms/forgot-password-form/forgot-password-form.component.ts b/packages/angular/src/lib/auth/forms/forgot-password-form/forgot-password-form.component.ts deleted file mode 100644 index fbbf6a89..00000000 --- a/packages/angular/src/lib/auth/forms/forgot-password-form/forgot-password-form.component.ts +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, inject, Input, OnInit } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { injectForm, TanStackField } from "@tanstack/angular-form"; -import { FirebaseUI } from "../../../provider"; -import { Auth } from "@angular/fire/auth"; -import { ButtonComponent } from "../../../components/button/button.component"; -import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; -import { createForgotPasswordFormSchema, FirebaseUIConfiguration, FirebaseUIError, sendPasswordResetEmail } from "@firebase-ui/core"; -import { firstValueFrom } from "rxjs"; -import { Router } from "@angular/router"; - -@Component({ - selector: "fui-forgot-password-form", - standalone: true, - imports: [CommonModule, TanStackField, ButtonComponent, TermsAndPrivacyComponent], - template: ` -
- {{ checkEmailForResetMessage | async }} -
-
-
- - - -
- - - -
- - {{ resetPasswordLabel | async }} - -
{{ formError }}
-
- -
- -
-
- `, -}) -export class ForgotPasswordFormComponent implements OnInit { - private ui = inject(FirebaseUI); - private router = inject(Router); - - @Input({ required: true }) signInRoute!: string; - - formError: string | null = null; - emailSent = false; - private formSchema: any; - private config: FirebaseUIConfiguration; - - form = injectForm({ - defaultValues: { - email: "", - }, - }); - - async ngOnInit() { - try { - this.config = await firstValueFrom(this.ui.config()); - - this.formSchema = createForgotPasswordFormSchema(this.config); - - this.form.update({ - validators: { - onSubmit: this.formSchema, - onBlur: this.formSchema, - }, - }); - } catch (error) { - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - async handleSubmit(event: SubmitEvent) { - event.preventDefault(); - event.stopPropagation(); - - const email = this.form.state.values.email; - - if (!email) { - return; - } - - await this.resetPassword(email); - } - - async resetPassword(email: string) { - this.formError = null; - - try { - const validationResult = this.formSchema.safeParse({ - email, - }); - - if (!validationResult.success) { - const validationErrors = validationResult.error.format(); - - if (validationErrors.email?._errors?.length) { - this.formError = validationErrors.email._errors[0]; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - return; - } - - // Send password reset email - await sendPasswordResetEmail(await firstValueFrom(this.ui.config()), email); - - this.emailSent = true; - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - navigateTo(route: string) { - this.router.navigateByUrl(route); - } - - get emailLabel() { - return this.ui.translation("labels", "emailAddress"); - } - - get resetPasswordLabel() { - return this.ui.translation("labels", "resetPassword"); - } - - get backToSignInLabel() { - return this.ui.translation("labels", "backToSignIn"); - } - - get checkEmailForResetMessage() { - return this.ui.translation("messages", "checkEmailForReset"); - } -} diff --git a/packages/angular/src/lib/auth/forms/phone-form/phone-form.component.spec.ts b/packages/angular/src/lib/auth/forms/phone-auth-form/phone-auth-form.component.spec.ts similarity index 100% rename from packages/angular/src/lib/auth/forms/phone-form/phone-form.component.spec.ts rename to packages/angular/src/lib/auth/forms/phone-auth-form/phone-auth-form.component.spec.ts diff --git a/packages/angular/src/lib/auth/forms/phone-auth-form/phone-auth-form.component.ts b/packages/angular/src/lib/auth/forms/phone-auth-form/phone-auth-form.component.ts new file mode 100644 index 00000000..cb38cee6 --- /dev/null +++ b/packages/angular/src/lib/auth/forms/phone-auth-form/phone-auth-form.component.ts @@ -0,0 +1,309 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Component, + OnInit, + ElementRef, + effect, + input, + signal, + output, + computed, + viewChild, +} from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { injectForm, injectStore, TanStackAppField, TanStackField } from "@tanstack/angular-form"; +import { injectPhoneAuthFormSchema, injectTranslation, injectUI } from "../../../provider"; +import { ConfirmationResult, RecaptchaVerifier, UserCredential } from "@angular/fire/auth"; +import { PoliciesComponent } from "../../../components/policies/policies.component"; +import { CountrySelectorComponent } from "../../../components/country-selector/country-selector.component"; +import { + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, +} from "../../../components/form/form.component"; +import { + countryData, + FirebaseUIError, + formatPhoneNumberWithCountry, + confirmPhoneNumber, + signInWithPhoneNumber, + CountryCode, +} from "@firebase-ui/core"; + +@Component({ + selector: "fui-phone-number-form", + standalone: true, + imports: [ + CommonModule, + TanStackField, + TanStackAppField, + PoliciesComponent, + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + CountrySelectorComponent, + ], + template: ` +
+
+ + +
+
+
+
+ +
+ + {{ sendCodeLabel() }} + + +
+ + `, +}) +export class PhoneNumberFormComponent implements OnInit { + private ui = injectUI(); + private formSchema = injectPhoneAuthFormSchema(); + private phoneFormSchema: ReturnType; + + onSubmit = output(); + country = signal(countryData[0].code); + + phoneNumberLabel = injectTranslation("labels", "phoneNumber"); + sendCodeLabel = injectTranslation("labels", "sendCode"); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + + recaptchaContainer = viewChild.required>("recaptchaContainer"); + + recaptchaVerifier = computed(() => { + return new RecaptchaVerifier(this.ui().auth, this.recaptchaContainer().nativeElement, { + size: "normal", // TODO(ehesp): Get this from the ui behavior + }); + }); + + form = injectForm({ + defaultValues: { + phoneNumber: "", + }, + }); + + state = injectStore(this.form, (state) => state); + + async ngOnInit() { + this.phoneFormSchema = this.pickPhoneFormSchema(); + + effect(() => { + this.form.update({ + validators: { + onBlur: this.phoneFormSchema(), + onSubmit: this.phoneFormSchema(), + onSubmitAsync: async ({ value }) => { + const formattedNumber = formatPhoneNumberWithCountry(value.phoneNumber, this.country()); + + try { + const result = await signInWithPhoneNumber(this.ui(), formattedNumber, this.recaptchaVerifier()); + this.onSubmit.emit(result); + } catch (error) { + if (error instanceof FirebaseUIError) { + return error.message; + } + + return this.unknownErrorLabel(); + } + }, + }, + }); + }); + + effect((onCleanup) => { + const verifier = this.recaptchaVerifier(); + + onCleanup(() => { + verifier.clear(); + }); + }); + } + + private pickPhoneFormSchema() { + return computed(() => + this.formSchema().pick({ + phoneNumber: true, + }) + ); + } + + async handleSubmit(event: SubmitEvent) { + event.preventDefault(); + event.stopPropagation(); + this.form.handleSubmit(); + } +} + +@Component({ + selector: "fui-verification-form", + standalone: true, + imports: [ + CommonModule, + TanStackField, + TanStackAppField, + PoliciesComponent, + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, + ], + template: ` +
+
+ +
+ + + +
+ + {{ verifyCodeLabel() }} + + +
+ +
+ +
+ + `, +}) +export class VerificationFormComponent implements OnInit { + private ui = injectUI(); + private formSchema = injectPhoneAuthFormSchema(); + private verificationFormSchema: ReturnType; + + confirmationResult = input.required(); + resendDelay = input(30); + signIn = output(); + + isResending = signal(false); + + verificationCodeLabel = injectTranslation("labels", "verificationCode"); + verifyCodeLabel = injectTranslation("labels", "verifyCode"); + resendCodeLabel = injectTranslation("labels", "resendCode"); + sendingLabel = injectTranslation("labels", "sending"); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + + // @Input() onSubmit!: (code: string) => Promise; + // @Input() onResend!: () => Promise; + // @Input() formError: string | null = null; + // @Input() showTerms = false; + // @Input() isResending = false; + // @Input() canResend = false; + // @Input() timeLeft = 0; + // @ViewChild("recaptchaContainer", { static: true }) + // recaptchaContainer!: ElementRef; + + // private formSchema: any; + // private config: any; + + form = injectForm({ + defaultValues: { + verificationCode: "", + }, + }); + + state = injectStore(this.form, (state) => state); + + async ngOnInit() { + this.verificationFormSchema = this.pickVerificationFormSchema(); + + effect(() => { + this.form.update({ + validators: { + onBlur: this.verificationFormSchema(), + onSubmit: this.verificationFormSchema(), + onSubmitAsync: async ({ value }) => { + try { + const credential = await confirmPhoneNumber(this.ui(), this.confirmationResult(), value.verificationCode); + this.signIn.emit(credential); + } catch (error) { + if (error instanceof FirebaseUIError) { + return error.message; + } + + return this.unknownErrorLabel(); + } + }, + }, + }); + }); + } + + private pickVerificationFormSchema() { + return computed(() => + this.formSchema().pick({ + verificationCode: true, + }) + ); + } + + async handleSubmit(event: SubmitEvent) { + event.preventDefault(); + event.stopPropagation(); + this.form.handleSubmit(); + } + + async onResend() { + alert("TODO: Implement resend code"); + } +} + +@Component({ + selector: "fui-phone-auth-form", + standalone: true, + imports: [CommonModule, PhoneNumberFormComponent, VerificationFormComponent], + template: ` +
+ @if (confirmationResult()) { + + } @else { + + } +
+ `, +}) +export class PhoneAuthFormComponent { + confirmationResult = signal(null); + resendDelay = input(30); + signIn = output(); +} diff --git a/packages/angular/src/lib/auth/forms/phone-form/phone-form.component.ts b/packages/angular/src/lib/auth/forms/phone-form/phone-form.component.ts deleted file mode 100644 index b1a7dc96..00000000 --- a/packages/angular/src/lib/auth/forms/phone-form/phone-form.component.ts +++ /dev/null @@ -1,541 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, inject, Input, OnDestroy, OnInit, ViewChild, ElementRef } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { injectForm, TanStackField } from "@tanstack/angular-form"; -import { FirebaseUI } from "../../../provider"; -import { Auth, ConfirmationResult, RecaptchaVerifier } from "@angular/fire/auth"; -import { map } from "rxjs/operators"; -import { ButtonComponent } from "../../../components/button/button.component"; -import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; -import { CountrySelectorComponent } from "../../../components/country-selector/country-selector.component"; -import { - CountryData, - countryData, - createPhoneFormSchema, - FirebaseUIError, - formatPhoneNumberWithCountry, - confirmPhoneNumber, - signInWithPhoneNumber, - FirebaseUIConfiguration, -} from "@firebase-ui/core"; -import { interval, Subscription, firstValueFrom } from "rxjs"; -import { Router } from "@angular/router"; -import { takeWhile } from "rxjs/operators"; - -@Component({ - selector: "fui-phone-number-form", - standalone: true, - imports: [CommonModule, TanStackField, ButtonComponent, TermsAndPrivacyComponent, CountrySelectorComponent], - template: ` -
-
- - - -
- -
-
-
- - - -
- - {{ sendCodeLabel | async }} - -
{{ formError }}
-
-
- `, -}) -export class PhoneNumberFormComponent implements OnInit, OnDestroy { - private ui = inject(FirebaseUI); - - @Input() onSubmit!: (phoneNumber: string) => Promise; - @Input() formError: string | null = null; - @Input() showTerms = true; - @ViewChild("recaptchaContainer", { static: true }) - recaptchaContainer!: ElementRef; - - recaptchaVerifier: RecaptchaVerifier | null = null; - selectedCountry: CountryData = countryData[0]; - private formSchema: any; - private config: FirebaseUIConfiguration; - - form = injectForm({ - defaultValues: { - phoneNumber: "", - }, - }); - - async ngOnInit() { - try { - this.config = await firstValueFrom(this.ui.config()); - - this.formSchema = createPhoneFormSchema(this.config).pick({ - phoneNumber: true, - }); - - this.form.update({ - validators: { - onSubmit: this.formSchema, - onBlur: this.formSchema, - }, - }); - - await this.initRecaptcha(); - } catch (error) { - console.error(error); - } - } - - ngOnDestroy() { - if (this.recaptchaVerifier) { - this.recaptchaVerifier.clear(); - this.recaptchaVerifier = null; - } - } - - async initRecaptcha() { - const verifier = new RecaptchaVerifier( - (await firstValueFrom(this.ui.config())).getAuth(), - this.recaptchaContainer.nativeElement, - { - size: this.config?.recaptchaMode ?? "normal", - } - ); - this.recaptchaVerifier = verifier; - } - - async handleSubmit(event: SubmitEvent) { - event.preventDefault(); - event.stopPropagation(); - - const phoneNumber = this.form.state.values.phoneNumber; - - if (!phoneNumber) { - return; - } - - this.submitPhoneNumber(phoneNumber); - } - - async submitPhoneNumber(phoneNumber: string) { - try { - // Validate phoneNumber - const validationResult = this.formSchema.safeParse({ - phoneNumber, - }); - - if (!validationResult.success) { - const validationErrors = validationResult.error.format(); - - if (validationErrors.phoneNumber?._errors?.length) { - // We can't set formError directly since it's an input, so we need to call the parent - await this.onSubmit("VALIDATION_ERROR:" + validationErrors.phoneNumber._errors[0]); - return; - } - - await this.onSubmit("VALIDATION_ERROR:Invalid phone number"); - return; - } - - // Format number and submit - const formattedNumber = formatPhoneNumberWithCountry(phoneNumber, this.selectedCountry.dialCode); - await this.onSubmit(formattedNumber); - } catch (error) { - console.error(error); - } - } - - handleCountryChange(country: CountryData) { - this.selectedCountry = country; - } - - get phoneNumberLabel() { - return this.ui.translation("labels", "phoneNumber"); - } - - get sendCodeLabel() { - return this.ui.translation("labels", "sendCode"); - } -} - -@Component({ - selector: "fui-verification-form", - standalone: true, - imports: [CommonModule, TanStackField, ButtonComponent, TermsAndPrivacyComponent], - template: ` -
-
- - - -
- -
-
-
- - - - - -
- - {{ verifyCodeLabel | async }} - - - - {{ sendingLabel | async }} - - - {{ resendCodeLabel | async }} ({{ timeLeft }}s) - - - {{ resendCodeLabel | async }} - - -
{{ formError }}
-
- - -
- `, -}) -export class VerificationFormComponent implements OnInit, OnDestroy { - private ui = inject(FirebaseUI); - - @Input() onSubmit!: (code: string) => Promise; - @Input() onResend!: () => Promise; - @Input() formError: string | null = null; - @Input() showTerms = false; - @Input() isResending = false; - @Input() canResend = false; - @Input() timeLeft = 0; - @ViewChild("recaptchaContainer", { static: true }) - recaptchaContainer!: ElementRef; - - private formSchema: any; - private config: any; - - form = injectForm({ - defaultValues: { - verificationCode: "", - }, - }); - - async ngOnInit() { - try { - this.config = await firstValueFrom(this.ui.config()); - - // Create schema once - this.formSchema = createPhoneFormSchema(this.config?.translations).pick({ - verificationCode: true, - }); - - this.form.update({ - validators: { - onSubmit: this.formSchema, - onBlur: this.formSchema, - }, - }); - } catch (error) { - console.error(error); - } - } - - ngOnDestroy() {} - - async handleSubmit(event: SubmitEvent) { - event.preventDefault(); - event.stopPropagation(); - - const code = this.form.state.values.verificationCode; - - if (!code) { - return; - } - - await this.verifyCode(code); - } - - async verifyCode(code: string) { - try { - const validationResult = this.formSchema.safeParse({ - verificationCode: code, - }); - - if (!validationResult.success) { - const validationErrors = validationResult.error.format(); - - if (validationErrors.verificationCode?._errors?.length) { - await this.onSubmit("VALIDATION_ERROR:" + validationErrors.verificationCode._errors[0]); - return; - } - - await this.onSubmit("VALIDATION_ERROR:Invalid verification code"); - return; - } - - await this.onSubmit(code); - } catch (error) { - console.error(error); - } - } - - get verificationCodeLabel() { - return this.ui.translation("labels", "verificationCode"); - } - - get verifyCodeLabel() { - return this.ui.translation("labels", "verifyCode"); - } - - get resendCodeLabel() { - return this.ui.translation("labels", "resendCode"); - } - - get sendingLabel() { - return this.ui.translation("labels", "sending"); - } -} - -@Component({ - selector: "fui-phone-form", - standalone: true, - imports: [CommonModule, PhoneNumberFormComponent, VerificationFormComponent], - template: ` -
- - - - - - -
- `, -}) -export class PhoneFormComponent implements OnInit, OnDestroy { - private ui = inject(FirebaseUI); - private config: any; - - @Input() resendDelay = 30; - - formError: string | null = null; - confirmationResult: ConfirmationResult | null = null; - recaptchaVerifier: RecaptchaVerifier | null = null; - phoneNumber = ""; - isResending = false; - timeLeft = 0; - canResend = false; - timerSubscription: Subscription | null = null; - - async ngOnInit() { - try { - this.config = await firstValueFrom(this.ui.config()); - } catch (error) { - console.error(error); - } - } - - ngOnDestroy() { - if (this.timerSubscription) { - this.timerSubscription.unsubscribe(); - } - } - - async handlePhoneSubmit(number: string): Promise { - this.formError = null; - - if (number.startsWith("VALIDATION_ERROR:")) { - this.formError = number.substring("VALIDATION_ERROR:".length); - return; - } - - try { - if (!this.recaptchaVerifier) { - throw new Error("ReCAPTCHA not initialized"); - } - - const result = await signInWithPhoneNumber( - await firstValueFrom(this.ui.config()), - number, - this.recaptchaVerifier - ); - - this.phoneNumber = number; - this.confirmationResult = result; - this.startTimer(); - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - return; - } - console.error(error); - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - async handleResend(): Promise { - if (this.isResending || !this.canResend || !this.phoneNumber) { - return; - } - - this.isResending = true; - this.formError = null; - - try { - if (this.recaptchaVerifier) { - this.recaptchaVerifier.clear(); - } - - // We need to get the recaptcha container from the verification form - // This is a bit hacky, but it works for now - const recaptchaContainer = document.querySelector(".fui-recaptcha-container") as HTMLDivElement; - if (!recaptchaContainer) { - throw new Error("ReCAPTCHA container not found"); - } - - const verifier = new RecaptchaVerifier((await firstValueFrom(this.ui.config())).getAuth(), recaptchaContainer, { - size: this.config?.recaptchaMode ?? "normal", - }); - this.recaptchaVerifier = verifier; - - const result = await signInWithPhoneNumber(await firstValueFrom(this.ui.config()), this.phoneNumber, verifier); - - this.confirmationResult = result; - this.startTimer(); - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - } else { - console.error(error); - this.ui.translation("errors", "unknownError").subscribe((message) => { - this.formError = message; - }); - } - } finally { - this.isResending = false; - } - } - - async handleVerificationSubmit(code: string): Promise { - if (code.startsWith("VALIDATION_ERROR:")) { - this.formError = code.substring("VALIDATION_ERROR:".length); - return; - } - - if (!this.confirmationResult) { - throw new Error("Confirmation result not initialized"); - } - - this.formError = null; - - try { - await confirmPhoneNumber(await firstValueFrom(this.ui.config()), this.confirmationResult, code); - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - return; - } - console.error(error); - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - startTimer() { - if (this.timerSubscription) { - this.timerSubscription.unsubscribe(); - } - - this.timeLeft = this.resendDelay; - this.canResend = false; - - this.timerSubscription = interval(1000) - .pipe(takeWhile(() => this.timeLeft > 0)) - .subscribe(() => { - this.timeLeft--; - if (this.timeLeft === 0) { - this.canResend = true; - if (this.timerSubscription) { - this.timerSubscription.unsubscribe(); - } - } - }); - } -} diff --git a/packages/angular/src/lib/auth/forms/register-form/register-form.component.ts b/packages/angular/src/lib/auth/forms/register-form/register-form.component.ts deleted file mode 100644 index c1caa691..00000000 --- a/packages/angular/src/lib/auth/forms/register-form/register-form.component.ts +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, inject, Input, OnInit } from "@angular/core"; -import { ButtonComponent } from "../../../components/button/button.component"; -import { FirebaseUI } from "../../../provider"; -import { CommonModule } from "@angular/common"; -import { injectForm, TanStackField } from "@tanstack/angular-form"; -import { - createEmailFormSchema, - EmailFormSchema, - FirebaseUIError, - createUserWithEmailAndPassword, - FirebaseUIConfiguration, -} from "@firebase-ui/core"; -import { Auth } from "@angular/fire/auth"; -import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; -import { firstValueFrom } from "rxjs"; -import { Router } from "@angular/router"; - -@Component({ - selector: "fui-register-form", - imports: [CommonModule, TanStackField, ButtonComponent, TermsAndPrivacyComponent], - template: ` -
-
- - - -
-
- - - -
- - - -
- - {{ createAccountLabel | async }} - -
{{ formError }}
-
- -
- -
-
- `, - standalone: true, -}) -export class RegisterFormComponent implements OnInit { - private ui = inject(FirebaseUI); - private router = inject(Router); - - @Input({ required: true }) signInRoute!: string; - - formError: string | null = null; - private formSchema: any; - private config: FirebaseUIConfiguration; - - form = injectForm({ - defaultValues: { - email: "", - password: "", - }, - }); - - async ngOnInit() { - try { - this.config = await firstValueFrom(this.ui.config()); - - this.formSchema = createEmailFormSchema(this.config); - - this.form.update({ - validators: { - onSubmit: this.formSchema, - onBlur: this.formSchema, - }, - }); - } catch (error) { - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - async handleSubmit(event: SubmitEvent) { - event.preventDefault(); - event.stopPropagation(); - - const email = this.form.state.values.email; - const password = this.form.state.values.password; - - if (!email || !password) { - return; - } - - await this.registerUser(email, password); - } - - async registerUser(email: string, password: string) { - this.formError = null; - - try { - const validationResult = this.formSchema.safeParse({ - email, - password, - }); - - if (!validationResult.success) { - const validationErrors = validationResult.error.format(); - - if (validationErrors.email?._errors?.length) { - this.formError = validationErrors.email._errors[0]; - return; - } - - if (validationErrors.password?._errors?.length) { - this.formError = validationErrors.password._errors[0]; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - return; - } - - await createUserWithEmailAndPassword(await firstValueFrom(this.ui.config()), email, password); - } catch (error) { - if (error instanceof FirebaseUIError) { - this.formError = error.message; - return; - } - - this.formError = await firstValueFrom(this.ui.translation("errors", "unknownError")); - } - } - - navigateTo(route: string) { - this.router.navigateByUrl(route); - } - - get emailLabel() { - return this.ui.translation("labels", "emailAddress"); - } - - get passwordLabel() { - return this.ui.translation("labels", "password"); - } - - get createAccountLabel() { - return this.ui.translation("labels", "createAccount"); - } - - get haveAccountLabel() { - return this.ui.translation("prompts", "haveAccount"); - } - - get signInLabel() { - return this.ui.translation("labels", "signIn"); - } -} diff --git a/packages/angular/src/lib/auth/forms/email-password-form/email-password-form.component.spec.ts b/packages/angular/src/lib/auth/forms/sign-in-auth-form/sign-in-auth-form.component.spec.ts similarity index 100% rename from packages/angular/src/lib/auth/forms/email-password-form/email-password-form.component.spec.ts rename to packages/angular/src/lib/auth/forms/sign-in-auth-form/sign-in-auth-form.component.spec.ts diff --git a/packages/angular/src/lib/auth/forms/sign-in-auth-form/sign-in-auth-form.component.ts b/packages/angular/src/lib/auth/forms/sign-in-auth-form/sign-in-auth-form.component.ts new file mode 100644 index 00000000..7342d5ba --- /dev/null +++ b/packages/angular/src/lib/auth/forms/sign-in-auth-form/sign-in-auth-form.component.ts @@ -0,0 +1,134 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, output, effect } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { UserCredential } from "@angular/fire/auth"; +import { injectForm, TanStackField, TanStackAppField, injectStore } from "@tanstack/angular-form"; +import { FirebaseUIError, signInWithEmailAndPassword } from "@firebase-ui/core"; + +import { injectSignInAuthFormSchema, injectTranslation, injectUI } from "../../../provider"; +import { PoliciesComponent } from "../../../components/policies/policies.component"; +import { + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, +} from "../../../components/form/form.component"; + +@Component({ + selector: "fui-sign-in-auth-form", + standalone: true, + imports: [ + CommonModule, + TanStackField, + TanStackAppField, + PoliciesComponent, + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, + ], + template: ` +
+
+ +
+
+ + @if (forgotPassword) { + + } + +
+ + + +
+ + {{ signInLabel() }} + + +
+ + @if (signUp) { + + } + + `, +}) +export class SignInAuthFormComponent implements OnInit { + private ui = injectUI(); + private formSchema = injectSignInAuthFormSchema(); + + emailLabel = injectTranslation("labels", "emailAddress"); + passwordLabel = injectTranslation("labels", "password"); + forgotPasswordLabel = injectTranslation("labels", "forgotPassword"); + signInLabel = injectTranslation("labels", "signIn"); + noAccountLabel = injectTranslation("prompts", "noAccount"); + registerLabel = injectTranslation("labels", "register"); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + + forgotPassword = output(); + signUp = output(); + signIn = output(); + + form = injectForm({ + defaultValues: { + email: "", + password: "", + }, + }); + + state = injectStore(this.form, (state) => state); + + handleSubmit(event: SubmitEvent) { + event.preventDefault(); + event.stopPropagation(); + this.form.handleSubmit(); + } + + ngOnInit() { + this.form.update({ + validators: { + onChange: this.formSchema(), + onBlur: this.formSchema(), + onSubmit: this.formSchema(), + onSubmitAsync: async ({ value }) => { + console.log("onSubmitAsync", value); + try { + const credential = await signInWithEmailAndPassword(this.ui(), value.email, value.password); + this.signIn?.emit(credential); + } catch (error) { + console.log("error", error); + if (error instanceof FirebaseUIError) { + return error.message; + } + + return this.unknownErrorLabel(); + } + }, + }, + }); + } +} diff --git a/packages/angular/src/lib/auth/forms/register-form/register-form.component.spec.ts b/packages/angular/src/lib/auth/forms/sign-up-auth-form/sign-up-auth-form.component.spec.ts similarity index 100% rename from packages/angular/src/lib/auth/forms/register-form/register-form.component.spec.ts rename to packages/angular/src/lib/auth/forms/sign-up-auth-form/sign-up-auth-form.component.spec.ts diff --git a/packages/angular/src/lib/auth/forms/sign-up-auth-form/sign-up-auth-form.component.ts b/packages/angular/src/lib/auth/forms/sign-up-auth-form/sign-up-auth-form.component.ts new file mode 100644 index 00000000..35b0ca0a --- /dev/null +++ b/packages/angular/src/lib/auth/forms/sign-up-auth-form/sign-up-auth-form.component.ts @@ -0,0 +1,128 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, output, effect } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { injectForm, injectStore, TanStackAppField, TanStackField } from "@tanstack/angular-form"; +import { FirebaseUIError, createUserWithEmailAndPassword } from "@firebase-ui/core"; +import { UserCredential } from "@angular/fire/auth"; + +import { PoliciesComponent } from "../../../components/policies/policies.component"; +import { injectSignUpAuthFormSchema, injectTranslation, injectUI } from "../../../provider"; +import { + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, +} from "../../../components/form/form.component"; + +@Component({ + selector: "fui-sign-up-auth-form", + imports: [ + CommonModule, + TanStackField, + TanStackAppField, + PoliciesComponent, + FormInputComponent, + FormSubmitComponent, + FormErrorMessageComponent, + FormActionComponent, + ], + template: ` +
+
+ +
+
+ +
+ + + +
+ + {{ createAccountLabel() }} + + +
+ + @if (signIn) { + + } + + `, + standalone: true, +}) +export class SignUpAuthFormComponent implements OnInit { + private ui = injectUI(); + private formSchema = injectSignUpAuthFormSchema(); + + emailLabel = injectTranslation("labels", "emailAddress"); + passwordLabel = injectTranslation("labels", "password"); + createAccountLabel = injectTranslation("labels", "createAccount"); + haveAccountLabel = injectTranslation("prompts", "haveAccount"); + signInLabel = injectTranslation("labels", "signIn"); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + + signUp = output(); + signIn = output(); + + form = injectForm({ + defaultValues: { + email: "", + password: "", + }, + }); + + state = injectStore(this.form, (state) => state); + + handleSubmit(event: SubmitEvent) { + event.preventDefault(); + event.stopPropagation(); + this.form.handleSubmit(); + } + + ngOnInit() { + this.form.update({ + validators: { + onBlur: this.formSchema(), + onSubmit: this.formSchema(), + onSubmitAsync: async ({ value }) => { + try { + const credential = await createUserWithEmailAndPassword(this.ui(), value.email, value.password); + this.signUp?.emit(credential); + } catch (error) { + if (error instanceof FirebaseUIError) { + return error.message; + } + + return this.unknownErrorLabel(); + } + }, + }, + }); + } +} diff --git a/packages/angular/src/lib/auth/oauth/google-sign-in-button.component.ts b/packages/angular/src/lib/auth/oauth/google-sign-in-button.component.ts index f88edeff..561caca0 100644 --- a/packages/angular/src/lib/auth/oauth/google-sign-in-button.component.ts +++ b/packages/angular/src/lib/auth/oauth/google-sign-in-button.component.ts @@ -14,10 +14,10 @@ * limitations under the License. */ -import { Component, inject } from "@angular/core"; +import { Component, input } from "@angular/core"; import { CommonModule } from "@angular/common"; import { OAuthButtonComponent } from "./oauth-button.component"; -import { FirebaseUI } from "../../provider"; +import { injectTranslation, injectUI } from "../../provider"; import { GoogleAuthProvider } from "@angular/fire/auth"; @Component({ @@ -49,15 +49,19 @@ import { GoogleAuthProvider } from "@angular/fire/auth"; d="M43.611 20.083H42V20H24v8h11.303a12.04 12.04 0 0 1-4.087 5.571l.003-.002 6.19 5.238C36.971 39.205 44 34 44 24c0-1.341-.138-2.65-.389-3.917z" /> - {{ signInWithGoogleLabel | async }} + {{ signInWithGoogleLabel() }} `, }) export class GoogleSignInButtonComponent { - private ui = inject(FirebaseUI); - googleProvider = new GoogleAuthProvider(); + ui = injectUI(); + signInWithGoogleLabel = injectTranslation("labels", "signInWithGoogle"); - get signInWithGoogleLabel() { - return this.ui.translation("labels", "signInWithGoogle"); + private defaultProvider = new GoogleAuthProvider(); + + provider = input(); + + get googleProvider() { + return this.provider() || this.defaultProvider; } } diff --git a/packages/angular/src/lib/auth/oauth/oauth-button.component.ts b/packages/angular/src/lib/auth/oauth/oauth-button.component.ts index 5ae74ac8..a11fc488 100644 --- a/packages/angular/src/lib/auth/oauth/oauth-button.component.ts +++ b/packages/angular/src/lib/auth/oauth/oauth-button.component.ts @@ -14,13 +14,12 @@ * limitations under the License. */ -import { Component, inject, Input, OnInit } from "@angular/core"; +import { Component, input, signal } from "@angular/core"; import { CommonModule } from "@angular/common"; import { ButtonComponent } from "../../components/button/button.component"; -import { FirebaseUI } from "../../provider"; -import { Auth, AuthProvider } from "@angular/fire/auth"; -import { FirebaseUIError, signInWithOAuth } from "@firebase-ui/core"; -import { firstValueFrom } from "rxjs"; +import { injectTranslation, injectUI } from "../../provider"; +import { AuthProvider } from "@angular/fire/auth"; +import { FirebaseUIError, signInWithProvider } from "@firebase-ui/core"; @Component({ selector: "fui-oauth-button", @@ -28,39 +27,40 @@ import { firstValueFrom } from "rxjs"; imports: [CommonModule, ButtonComponent], template: `
- + + + @if (error()) { +
{{ error() }}
+ }
`, }) -export class OAuthButtonComponent implements OnInit { - private ui = inject(FirebaseUI); - - @Input() provider!: AuthProvider; - - error: string | null = null; - - ngOnInit() { - if (!this.provider) { - console.error("Provider is required for OAuthButtonComponent"); - } - } +export class OAuthButtonComponent { + ui = injectUI(); + unknownErrorLabel = injectTranslation("errors", "unknownError"); + provider = input.required(); + error = signal(undefined); async handleOAuthSignIn() { - this.error = null; + this.error.set(undefined); try { - await signInWithOAuth(await firstValueFrom(this.ui.config()), this.provider); + await signInWithProvider(this.ui(), this.provider()); } catch (error) { if (error instanceof FirebaseUIError) { - this.error = error.message; + this.error.set(error.message); return; } + console.error(error); - firstValueFrom(this.ui.translation("errors", "unknownError")) - .then((message) => (this.error = message)) - .catch(() => (this.error = "Unknown error")); + this.error.set(this.unknownErrorLabel()); } } } diff --git a/packages/angular/src/lib/auth/screens/email-link-auth-screen/email-link-auth-screen.component.ts b/packages/angular/src/lib/auth/screens/email-link-auth-screen/email-link-auth-screen.component.ts index f3fce95d..76614770 100644 --- a/packages/angular/src/lib/auth/screens/email-link-auth-screen/email-link-auth-screen.component.ts +++ b/packages/angular/src/lib/auth/screens/email-link-auth-screen/email-link-auth-screen.component.ts @@ -14,17 +14,19 @@ * limitations under the License. */ -import { Component, inject, Input, AfterContentInit, ViewChild, ElementRef } from "@angular/core"; +import { Component, ElementRef, output, computed, viewChild } from "@angular/core"; import { CommonModule } from "@angular/common"; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, + CardContentComponent, } from "../../../components/card/card.component"; -import { FirebaseUI } from "../../../provider"; -import { EmailLinkFormComponent } from "../../forms/email-link-form/email-link-form.component"; +import { injectTranslation } from "../../../provider"; +import { EmailLinkAuthFormComponent } from "../../forms/email-link-auth-form/email-link-auth-form.component"; import { DividerComponent } from "../../../components/divider/divider.component"; +import { UserCredential } from "@angular/fire/auth"; @Component({ selector: "fui-email-link-auth-screen", @@ -35,69 +37,42 @@ import { DividerComponent } from "../../../components/divider/divider.component" CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, - EmailLinkFormComponent, + CardContentComponent, + EmailLinkAuthFormComponent, DividerComponent, ], template: `
- {{ titleText | async }} - {{ subtitleText | async }} + {{ titleText() }} + {{ subtitleText() }} - + + - - {{ dividerOrLabel | async }} -
+ @if (hasChildren()) { + {{ dividerOrLabel() }} + } +
- +
`, }) -export class EmailLinkAuthScreenComponent implements AfterContentInit { - private ui = inject(FirebaseUI); +export class EmailLinkAuthScreenComponent { + titleText = injectTranslation("labels", "signIn"); + subtitleText = injectTranslation("prompts", "signInToAccount"); + dividerOrLabel = injectTranslation("messages", "dividerOr"); - @ViewChild("contentContainer") contentContainer!: ElementRef; - private _hasProjectedContent = false; + emailSent = output(); + signIn = output(); - get hasContent(): boolean { - return this._hasProjectedContent; - } - - get titleText() { - return this.ui.translation("labels", "signIn"); - } - - get subtitleText() { - return this.ui.translation("prompts", "signInToAccount"); - } - - get dividerOrLabel() { - return this.ui.translation("messages", "dividerOr"); - } - - ngAfterContentInit() { - // Set to true initially to ensure the container is rendered - this._hasProjectedContent = true; - - // We need to use setTimeout to check after the view is rendered - setTimeout(() => { - // Check if there's any actual content in the container - if (this.contentContainer && this.contentContainer.nativeElement) { - const container = this.contentContainer.nativeElement; - // Only consider it to have content if there are child nodes that aren't just whitespace - this._hasProjectedContent = Array.from(container.childNodes as NodeListOf).some((node: Node) => { - return ( - node.nodeType === Node.ELEMENT_NODE || - (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim() !== "") - ); - }); - } else { - this._hasProjectedContent = false; - } - }); - } + contentContainer = viewChild.required('contentContainer'); + hasChildren = computed(() => this.contentContainer().nativeElement.children.length > 0); } diff --git a/packages/angular/src/lib/auth/screens/password-reset-screen/password-reset-screen.component.spec.ts b/packages/angular/src/lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component.spec.ts similarity index 96% rename from packages/angular/src/lib/auth/screens/password-reset-screen/password-reset-screen.component.spec.ts rename to packages/angular/src/lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component.spec.ts index 3659ec5d..afedcb78 100644 --- a/packages/angular/src/lib/auth/screens/password-reset-screen/password-reset-screen.component.spec.ts +++ b/packages/angular/src/lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component.spec.ts @@ -20,8 +20,7 @@ import { CommonModule } from "@angular/common"; import { By } from "@angular/platform-browser"; import { of } from "rxjs"; import { FirebaseUI } from "../../../provider"; -import { PasswordResetScreenComponent } from "./password-reset-screen.component"; -import { CardComponent } from "../../../components/card/card.component"; +import { PasswordResetScreenComponent } from "./forgot-password-auth-screen.component"; // Mock Card components @Component({ diff --git a/packages/angular/src/lib/auth/screens/password-reset-screen/password-reset-screen.component.ts b/packages/angular/src/lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component.ts similarity index 54% rename from packages/angular/src/lib/auth/screens/password-reset-screen/password-reset-screen.component.ts rename to packages/angular/src/lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component.ts index 10568f5a..595d0082 100644 --- a/packages/angular/src/lib/auth/screens/password-reset-screen/password-reset-screen.component.ts +++ b/packages/angular/src/lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component.ts @@ -14,19 +14,20 @@ * limitations under the License. */ -import { Component, EventEmitter, inject, Input, Output } from "@angular/core"; +import { Component, output } from "@angular/core"; import { CommonModule } from "@angular/common"; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, + CardContentComponent, } from "../../../components/card/card.component"; -import { FirebaseUI } from "../../../provider"; -import { ForgotPasswordFormComponent } from "../../forms/forgot-password-form/forgot-password-form.component"; +import { injectTranslation } from "../../../provider"; +import { ForgotPasswordAuthFormComponent } from "../../forms/forgot-password-auth-form/forgot-password-auth-form.component"; @Component({ - selector: "fui-password-reset-screen", + selector: "fui-forgot-password-auth-screen", standalone: true, imports: [ CommonModule, @@ -34,30 +35,27 @@ import { ForgotPasswordFormComponent } from "../../forms/forgot-password-form/fo CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, - ForgotPasswordFormComponent, + CardContentComponent, + ForgotPasswordAuthFormComponent, ], template: `
- {{ titleText | async }} - {{ subtitleText | async }} + {{ titleText() }} + {{ subtitleText() }} - + + +
`, }) -export class PasswordResetScreenComponent { - private ui = inject(FirebaseUI); +export class ForgotPasswordAuthScreenComponent { + titleText = injectTranslation("labels", "resetPassword"); + subtitleText = injectTranslation("prompts", "enterEmailToReset"); - @Input() signInRoute: string = ""; - - get titleText() { - return this.ui.translation("labels", "resetPassword"); - } - - get subtitleText() { - return this.ui.translation("prompts", "enterEmailToReset"); - } + passwordSent = output(); + backToSignIn = output(); } diff --git a/packages/angular/src/lib/auth/screens/oauth-screen/oauth-screen.component.ts b/packages/angular/src/lib/auth/screens/oauth-screen/oauth-screen.component.ts index e30a0092..21e647fb 100644 --- a/packages/angular/src/lib/auth/screens/oauth-screen/oauth-screen.component.ts +++ b/packages/angular/src/lib/auth/screens/oauth-screen/oauth-screen.component.ts @@ -14,16 +14,17 @@ * limitations under the License. */ -import { Component, inject } from "@angular/core"; +import { Component } from "@angular/core"; import { CommonModule } from "@angular/common"; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, + CardContentComponent, } from "../../../components/card/card.component"; -import { FirebaseUI } from "../../../provider"; -import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; +import { injectTranslation } from "../../../provider"; +import { PoliciesComponent } from "../../../components/policies/policies.component"; @Component({ selector: "fui-oauth-screen", @@ -34,29 +35,25 @@ import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/ CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, - TermsAndPrivacyComponent, + CardContentComponent, + PoliciesComponent, ], template: `
- {{ titleText | async }} - {{ subtitleText | async }} + {{ titleText() }} + {{ subtitleText() }} - - + + + +
`, }) export class OAuthScreenComponent { - private ui = inject(FirebaseUI); - - get titleText() { - return this.ui.translation("labels", "signIn"); - } - - get subtitleText() { - return this.ui.translation("prompts", "signInToAccount"); - } + titleText = injectTranslation("labels", "signIn"); + subtitleText = injectTranslation("prompts", "signInToAccount"); } diff --git a/packages/angular/src/lib/auth/screens/phone-auth-screen/phone-auth-screen.component.ts b/packages/angular/src/lib/auth/screens/phone-auth-screen/phone-auth-screen.component.ts index 80bbcbb9..9bdef14d 100644 --- a/packages/angular/src/lib/auth/screens/phone-auth-screen/phone-auth-screen.component.ts +++ b/packages/angular/src/lib/auth/screens/phone-auth-screen/phone-auth-screen.component.ts @@ -14,17 +14,19 @@ * limitations under the License. */ -import { Component, inject, Input, AfterContentInit, ViewChild, ElementRef } from "@angular/core"; +import { Component, ElementRef, input, output, computed, viewChild } from "@angular/core"; import { CommonModule } from "@angular/common"; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, + CardContentComponent, } from "../../../components/card/card.component"; -import { FirebaseUI } from "../../../provider"; -import { PhoneFormComponent } from "../../forms/phone-form/phone-form.component"; +import { injectTranslation } from "../../../provider"; +import { PhoneAuthFormComponent } from "../../forms/phone-auth-form/phone-auth-form.component"; import { DividerComponent } from "../../../components/divider/divider.component"; +import { UserCredential } from "@angular/fire/auth"; @Component({ selector: "fui-phone-auth-screen", @@ -35,71 +37,39 @@ import { DividerComponent } from "../../../components/divider/divider.component" CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, - PhoneFormComponent, + CardContentComponent, + PhoneAuthFormComponent, DividerComponent, ], template: `
- {{ titleText | async }} - {{ subtitleText | async }} + {{ titleText() }} + {{ subtitleText() }} - + + - - {{ dividerOrLabel | async }} -
+ @if (hasChildren()) { + {{ dividerOrLabel() }} + } +
- +
`, }) -export class PhoneAuthScreenComponent implements AfterContentInit { - private ui = inject(FirebaseUI); +export class PhoneAuthScreenComponent { + titleText = injectTranslation("labels", "signIn"); + subtitleText = injectTranslation("prompts", "signInToAccount"); + dividerOrLabel = injectTranslation("messages", "dividerOr"); - @Input() resendDelay = 30; + resendDelay = input(30); + signIn = output(); - @ViewChild("contentContainer") contentContainer!: ElementRef; - private _hasProjectedContent = false; - - get hasContent(): boolean { - return this._hasProjectedContent; - } - - get titleText() { - return this.ui.translation("labels", "signIn"); - } - - get subtitleText() { - return this.ui.translation("prompts", "signInToAccount"); - } - - get dividerOrLabel() { - return this.ui.translation("messages", "dividerOr"); - } - - ngAfterContentInit() { - // Set to true initially to ensure the container is rendered - this._hasProjectedContent = true; - - // We need to use setTimeout to check after the view is rendered - setTimeout(() => { - // Check if there's any actual content in the container - if (this.contentContainer && this.contentContainer.nativeElement) { - const container = this.contentContainer.nativeElement; - // Only consider it to have content if there are child nodes that aren't just whitespace - this._hasProjectedContent = Array.from(container.childNodes as NodeListOf).some((node: Node) => { - return ( - node.nodeType === Node.ELEMENT_NODE || - (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim() !== "") - ); - }); - } else { - this._hasProjectedContent = false; - } - }); - } + contentContainer = viewChild.required("contentContainer"); + hasChildren = computed(() => this.contentContainer().nativeElement.children.length > 0); } diff --git a/packages/angular/src/lib/auth/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts b/packages/angular/src/lib/auth/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts index 90804de6..b3d8e580 100644 --- a/packages/angular/src/lib/auth/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts +++ b/packages/angular/src/lib/auth/screens/sign-in-auth-screen/sign-in-auth-screen.component.ts @@ -14,29 +14,20 @@ * limitations under the License. */ -import { - Component, - ContentChildren, - EventEmitter, - inject, - Input, - Output, - QueryList, - AfterContentInit, - ViewChild, - ElementRef, -} from "@angular/core"; +import { Component, ElementRef, output, viewChild, computed } from "@angular/core"; import { CommonModule } from "@angular/common"; + +import { injectTranslation } from "../../../provider"; +import { SignInAuthFormComponent } from "../../forms/sign-in-auth-form/sign-in-auth-form.component"; +import { DividerComponent } from "../../../components/divider/divider.component"; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, + CardContentComponent, } from "../../../components/card/card.component"; -import { FirebaseUI } from "../../../provider"; -import { EmailPasswordFormComponent } from "../../forms/email-password-form/email-password-form.component"; -import { DividerComponent } from "../../../components/divider/divider.component"; - +import { UserCredential } from "@angular/fire/auth"; @Component({ selector: "fui-sign-in-auth-screen", standalone: true, @@ -46,74 +37,40 @@ import { DividerComponent } from "../../../components/divider/divider.component" CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, - EmailPasswordFormComponent, + CardContentComponent, + SignInAuthFormComponent, DividerComponent, ], template: `
- {{ titleText | async }} - {{ subtitleText | async }} + {{ titleText() }} + {{ subtitleText() }} - - - - {{ dividerOrLabel | async }} -
+ + + + @if (hasChildren()) { + {{ dividerOrLabel() }} + } +
- +
`, }) -export class SignInAuthScreenComponent implements AfterContentInit { - private ui = inject(FirebaseUI); - - @Input() forgotPasswordRoute: string = ""; - @Input() registerRoute: string = ""; - @ViewChild("contentContainer") contentContainer!: ElementRef; - private _hasProjectedContent = false; - - get hasContent(): boolean { - return this._hasProjectedContent; - } - - get titleText() { - return this.ui.translation("labels", "signIn"); - } - - get subtitleText() { - return this.ui.translation("prompts", "signInToAccount"); - } - - get dividerOrLabel() { - return this.ui.translation("messages", "dividerOr"); - } +export class SignInAuthScreenComponent { + titleText = injectTranslation("labels", "signIn"); + subtitleText = injectTranslation("prompts", "signInToAccount"); + dividerOrLabel = injectTranslation("messages", "dividerOr"); - ngAfterContentInit() { - // Set to true initially to ensure the container is rendered - this._hasProjectedContent = true; + forgotPassword = output(); + signUp = output(); + signIn = output(); - // We need to use setTimeout to check after the view is rendered - setTimeout(() => { - // Check if there's any actual content in the container - if (this.contentContainer && this.contentContainer.nativeElement) { - const container = this.contentContainer.nativeElement; - // Only consider it to have content if there are child nodes that aren't just whitespace - this._hasProjectedContent = Array.from(container.childNodes as NodeListOf).some((node: Node) => { - return ( - node.nodeType === Node.ELEMENT_NODE || - (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim() !== "") - ); - }); - } else { - this._hasProjectedContent = false; - } - }); - } + contentContainer = viewChild.required('contentContainer'); + hasChildren = computed(() => this.contentContainer().nativeElement.children.length > 0); } diff --git a/packages/angular/src/lib/auth/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts b/packages/angular/src/lib/auth/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts index f13cbb03..3ac49247 100644 --- a/packages/angular/src/lib/auth/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts +++ b/packages/angular/src/lib/auth/screens/sign-up-auth-screen/sign-up-auth-screen.component.ts @@ -14,29 +14,21 @@ * limitations under the License. */ -import { - Component, - EventEmitter, - inject, - Input, - Output, - QueryList, - AfterContentInit, - ViewChild, - ElementRef, -} from "@angular/core"; +import { Component, ElementRef, output, computed, viewChild } from "@angular/core"; import { CommonModule } from "@angular/common"; +import { UserCredential } from "@angular/fire/auth"; + +import { injectTranslation } from "../../../provider"; +import { SignUpAuthFormComponent } from "../../forms/sign-up-auth-form/sign-up-auth-form.component"; +import { DividerComponent } from "../../../components/divider/divider.component"; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, + CardContentComponent, } from "../../../components/card/card.component"; -import { FirebaseUI } from "../../../provider"; -import { RegisterFormComponent } from "../../forms/register-form/register-form.component"; -import { DividerComponent } from "../../../components/divider/divider.component"; - @Component({ selector: "fui-sign-up-auth-screen", standalone: true, @@ -46,70 +38,39 @@ import { DividerComponent } from "../../../components/divider/divider.component" CardHeaderComponent, CardTitleComponent, CardSubtitleComponent, - RegisterFormComponent, + CardContentComponent, + SignUpAuthFormComponent, DividerComponent, ], template: `
- {{ titleText | async }} - {{ subtitleText | async }} + {{ titleText() }} + {{ subtitleText() }} - + + - - {{ dividerOrLabel | async }} -
+ @if (hasChildren()) { + {{ dividerOrLabel() }} + } +
- +
`, }) -export class SignUpAuthScreenComponent implements AfterContentInit { - private ui = inject(FirebaseUI); - - @Input() signInRoute: string = ""; - @ViewChild("contentContainer") contentContainer!: ElementRef; - private _hasProjectedContent = false; - - get hasContent(): boolean { - return this._hasProjectedContent; - } - - get titleText() { - return this.ui.translation("labels", "register"); - } - - get subtitleText() { - return this.ui.translation("prompts", "enterDetailsToCreate"); - } - - get dividerOrLabel() { - return this.ui.translation("messages", "dividerOr"); - } +export class SignUpAuthScreenComponent { + titleText = injectTranslation("labels", "register"); + subtitleText = injectTranslation("prompts", "enterDetailsToCreate"); + dividerOrLabel = injectTranslation("messages", "dividerOr"); - ngAfterContentInit() { - // Set to true initially to ensure the container is rendered - this._hasProjectedContent = true; + signUp = output(); + signIn = output(); - // We need to use setTimeout to check after the view is rendered - setTimeout(() => { - // Check if there's any actual content in the container - if (this.contentContainer && this.contentContainer.nativeElement) { - const container = this.contentContainer.nativeElement; - // Only consider it to have content if there are child nodes that aren't just whitespace - this._hasProjectedContent = Array.from(container.childNodes as NodeListOf).some((node: Node) => { - return ( - node.nodeType === Node.ELEMENT_NODE || - (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim() !== "") - ); - }); - } else { - this._hasProjectedContent = false; - } - }); - } + contentContainer = viewChild.required("contentContainer"); + hasChildren = computed(() => this.contentContainer().nativeElement.children.length > 0); } diff --git a/packages/angular/src/lib/components/button/button.component.spec.ts b/packages/angular/src/lib/components/button/button.component.spec.ts index 0c19e343..a223cbb9 100644 --- a/packages/angular/src/lib/components/button/button.component.spec.ts +++ b/packages/angular/src/lib/components/button/button.component.spec.ts @@ -14,86 +14,17 @@ * limitations under the License. */ -import { Component } from "@angular/core"; -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { By } from "@angular/platform-browser"; -import { ButtonComponent } from "./button.component"; -import { describe, it, expect, beforeEach } from "vitest"; - -@Component({ - template: ` - Click me - Secondary - Custom Class - Disabled - `, - standalone: true, - imports: [ButtonComponent], -}) -class TestHostComponent { - clicks = 0; - - handleClick() { - this.clicks++; - } -} - -describe("ButtonComponent", () => { - let fixture: ComponentFixture; - let hostComponent: TestHostComponent; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ButtonComponent, TestHostComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(TestHostComponent); - hostComponent = fixture.componentInstance; - fixture.detectChanges(); - }); - - it("renders with default variant (primary)", () => { - const buttonEl = fixture.debugElement.query(By.css('[data-testid="test-button"]')); - const button = buttonEl.nativeElement.querySelector("button"); - - expect(button).toBeTruthy(); - expect(button.classList.contains("fui-button")).toBe(true); - expect(button.classList.contains("fui-button--secondary")).toBe(false); - expect(button.textContent.trim()).toBe("Click me"); - }); - - it("renders with secondary variant", () => { - const buttonEl = fixture.debugElement.query(By.css('[data-testid="secondary-button"]')); - const button = buttonEl.nativeElement.querySelector("button"); +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { render, screen, fireEvent, } from "@testing-library/angular"; - expect(button).toBeTruthy(); - expect(button.classList.contains("fui-button")).toBe(true); - expect(button.classList.contains("fui-button--secondary")).toBe(true); - }); - - it("applies custom className", () => { - const buttonEl = fixture.debugElement.query(By.css('[data-testid="custom-class-button"]')); - - expect(buttonEl.nativeElement.classList.contains("custom-class")).toBe(true); - }); - - it("handles click events", () => { - const buttonEl = fixture.debugElement.query(By.css('[data-testid="test-button"]')); - const button = buttonEl.nativeElement.querySelector("button"); - - expect(hostComponent.clicks).toBe(0); - - button.click(); - fixture.detectChanges(); - - expect(hostComponent.clicks).toBe(1); - }); - - it("can be disabled", () => { - const buttonEl = fixture.debugElement.query(By.css('[data-testid="disabled-button"]')); - const button = buttonEl.query(By.css("button")); +import { ButtonComponent } from "./button.component"; - expect(button).toBeTruthy(); - expect(button.nativeElement.disabled).toBe(true); +describe("`, { imports: [ButtonComponent] }); + const button = screen.getByRole("button", { name: /click me/i }); + expect(button).toBeDefined(); + expect(button).toHaveClass("fui-button"); + expect(button).not.toHaveClass("fui-button--secondary"); }); }); diff --git a/packages/angular/src/lib/components/button/button.component.ts b/packages/angular/src/lib/components/button/button.component.ts index d62a32e7..2cc1074a 100644 --- a/packages/angular/src/lib/components/button/button.component.ts +++ b/packages/angular/src/lib/components/button/button.component.ts @@ -14,24 +14,19 @@ * limitations under the License. */ -import { Component, Directive, ElementRef, Input } from "@angular/core"; +import { Component, HostBinding, input } from "@angular/core"; +import { buttonVariant, type ButtonVariant } from "@firebase-ui/styles"; @Component({ - selector: "fui-button", - template: ` - - `, + selector: "button[fui-button]", + template: ``, standalone: true, }) export class ButtonComponent { - @Input() type: "button" | "submit" | "reset" = "button"; - @Input() disabled: boolean = false; - @Input() variant: "primary" | "secondary" = "primary"; + variant = input(); + + @HostBinding("attr.class") + get getButtonClasses(): string { + return buttonVariant({ variant: this.variant() }); + } } diff --git a/packages/angular/src/lib/components/card/card.component.spec.ts b/packages/angular/src/lib/components/card/card.component.spec.ts index 5a267380..e893177a 100644 --- a/packages/angular/src/lib/components/card/card.component.spec.ts +++ b/packages/angular/src/lib/components/card/card.component.spec.ts @@ -57,7 +57,9 @@ class TestCardSubtitleHostComponent {} Card Title Card Subtitle -
Card Body Content
+ +
Card Body Content
+
`, standalone: true, diff --git a/packages/angular/src/lib/components/card/card.component.ts b/packages/angular/src/lib/components/card/card.component.ts index 313905ca..a1ef438c 100644 --- a/packages/angular/src/lib/components/card/card.component.ts +++ b/packages/angular/src/lib/components/card/card.component.ts @@ -23,7 +23,8 @@ import { CommonModule } from "@angular/common"; imports: [], template: `
- + +
`, }) @@ -33,12 +34,10 @@ export class CardComponent {} selector: "fui-card-header", standalone: true, imports: [CommonModule], - host: { - style: "display: block;", - }, template: `
- + +
`, }) @@ -67,3 +66,15 @@ export class CardTitleComponent {} `, }) export class CardSubtitleComponent {} + +@Component({ + selector: "fui-card-content", + standalone: true, + imports: [CommonModule], + template: ` +
+ +
+ `, +}) +export class CardContentComponent {} diff --git a/packages/angular/src/lib/components/country-selector/country-selector.component.ts b/packages/angular/src/lib/components/country-selector/country-selector.component.ts index b7701a0a..f4cf37c8 100644 --- a/packages/angular/src/lib/components/country-selector/country-selector.component.ts +++ b/packages/angular/src/lib/components/country-selector/country-selector.component.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { Component, computed, model } from "@angular/core"; import { CommonModule } from "@angular/common"; -import { CountryData, countryData } from "@firebase-ui/core"; +import { CountryCode, CountryData, countryData } from "@firebase-ui/core"; import { FormsModule } from "@angular/forms"; @Component({ @@ -24,14 +24,14 @@ import { FormsModule } from "@angular/forms"; standalone: true, imports: [CommonModule, FormsModule], template: ` -
+
- {{ value.emoji }} + {{ selected().emoji }}
- {{ value.dialCode }} + {{ selected().dialCode }} + + + + `, +}) +export class FormInputComponent { + field = injectField(); + label = input.required(); +} + +@Component({ + selector: "button[fui-form-action]", + standalone: true, + host: { + class: "fui-form__action", + type: "button", + }, + template: ` `, +}) +export class FormActionComponent {} + +@Component({ + selector: "fui-form-submit", + standalone: true, + imports: [ButtonComponent], + host: { + type: "submit", + }, + template: ` + + `, +}) +export class FormSubmitComponent { + class = input(); + state = input.required(); + + isSubmitting = computed(() => this.state().isSubmitting); +} + +@Component({ + selector: "fui-form-error-message", + standalone: true, + template: ` + @if (errorMessage()) { +
+ {{ errorMessage() }} +
+ } + `, +}) +export class FormErrorMessageComponent { + state = input.required(); + + errorMessage = computed(() => { + return this.state().errorMap?.onSubmit ? String(this.state().errorMap.onSubmit) : undefined; + }); +} diff --git a/packages/angular/src/lib/components/terms-and-privacy/terms-and-privacy.component.spec.ts b/packages/angular/src/lib/components/policies/policies.component.spec.ts similarity index 92% rename from packages/angular/src/lib/components/terms-and-privacy/terms-and-privacy.component.spec.ts rename to packages/angular/src/lib/components/policies/policies.component.spec.ts index de700a7f..ac2cdae5 100644 --- a/packages/angular/src/lib/components/terms-and-privacy/terms-and-privacy.component.spec.ts +++ b/packages/angular/src/lib/components/policies/policies.component.spec.ts @@ -18,8 +18,8 @@ import { TestBed } from "@angular/core/testing"; import { By } from "@angular/platform-browser"; import { BehaviorSubject } from "rxjs"; -import { FirebaseUI, FirebaseUIPolicies } from "../../provider"; -import { TermsAndPrivacyComponent } from "./terms-and-privacy.component"; +import { PoliciesComponent } from "./policies.component"; +import { getFirebaseUITestProviders } from "../../testing/test-helpers"; class MockFirebaseUI { private _termsText = new BehaviorSubject("Terms of Service"); @@ -60,11 +60,15 @@ function configureComponentTest({ const mockFirebaseUI = new MockFirebaseUI(); TestBed.configureTestingModule({ - imports: [TermsAndPrivacyComponent], + imports: [PoliciesComponent], providers: [ - { provide: FirebaseUI, useValue: mockFirebaseUI }, + ...getFirebaseUITestProviders(), { - provide: FirebaseUIPolicies, + provide: 'FIREBASE_UI_STORE', + useValue: mockFirebaseUI, + }, + { + provide: 'FIREBASE_UI_POLICIES', useValue: { termsOfServiceUrl: tosUrl, privacyPolicyUrl: privacyPolicyUrl, @@ -73,14 +77,14 @@ function configureComponentTest({ ], }).compileComponents(); - const fixture = TestBed.createComponent(TermsAndPrivacyComponent); + const fixture = TestBed.createComponent(PoliciesComponent); const component = fixture.componentInstance; return { fixture, component, mockFirebaseUI }; } -describe("TermsAndPrivacyComponent", () => { - it("renders component with terms and privacy links", async () => { +describe("PoliciesComponent", () => { + it("renders component with terms and privacy links", fakeAsync(() => { const { fixture } = configureComponentTest({ tosUrl: "https://example.com/terms", privacyPolicyUrl: "https://example.com/privacy", diff --git a/packages/angular/src/lib/components/policies/policies.component.ts b/packages/angular/src/lib/components/policies/policies.component.ts new file mode 100644 index 00000000..554d55af --- /dev/null +++ b/packages/angular/src/lib/components/policies/policies.component.ts @@ -0,0 +1,104 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, computed, Signal } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { injectPolicies, injectTranslation, injectUI } from "../../provider"; + +type PolicyPart = + | { type: "tos"; url: string; text: string } + | { type: "privacy"; url: string; text: string } + | { type: "text"; content: string }; + +@Component({ + selector: "fui-policies", + standalone: true, + imports: [CommonModule], + template: ` + @if (shouldShow()) { +
+ @for (part of policyParts(); track $index) { + @if (part.type === "tos") { + + {{ part.text }} + + } @else if (part.type === "privacy") { + + {{ part.text }} + + } @else { + {{ part.content }} + } + } +
+ } + `, +}) +export class PoliciesComponent { + private readonly ui = injectUI(); + private readonly policies = injectPolicies(); + + private readonly termsText = injectTranslation("labels", "termsOfService"); + private readonly privacyText = injectTranslation("labels", "privacyPolicy"); + private readonly templateText = injectTranslation("messages", "termsAndPrivacy"); + + private readonly tosUrl = this.policies?.termsOfServiceUrl; + private readonly privacyPolicyUrl = this.policies?.privacyPolicyUrl; + + readonly shouldShow = computed(() => this.policies !== null); + + readonly policyParts: Signal = computed(() => { + if (!this.shouldShow()) { + return []; + } + + const template = this.templateText(); + const parts = template.split(/({tos}|{privacy})/); + + return parts + .filter((part) => part.length > 0) + .map((part) => { + if (part === "{tos}" && this.tosUrl) { + return { + type: "tos" as const, + url: this.tosUrl, + text: this.termsText(), + }; + } + if (part === "{privacy}" && this.privacyPolicyUrl) { + return { + type: "privacy" as const, + url: this.privacyPolicyUrl, + text: this.privacyText(), + }; + } + return { + type: "text" as const, + content: part, + }; + }); + }); +} diff --git a/packages/angular/src/lib/components/terms-and-privacy/terms-and-privacy.component.ts b/packages/angular/src/lib/components/terms-and-privacy/terms-and-privacy.component.ts deleted file mode 100644 index 3cb6690e..00000000 --- a/packages/angular/src/lib/components/terms-and-privacy/terms-and-privacy.component.ts +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component, inject } from "@angular/core"; -import { CommonModule } from "@angular/common"; -import { FirebaseUI, FirebaseUIPolicies } from "../../provider"; -import { map } from "rxjs"; - -@Component({ - selector: "fui-terms-and-privacy", - standalone: true, - imports: [CommonModule], - template: ` - - `, -}) -export class TermsAndPrivacyComponent { - private ui = inject(FirebaseUI); - private policies = inject(FirebaseUIPolicies); - - tosUrl = this.policies.termsOfServiceUrl; - privacyPolicyUrl = this.policies.privacyPolicyUrl; - - get shouldShow(): boolean { - return !!(this.tosUrl || this.privacyPolicyUrl); - } - - termsText = this.ui.translation("labels", "termsOfService"); - privacyText = this.ui.translation("labels", "privacyPolicy"); - - parts = this.ui.translation("messages", "termsAndPrivacy").pipe( - map((text) => { - const parts = text.split(/({tos}|{privacy})/); - return parts.map((part) => { - if (part === "{tos}") return { type: "tos" }; - if (part === "{privacy}") return { type: "privacy" }; - return { type: "text", content: part }; - }); - }) - ); - - handleUrl(url: string) { - if (url) { - window.open(url, "_blank", "noopener,noreferrer"); - } - } -} diff --git a/packages/angular/src/lib/provider.ts b/packages/angular/src/lib/provider.ts index 4ed80951..ab1d9747 100644 --- a/packages/angular/src/lib/provider.ts +++ b/packages/angular/src/lib/provider.ts @@ -21,13 +21,23 @@ import { InjectionToken, Injectable, inject, + signal, + computed, + effect, + Signal, } from "@angular/core"; import { FirebaseApps } from "@angular/fire/app"; -import { type FirebaseUI as FirebaseUIType, getTranslation } from "@firebase-ui/core"; -import { Tail } from "../types"; -import { distinctUntilChanged, map, takeUntil } from "rxjs/operators"; -import { Observable, ReplaySubject } from "rxjs"; -import { Store } from "nanostores"; +import { + createEmailLinkAuthFormSchema, + createForgotPasswordAuthFormSchema, + createPhoneAuthFormSchema, + createSignInAuthFormSchema, + createSignUpAuthFormSchema, + FirebaseUIConfiguration, + type FirebaseUI as FirebaseUIType, + getTranslation, +} from "@firebase-ui/core"; +import { TranslationCategory, TranslationKey } from "@firebase-ui/translations"; const FIREBASE_UI_STORE = new InjectionToken("firebaseui.store"); const FIREBASE_UI_POLICIES = new InjectionToken("firebaseui.policies"); @@ -46,12 +56,11 @@ export function provideFirebaseUI(uiFactory: (apps: FirebaseApps) => FirebaseUIT useFactory: () => { const apps = inject(FirebaseApps); if (!apps || apps.length === 0) { - return null as any; + throw new Error("No Firebase apps found"); } return uiFactory(apps); }, }, - FirebaseUI, ]; return makeEnvironmentProviders(providers); @@ -63,53 +72,48 @@ export function provideFirebaseUIPolicies(factory: () => PolicyConfig) { return makeEnvironmentProviders(providers); } -@Injectable({ - providedIn: "root", -}) -export class FirebaseUI { - private store = inject(FIREBASE_UI_STORE); - private destroyed$: ReplaySubject = new ReplaySubject(1); - - config() { - return this.useStore(this.store); - } - - //TODO: This should be typed more specifically from the translations package - translation(...args: Tail) { - return this.config().pipe(map((config) => getTranslation(config, ...args))); - } - - useStore(store: Store | null): Observable { - if (!store) { - // Return an observable that emits a default value for SSR when store is not available - return new Observable((subscriber) => { - subscriber.next({} as T); - subscriber.complete(); - }); - } - return new Observable((sub) => { - sub.next(store.get()); - return store.subscribe((value) => sub.next(value)); - }).pipe(distinctUntilChanged(), takeUntil(this.destroyed$)); - } - - ngOnDestroy(): void { - this.destroyed$.next(); - this.destroyed$.complete(); - } +// Provides a signal with a subscription to the FirebaseUIConfiguration +export function injectUI() { + const store = inject(FIREBASE_UI_STORE); + const ui = signal(store.get()); + + effect(() => { + return store.subscribe(ui.set); + }); + + return ui.asReadonly(); } -@Injectable({ - providedIn: "root", -}) -export class FirebaseUIPolicies { - private policies = inject(FIREBASE_UI_POLICIES); +export function injectTranslation(category: T, key: TranslationKey) { + const ui = injectUI(); + return computed(() => getTranslation(ui(), category, key)); +} - get termsOfServiceUrl() { - return this.policies.termsOfServiceUrl; - } +export function injectSignInAuthFormSchema(): Signal> { + const ui = injectUI(); + return computed(() => createSignInAuthFormSchema(ui())); +} + +export function injectSignUpAuthFormSchema(): Signal> { + const ui = injectUI(); + return computed(() => createSignUpAuthFormSchema(ui())); +} + +export function injectForgotPasswordAuthFormSchema(): Signal> { + const ui = injectUI(); + return computed(() => createForgotPasswordAuthFormSchema(ui())); +} + +export function injectEmailLinkAuthFormSchema(): Signal> { + const ui = injectUI(); + return computed(() => createEmailLinkAuthFormSchema(ui())); +} + +export function injectPhoneAuthFormSchema(): Signal> { + const ui = injectUI(); + return computed(() => createPhoneAuthFormSchema(ui())); +} - get privacyPolicyUrl() { - return this.policies.privacyPolicyUrl; - } +export function injectPolicies(): PolicyConfig | null { + return inject(FIREBASE_UI_POLICIES, { optional: true }); } diff --git a/packages/angular/src/public-api.ts b/packages/angular/src/public-api.ts index 7e6716c4..f6bf0eac 100644 --- a/packages/angular/src/public-api.ts +++ b/packages/angular/src/public-api.ts @@ -14,13 +14,27 @@ * limitations under the License. */ +export { EmailLinkAuthFormComponent } from "./lib/auth/forms/email-link-auth-form/email-link-auth-form.component"; +export { ForgotPasswordAuthFormComponent } from "./lib/auth/forms/forgot-password-auth-form/forgot-password-auth-form.component"; +export { PhoneAuthFormComponent } from "./lib/auth/forms/phone-auth-form/phone-auth-form.component"; +export { SignInAuthFormComponent } from "./lib/auth/forms/sign-in-auth-form/sign-in-auth-form.component"; +export { SignUpAuthFormComponent } from "./lib/auth/forms/sign-up-auth-form/sign-up-auth-form.component"; + +export { GoogleSignInButtonComponent } from "./lib/auth/oauth/google-sign-in-button.component"; +export { OAuthButtonComponent } from "./lib/auth/oauth/oauth-button.component"; + export { EmailLinkAuthScreenComponent } from "./lib/auth/screens/email-link-auth-screen/email-link-auth-screen.component"; -export { SignInAuthScreenComponent } from "./lib/auth/screens/sign-in-auth-screen/sign-in-auth-screen.component"; +export { ForgotPasswordAuthScreenComponent } from "./lib/auth/screens/forgot-password-auth-screen/forgot-password-auth-screen.component"; +export { OAuthScreenComponent } from "./lib/auth/screens/oauth-screen/oauth-screen.component"; export { PhoneAuthScreenComponent } from "./lib/auth/screens/phone-auth-screen/phone-auth-screen.component"; +export { SignInAuthScreenComponent } from "./lib/auth/screens/sign-in-auth-screen/sign-in-auth-screen.component"; export { SignUpAuthScreenComponent } from "./lib/auth/screens/sign-up-auth-screen/sign-up-auth-screen.component"; -export { OAuthScreenComponent } from "./lib/auth/screens/oauth-screen/oauth-screen.component"; -export { PasswordResetScreenComponent } from "./lib/auth/screens/password-reset-screen/password-reset-screen.component"; -export { GoogleSignInButtonComponent } from "./lib/auth/oauth/google-sign-in-button.component"; + +export { ButtonComponent } from "./lib/components/button/button.component"; +export { CardComponent } from "./lib/components/card/card.component"; +export { CountrySelectorComponent } from "./lib/components/country-selector/country-selector.component"; +export { DividerComponent } from "./lib/components/divider/divider.component"; +export { PoliciesComponent } from "./lib/components/policies/policies.component"; // Provider export * from "./lib/provider"; diff --git a/packages/angular/src/test-setup.ts b/packages/angular/src/test-setup.ts deleted file mode 100644 index b2d8bcf1..00000000 --- a/packages/angular/src/test-setup.ts +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// This file is required by vitest.config.ts and sets up the Angular testing environment - -// Import Zone.js testing utilities first -import "zone.js"; -import "zone.js/testing"; - -// Import Angular testing utilities -import { getTestBed, TestBed } from "@angular/core/testing"; -import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing"; - -// Ensure Zone.js testing environment is properly configured -beforeEach(() => { - // Reset Zone.js state before each test - if (typeof Zone !== "undefined") { - Zone.current.fork({}).run(() => { - // Run each test in a fresh zone - }); - } -}); - -// Import Vitest utilities -import { expect, vi, afterEach, beforeEach } from "vitest"; -import * as matchers from "@testing-library/jest-dom/matchers"; - -// Extend Vitest's expect with jest-dom matchers -expect.extend(matchers); - -// Initialize the testing environment with Zone.js support -if (!TestBed.platform) { - TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { - teardown: { destroyAfterEach: false }, - }); -} - -// Reset TestBed after each test to prevent configuration conflicts -afterEach(() => { - TestBed.resetTestingModule(); -}); - -// Make Vitest globals available -declare global { - const spyOn: typeof vi.spyOn; - const pending: (reason?: string) => void; -} - -// Define global test utilities -globalThis.spyOn = (obj: any, method: string) => { - const spy = vi.spyOn(obj, method); - // Add Jasmine-compatible methods - spy.and = { - callFake: (fn: Function) => { - spy.mockImplementation(fn); - return spy; - }, - returnValue: (value: any) => { - spy.mockReturnValue(value); - return spy; - }, - callThrough: () => { - spy.mockImplementation((...args: any[]) => obj[method](...args)); - return spy; - }, - }; - spy.calls = { - reset: () => spy.mockClear(), - all: () => spy.mock.calls, - count: () => spy.mock.calls.length, - mostRecent: () => spy.mock.calls[spy.mock.calls.length - 1] || { args: [] }, - first: () => spy.mock.calls[0] || { args: [] }, - }; - return spy; -}; -globalThis.pending = (reason?: string) => { - throw new Error(`Test pending: ${reason || "No reason provided"}`); -}; - -// Mock global objects that might be needed for Firebase UI testing -Object.defineProperty(window, "signInWithEmailAndPassword", { - value: vi.fn(), - writable: true, - configurable: true, -}); - -Object.defineProperty(window, "createEmailFormSchema", { - value: vi.fn(), - writable: true, - configurable: true, -}); - -Object.defineProperty(window, "signInWithPopup", { - value: vi.fn(), - writable: true, - configurable: true, -}); - -Object.defineProperty(window, "signInWithRedirect", { - value: vi.fn(), - writable: true, - configurable: true, -}); - -Object.defineProperty(window, "signInWithPhoneNumber", { - value: vi.fn(), - writable: true, - configurable: true, -}); diff --git a/packages/angular/tsconfig.build.json b/packages/angular/tsconfig.build.json new file mode 100644 index 00000000..39da4c37 --- /dev/null +++ b/packages/angular/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "./node_modules/ng-packagr/src/lib/ts/conf/tsconfig.ngc.json", + "compilerOptions": { + "allowJs": true, + "module": "ESNext", + "moduleDetection": "force", + "moduleResolution": "Bundler" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true + }, + "include": ["src"] +} \ No newline at end of file diff --git a/packages/angular/tsconfig.json b/packages/angular/tsconfig.json new file mode 100644 index 00000000..73fbd1d6 --- /dev/null +++ b/packages/angular/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "moduleResolution": "Bundler", + "useDefineForClassFields": false, + "paths": { + "~/*": ["./src/*"], + "~/tests/*": ["./tests/*"], + "@firebase-ui/core": ["../core/src/index.ts"], + "@firebase-ui/styles": ["../styles/src/index.ts"] + } + }, + "include": ["src", "tests", "eslint.config.js", "vite.config.ts", "setup-test.ts"] +} \ No newline at end of file diff --git a/packages/angular/tsconfig.lib.json b/packages/angular/tsconfig.lib.json deleted file mode 100644 index de7d0629..00000000 --- a/packages/angular/tsconfig.lib.json +++ /dev/null @@ -1,18 +0,0 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/lib", - "declaration": true, - "declarationMap": true, - "inlineSources": true, - "types": [], - "baseUrl": ".", - "paths": { - "@firebase-ui/core": ["../core/src/index.ts"], - "@firebase-ui/translations": ["../translations/src/index.ts"] - } - }, - "exclude": ["**/*.spec.ts"] -} diff --git a/packages/angular/tsconfig.lib.prod.json b/packages/angular/tsconfig.lib.prod.json deleted file mode 100644 index 9215caac..00000000 --- a/packages/angular/tsconfig.lib.prod.json +++ /dev/null @@ -1,11 +0,0 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ -{ - "extends": "./tsconfig.lib.json", - "compilerOptions": { - "declarationMap": false - }, - "angularCompilerOptions": { - "compilationMode": "partial" - } -} diff --git a/packages/angular/tsconfig.spec.json b/packages/angular/tsconfig.spec.json index 38433371..2d41c266 100644 --- a/packages/angular/tsconfig.spec.json +++ b/packages/angular/tsconfig.spec.json @@ -1,23 +1,15 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { + "extends": "./tsconfig.build.json", "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["vitest/globals", "node", "@testing-library/jest-dom"], - "lib": ["es2018", "dom"], - "target": "es2018", - "module": "es2020", - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "skipLibCheck": true, - "strict": false, - "noImplicitAny": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "sourceMap": true, - "declaration": false + "outDir": "./out-tsc/spec", + "target": "es2016", + "types": ["vitest/globals", "node"], + "paths": { + "~/tests/*": ["./tests/*"], + "@firebase-ui/core": ["../core/src/index.ts"], + "@firebase-ui/styles": ["../styles/src/index.ts"] + } }, - "include": ["src/**/*.spec.ts", "src/**/*.d.ts", "src/**/*.ts"], - "files": ["src/test-setup.ts"] + "files": ["setup-test.ts"], + "include": ["tests/**/*.spec.ts", "tests/**/*.d.ts", "setup-test.ts"] } diff --git a/packages/angular/vite.config.ts b/packages/angular/vite.config.ts new file mode 100644 index 00000000..d4fd0912 --- /dev/null +++ b/packages/angular/vite.config.ts @@ -0,0 +1,41 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +const tsconfigPath = "tsconfig.spec.json"; + +export default defineConfig(({ mode }) => ({ + plugins: [ + tsconfigPaths({ projects: [tsconfigPath] }) + ], + test: { + name: "@firebase-ui/angular", + environment: "jsdom", + setupFiles: ["./setup-test.ts"], + typecheck: { enabled: false }, + globals: true, + restoreMocks: true, + include: ["src/**/*.{test,spec}.{ts,tsx}"], + exclude: ["node_modules", "dist", ".angular"], + pool: "threads", + threads: false + }, + define: { + "import.meta.vitest": mode !== "production", + }, +})); diff --git a/packages/angular/vitest.config.ts b/packages/angular/vitest.config.ts deleted file mode 100644 index 97ed14d1..00000000 --- a/packages/angular/vitest.config.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { defineConfig } from "vitest/config"; -import { resolve } from "path"; - -export default defineConfig({ - test: { - // Use jsdom environment for Angular component testing - environment: "jsdom", - // Include Angular test files - include: ["src/**/*.{test,spec}.{js,ts}"], - // Exclude build output and node_modules - exclude: ["node_modules/**/*", "dist/**/*"], - // Enable globals for Angular testing utilities - globals: true, - // Use the setup file for Angular testing environment - setupFiles: ["./src/test-setup.ts"], - // Mock modules - mockReset: false, - // Use tsconfig.spec.json for TypeScript - typecheck: { - enabled: true, - tsconfig: "./tsconfig.spec.json", - include: ["src/**/*.{ts}"], - }, - // Increase test timeout for Angular operations - testTimeout: 15000, - // Coverage configuration - coverage: { - provider: "v8", - reporter: ["text", "html"], - exclude: ["node_modules/**", "dist/**", "src/test-setup.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], - }, - // Environment variables for Angular testing - env: { - NODE_ENV: "test", - }, - // Define global test utilities - define: { - global: "globalThis", - }, - // Pool options for better Zone.js compatibility - pool: "forks", - poolOptions: { - forks: { - singleFork: true, - }, - }, - // Better isolation for Angular tests - isolate: true, - // Reset modules between tests - clearMocks: true, - restoreMocks: true, - }, - resolve: { - alias: { - "@": resolve(__dirname, "./src"), - }, - }, - define: { - global: "globalThis", - }, -}); diff --git a/packages/core/src/schemas.ts b/packages/core/src/schemas.ts index 4d90c034..2e2d16a1 100644 --- a/packages/core/src/schemas.ts +++ b/packages/core/src/schemas.ts @@ -26,7 +26,7 @@ export type AuthMode = "signIn" | "signUp"; export function createSignInAuthFormSchema(ui: FirebaseUIConfiguration) { return z.object({ email: z.email(getTranslation(ui, "errors", "invalidEmail")), - password: z.string().min(8, getTranslation(ui, "errors", "weakPassword")), + password: z.string().min(6, getTranslation(ui, "errors", "weakPassword")), }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf0bc239..a9c3b31c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,27 +39,12 @@ catalogs: '@angular/router': specifier: ^20.2.2 version: 20.3.0 - '@testing-library/jest-dom': - specifier: ^6.8.0 - version: 6.8.0 - '@testing-library/react': - specifier: ^16.3.0 - version: 16.3.0 '@types/jsdom': specifier: ^21.1.7 version: 21.1.7 '@types/node': specifier: ^24.3.1 version: 24.3.1 - '@types/react': - specifier: ^19.1.12 - version: 19.1.12 - '@types/react-dom': - specifier: ^19.1.9 - version: 19.1.9 - '@vitejs/plugin-react': - specifier: ^5.0.2 - version: 5.0.2 firebase: specifier: ^11.10.0 version: 11.10.0 @@ -72,12 +57,6 @@ catalogs: prettier: specifier: ^3.6.2 version: 3.6.2 - react: - specifier: ^19.1.1 - version: 19.1.1 - react-dom: - specifier: ^19.1.1 - version: 19.1.1 rimraf: specifier: ^6.0.1 version: 6.0.1 @@ -287,141 +266,7 @@ importers: version: 5.9.2 vitest: specifier: ^3.2.0 - version: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - - examples/nextjs: - dependencies: - '@firebase-ui/core': - specifier: workspace:* - version: link:../../packages/core - '@firebase-ui/react': - specifier: workspace:* - version: link:../../packages/react - '@firebase-ui/styles': - specifier: workspace:* - version: link:../../packages/styles - '@firebase-ui/translations': - specifier: workspace:* - version: link:../../packages/translations - firebase: - specifier: ^11.3.1 - version: 11.10.0 - next: - specifier: 15.1.7 - version: 15.1.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.92.1) - react: - specifier: ^19.0.0 - version: 19.1.1 - react-dom: - specifier: ^19.0.0 - version: 19.1.1(react@19.1.1) - server-only: - specifier: ^0.0.1 - version: 0.0.1 - devDependencies: - '@tailwindcss/postcss': - specifier: ^4.0.6 - version: 4.1.13 - '@types/node': - specifier: ^20 - version: 20.19.13 - '@types/react': - specifier: ^19 - version: 19.1.12 - '@types/react-dom': - specifier: ^19 - version: 19.1.9(@types/react@19.1.12) - '@typescript-eslint/eslint-plugin': - specifier: ^8.43.0 - version: 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - '@typescript-eslint/parser': - specifier: ^8.43.0 - version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - eslint: - specifier: ^9.22.0 - version: 9.35.0(jiti@2.5.1) - eslint-config-next: - specifier: ^15.1.7 - version: 15.5.4(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - postcss: - specifier: ^8.5.2 - version: 8.5.6 - postcss-load-config: - specifier: ^6.0.1 - version: 6.0.1(jiti@2.5.1)(postcss@8.5.6) - prettier: - specifier: ^3.1.1 - version: 3.6.2 - tailwindcss: - specifier: ^4.0.6 - version: 4.1.13 - typescript: - specifier: ^5 - version: 5.7.3 - - examples/react: - dependencies: - '@firebase-ui/core': - specifier: workspace:* - version: link:../../packages/core - '@firebase-ui/react': - specifier: workspace:* - version: link:../../packages/react - '@firebase-ui/styles': - specifier: workspace:* - version: link:../../packages/styles - '@firebase-ui/translations': - specifier: workspace:* - version: link:../../packages/translations - firebase: - specifier: ^11.6.0 - version: 11.10.0 - react: - specifier: ^19.0.0 - version: 19.1.1 - react-dom: - specifier: ^19.0.0 - version: 19.1.1(react@19.1.1) - react-router: - specifier: ^7.5.1 - version: 7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - devDependencies: - '@eslint/js': - specifier: ^9.22.0 - version: 9.35.0 - '@tailwindcss/vite': - specifier: ^4.1.4 - version: 4.1.13(vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1)) - '@types/react': - specifier: ^19.0.10 - version: 19.1.12 - '@types/react-dom': - specifier: ^19.0.4 - version: 19.1.9(@types/react@19.1.12) - '@vitejs/plugin-react': - specifier: ^4.3.4 - version: 4.7.0(vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1)) - eslint: - specifier: ^9.22.0 - version: 9.35.0(jiti@2.5.1) - eslint-plugin-react-hooks: - specifier: ^5.2.0 - version: 5.2.0(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-react-refresh: - specifier: ^0.4.19 - version: 0.4.20(eslint@9.35.0(jiti@2.5.1)) - globals: - specifier: ^16.0.0 - version: 16.4.0 - prettier: - specifier: ^3.1.1 - version: 3.6.2 - tailwindcss: - specifier: ^4.1.4 - version: 4.1.13 - vite: - specifier: ^6.3.1 - version: 6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + version: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) packages/angular: dependencies: @@ -432,8 +277,8 @@ importers: specifier: workspace:* version: link:../styles '@tanstack/angular-form': - specifier: ^1.1.0 - version: 1.19.5(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: ^1.23.1 + version: 1.23.4(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)) nanostores: specifier: 'catalog:' version: 1.0.1 @@ -441,9 +286,12 @@ importers: specifier: ^2.8.1 version: 2.8.1 devDependencies: + '@analogjs/vitest-angular': + specifier: ^1.21.1 + version: 1.21.1(@analogjs/vite-plugin-angular@1.21.1(@angular-devkit/build-angular@20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5))(@angular/build@20.3.0(db6b8e5e4e31d8907efeea6f24de2797)))(@angular-devkit/architect@0.2003.0(chokidar@4.0.3))(vitest@3.2.4) '@angular-devkit/build-angular': specifier: 'catalog:' - version: 20.3.0(723092ee53b9cea3223901f7a1da068e) + version: 20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5) '@angular/cli': specifier: 'catalog:' version: 20.3.0(@types/node@24.3.1)(chokidar@4.0.3) @@ -474,18 +322,15 @@ importers: '@angular/router': specifier: 'catalog:' version: 20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@testing-library/angular': + specifier: ^18.0.0 + version: 18.0.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/router@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2))(@testing-library/dom@10.4.1) '@testing-library/jest-dom': specifier: ^6.6.0 version: 6.8.0 '@types/node': specifier: 'catalog:' version: 24.3.1 - '@vitest/coverage-v8': - specifier: ^2.0.0 - version: 2.1.9(vitest@2.1.9) - '@vitest/ui': - specifier: ^2.0.0 - version: 2.1.9(vitest@2.1.9) firebase: specifier: 'catalog:' version: 11.10.0 @@ -502,8 +347,8 @@ importers: specifier: 'catalog:' version: 5.9.2 vitest: - specifier: ^2.0.0 - version: 2.1.9(@types/node@24.3.1)(@vitest/ui@2.1.9)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + specifier: 'catalog:' + version: 3.2.4(@types/node@24.3.1)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) zone.js: specifier: 'catalog:' version: 0.15.1 @@ -551,85 +396,6 @@ importers: specifier: 'catalog:' version: 3.4.1 - packages/react: - dependencies: - '@firebase-ui/core': - specifier: workspace:* - version: link:../core - '@firebase-ui/styles': - specifier: workspace:* - version: link:../styles - '@nanostores/react': - specifier: ^1.0.0 - version: 1.0.0(nanostores@1.0.1)(react@19.1.1) - '@radix-ui/react-slot': - specifier: ^1.2.3 - version: 1.2.3(@types/react@19.1.12)(react@19.1.1) - '@tanstack/react-form': - specifier: ^0.41.3 - version: 0.41.4(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) - clsx: - specifier: ^2.1.1 - version: 2.1.1 - tailwind-merge: - specifier: ^3.0.1 - version: 3.3.1 - zod: - specifier: 'catalog:' - version: 4.1.11 - devDependencies: - '@testing-library/jest-dom': - specifier: 'catalog:' - version: 6.8.0 - '@testing-library/react': - specifier: 'catalog:' - version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@types/jsdom': - specifier: 'catalog:' - version: 21.1.7 - '@types/node': - specifier: 'catalog:' - version: 24.3.1 - '@types/react': - specifier: 'catalog:' - version: 19.1.12 - '@types/react-dom': - specifier: 'catalog:' - version: 19.1.9(@types/react@19.1.12) - '@vitejs/plugin-react': - specifier: 'catalog:' - version: 5.0.2(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1)) - firebase: - specifier: 'catalog:' - version: 11.10.0 - jsdom: - specifier: 'catalog:' - version: 26.1.0 - nanostores: - specifier: 'catalog:' - version: 1.0.1 - react: - specifier: 'catalog:' - version: 19.1.1 - react-dom: - specifier: 'catalog:' - version: 19.1.1(react@19.1.1) - tsup: - specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.12(@types/node@24.3.1))(jiti@2.5.1)(postcss@8.5.6)(typescript@5.9.2) - typescript: - specifier: 'catalog:' - version: 5.9.2 - vite: - specifier: 'catalog:' - version: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - vitest: - specifier: 'catalog:' - version: 3.2.4(@types/node@24.3.1)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@26.1.0)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - vitest-tsconfig-paths: - specifier: 'catalog:' - version: 3.4.1 - packages/styles: dependencies: cva: @@ -742,6 +508,24 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@analogjs/vite-plugin-angular@1.21.1': + resolution: {integrity: sha512-rXDmhZz29y8HbUG11cgJ/c2gafL1sV4u0Z7IhG6X4rZ+MzRWyjAQdv9ZwPEvfkxDCJFKHNOjMG81Br8+iDcBew==} + peerDependencies: + '@angular-devkit/build-angular': ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 + '@angular/build': ^18.0.0 || ^19.0.0 || ^20.0.0 + peerDependenciesMeta: + '@angular-devkit/build-angular': + optional: true + '@angular/build': + optional: true + + '@analogjs/vitest-angular@1.21.1': + resolution: {integrity: sha512-hKL/ja//GvhnVkjz79BEqgSQIufLgyvH/08HpAPzYq14fRvG8Y+V2/5P0c2tFnlOouRyqU8ov7oSbg62jSeq5w==} + peerDependencies: + '@analogjs/vite-plugin-angular': '*' + '@angular-devkit/architect': '>=0.1500.0 < 0.2100.0' + vitest: ^1.3.1 || ^2.0.0 || ^3.0.0 + '@angular-devkit/architect@0.2003.0': resolution: {integrity: sha512-4poZyD6YXvjfHvu4fr/r+2d/BUYcGB5gj+zJiGalJY5oTSHFuDkfJMzo3kaUAhDMFjb6cNgh/64SiLyQOETNJA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} @@ -1390,18 +1174,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-source@7.27.1': - resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.4': resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} engines: {node: '>=6.9.0'} @@ -1495,10 +1267,6 @@ packages: resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -1511,9 +1279,6 @@ packages: resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -1566,204 +1331,102 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.25.9': resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.25.9': resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.25.9': resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.25.9': resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.25.9': resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.25.9': resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.25.9': resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.25.9': resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.25.9': resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.25.9': resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.25.9': resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.25.9': resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.25.9': resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.25.9': resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.25.9': resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.25.9': resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} @@ -1776,12 +1439,6 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} @@ -1794,12 +1451,6 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} @@ -1812,48 +1463,24 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.25.9': resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.25.9': resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.25.9': resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.25.9': resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} @@ -2133,128 +1760,23 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] + '@inquirer/checkbox@4.2.2': + resolution: {integrity: sha512-E+KExNurKcUJJdxmjglTl141EwxWyAHplvsYJQgSwXf8qiNWkTxTuCCqmhFEmbIXd4zLaGMfQFJ6WrZ7fSeV3g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@inquirer/checkbox@4.2.2': - resolution: {integrity: sha512-E+KExNurKcUJJdxmjglTl141EwxWyAHplvsYJQgSwXf8qiNWkTxTuCCqmhFEmbIXd4zLaGMfQFJ6WrZ7fSeV3g==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/confirm@5.1.14': - resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + '@inquirer/confirm@5.1.14': + resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true '@inquirer/confirm@5.1.16': resolution: {integrity: sha512-j1a5VstaK5KQy8Mu8cHmuQvN1Zc62TbLhjJxwHvKPPKEoowSF6h/0UdOpA9DNdWZ+9Inq73+puRq1df6OJ8Sag==} @@ -2544,13 +2066,6 @@ packages: cpu: [x64] os: [win32] - '@nanostores/react@1.0.0': - resolution: {integrity: sha512-eDduyNy+lbQJMg6XxZ/YssQqF6b4OXMFEZMYKPJCCmBevp1lg0g+4ZRi94qGHirMtsNfAWKNwsjOhC+q1gvC+A==} - engines: {node: ^20.0.0 || >=22.0.0} - peerDependencies: - nanostores: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^1.0.0 - react: '>=18.0.0' - '@napi-rs/nice-android-arm-eabi@1.1.1': resolution: {integrity: sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==} engines: {node: '>= 10'} @@ -2657,66 +2172,9 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@napi-rs/wasm-runtime@1.0.4': resolution: {integrity: sha512-+ZEtJPp8EF8h4kN6rLQECRor00H7jtDgBVtttIUoxuDkXLiQMaSBqju3LV/IEsMvqVG5pviUvR4jYhIA1xNm8w==} - '@next/env@15.1.7': - resolution: {integrity: sha512-d9jnRrkuOH7Mhi+LHav2XW91HOgTAWHxjMPkXMGBc9B2b7614P7kjt8tAplRvJpbSt4nbO1lugcT/kAaWzjlLQ==} - - '@next/eslint-plugin-next@15.5.4': - resolution: {integrity: sha512-SR1vhXNNg16T4zffhJ4TS7Xn7eq4NfKfcOsRwea7RIAHrjRpI9ALYbamqIJqkAhowLlERffiwk0FMvTLNdnVtw==} - - '@next/swc-darwin-arm64@15.1.7': - resolution: {integrity: sha512-hPFwzPJDpA8FGj7IKV3Yf1web3oz2YsR8du4amKw8d+jAOHfYHYFpMkoF6vgSY4W6vB29RtZEklK9ayinGiCmQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@15.1.7': - resolution: {integrity: sha512-2qoas+fO3OQKkU0PBUfwTiw/EYpN+kdAx62cePRyY1LqKtP09Vp5UcUntfZYajop5fDFTjSxCHfZVRxzi+9FYQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@15.1.7': - resolution: {integrity: sha512-sKLLwDX709mPdzxMnRIXLIT9zaX2w0GUlkLYQnKGoXeWUhcvpCrK+yevcwCJPdTdxZEUA0mOXGLdPsGkudGdnA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@15.1.7': - resolution: {integrity: sha512-zblK1OQbQWdC8fxdX4fpsHDw+VSpBPGEUX4PhSE9hkaWPrWoeIJn+baX53vbsbDRaDKd7bBNcXRovY1hEhFd7w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@15.1.7': - resolution: {integrity: sha512-GOzXutxuLvLHFDAPsMP2zDBMl1vfUHHpdNpFGhxu90jEzH6nNIgmtw/s1MDwpTOiM+MT5V8+I1hmVFeAUhkbgQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@15.1.7': - resolution: {integrity: sha512-WrZ7jBhR7ATW1z5iEQ0ZJfE2twCNSXbpCSaAunF3BKcVeHFADSI/AW1y5Xt3DzTqPF1FzQlwQTewqetAABhZRQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@15.1.7': - resolution: {integrity: sha512-LDnj1f3OVbou1BqvvXVqouJZKcwq++mV2F+oFHptToZtScIEnhNRJAhJzqAtTE2dB31qDYL45xJwrc+bLeKM2Q==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-x64-msvc@15.1.7': - resolution: {integrity: sha512-dC01f1quuf97viOfW05/K8XYv2iuBgAxJZl7mbCKEjMgdQl5JjAKJ0D2qMKZCgPWDeFbFT0Q0nYWwytEW0DWTQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@ngtools/webpack@20.3.0': resolution: {integrity: sha512-++WfrAHodBf0ZZlmjLY/s5N/6/kcJF97daFTQNUYyD0JbVcrnYaDC9+uBulg2ovUotpYR/jm259/qiDSFrBlRQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} @@ -2737,10 +2195,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nolyfill/is-core-module@1.0.39': - resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} - engines: {node: '>=12.4.0'} - '@npmcli/agent@3.0.0': resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2908,62 +2362,6 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@remix-run/node@2.17.0': - resolution: {integrity: sha512-ISy3N4peKB+Fo8ddh+mU6ki3HzQqLXwJxUrAtqxYxrBDM4Pwc7EvISrcQ4QasB6ORBknJeEZSBu69WDRhGzrjA==} - engines: {node: '>=18.0.0'} - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - - '@remix-run/router@1.23.0': - resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} - engines: {node: '>=14.0.0'} - - '@remix-run/server-runtime@2.17.0': - resolution: {integrity: sha512-X0zfGLgvukhuTIL0tdWKnlvHy4xUe7Z17iQ0KMQoITK0SkTZPSud/6cJCsKhPqC8kfdYT1GNFLJKRhHz7Aapmw==} - engines: {node: '>=18.0.0'} - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - - '@remix-run/web-blob@3.1.0': - resolution: {integrity: sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g==} - - '@remix-run/web-fetch@4.4.2': - resolution: {integrity: sha512-jgKfzA713/4kAW/oZ4bC3MoLWyjModOVDjFPNseVqcJKSafgIscrYL9G50SurEYLswPuoU3HzSbO0jQCMYWHhA==} - engines: {node: ^10.17 || >=12.3} - - '@remix-run/web-file@3.1.0': - resolution: {integrity: sha512-dW2MNGwoiEYhlspOAXFBasmLeYshyAyhIdrlXBi06Duex5tDr3ut2LFKVj7tyHLmn8nnNwFf1BjNbkQpygC2aQ==} - - '@remix-run/web-form-data@3.1.0': - resolution: {integrity: sha512-NdeohLMdrb+pHxMQ/Geuzdp0eqPbea+Ieo8M8Jx2lGC6TBHsgHzYcBvr0LyPdPVycNRDEpWpiDdCOdCryo3f9A==} - - '@remix-run/web-stream@1.1.0': - resolution: {integrity: sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==} - '@rolldown/binding-android-arm64@1.0.0-beta.32': resolution: {integrity: sha512-Gs+313LfR4Ka3hvifdag9r44WrdKQaohya7ZXUXzARF7yx0atzFlVZjsvxtKAw1Vmtr4hB/RjUD1jf73SW7zDw==} cpu: [arm64] @@ -3034,15 +2432,9 @@ packages: cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rolldown/pluginutils@1.0.0-beta.32': resolution: {integrity: sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==} - '@rolldown/pluginutils@1.0.0-beta.34': - resolution: {integrity: sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==} - '@rollup/plugin-json@6.1.0': resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} @@ -3171,12 +2563,6 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - - '@rushstack/eslint-patch@1.12.0': - resolution: {integrity: sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==} - '@rushstack/node-core-library@5.14.0': resolution: {integrity: sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==} peerDependencies: @@ -3230,12 +2616,6 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@tailwindcss/node@4.1.13': resolution: {integrity: sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==} @@ -3324,18 +2704,13 @@ packages: '@tailwindcss/postcss@4.1.13': resolution: {integrity: sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==} - '@tailwindcss/vite@4.1.13': - resolution: {integrity: sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==} - peerDependencies: - vite: ^5.2.0 || ^6 || ^7 - '@tanstack/angular-form@0.42.1': resolution: {integrity: sha512-7uMewhfDrCo8X+CZSMGBu6xifeIhvGsDpwZeXrUYDrS7ZzVzUysFLuZPbGLylmWTVBRhdK85A6xXjoiBiAYP2A==} peerDependencies: '@angular/core': '>=19.0.0' - '@tanstack/angular-form@1.19.5': - resolution: {integrity: sha512-oqgl3lEyuTqASroxmYv+O9U0GViIIqaX/WfNeKjR0pwbNeZ3hW8we6CJklQN44qtZzoC8RQTaZTCNBc5+zmBWQ==} + '@tanstack/angular-form@1.23.4': + resolution: {integrity: sha512-4nqQCAZkdpkK8LuFLzZZOqKBGEO+Ozm4nf+J1QThbKWKIstbmp4xi0nSwdt+Qd4SZneqoBQa4tKEFPjNjZM7JA==} peerDependencies: '@angular/core': '>=19.0.0' @@ -3345,33 +2720,37 @@ packages: '@angular/common': '>=19.0.0' '@angular/core': '>=19.0.0' - '@tanstack/form-core@0.41.4': - resolution: {integrity: sha512-XZJtN7mWJmi3apsc2J+GpWbcsXbv0pWBkZKP47ZW1QD/2Tj1UWsM6JjcaAkzIlrBdaoEFYmrHToLKr/Ddk8BVg==} + '@tanstack/angular-store@0.7.7': + resolution: {integrity: sha512-Lhtn4wY+U9r7f8FjD+lgwH2RIIssmoM0D8CcEcVMd5LGBG0EbzxatsWYMbg5Ezd1JqWCXktbevjF30tF4ndDPw==} + peerDependencies: + '@angular/common': '>=19.0.0' + '@angular/core': '>=19.0.0' + + '@tanstack/devtools-event-client@0.3.2': + resolution: {integrity: sha512-gkvph/YMCFUfAca75EsJBJnhbKitDGix7vdEcT/3lAV+eyGSv+uECYG43apVQN4yLJKnV6mzcNvGzOhDhb72gg==} + engines: {node: '>=18'} '@tanstack/form-core@0.42.1': resolution: {integrity: sha512-jTU0jyHqFceujdtPNv3jPVej1dTqBwa8TYdIyWB5BCwRVUBZEp1PiYEBkC9r92xu5fMpBiKc+JKud3eeVjuMiA==} - '@tanstack/form-core@1.19.5': - resolution: {integrity: sha512-MhHk/f3fOVhm2kHAEOg+yJklSY84C3qSwwYwAUzAQw6i5ZQquBdB2aYzg89FFXNkhmLcEl9hJCqRZVw4NHzDMQ==} - - '@tanstack/react-form@0.41.4': - resolution: {integrity: sha512-uIfIDZJNqR1dLW03TNByK/woyKd2jfXIrEBq6DPJbqupqyfYXTDo5TMd/7koTYLO4dgTM5wd+2v3uBX3M2bRaA==} - peerDependencies: - '@tanstack/start': ^1.43.13 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@tanstack/start': - optional: true - - '@tanstack/react-store@0.7.5': - resolution: {integrity: sha512-A+WZtEnHZpvbKXm8qR+xndNKywBLez2KKKKEQc7w0Qs45GvY1LpRI3BTZNmELwEVim8+Apf99iEDH2J+MUIzlQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/form-core@1.24.0': + resolution: {integrity: sha512-bMxl7cwBt6WYiajImYN/0fjYRuiTAW7+3C/zPHNyxLTc6U5voPGr1lF1RGzf3U5Q8qtvHyGF0dVuISMLqb31yQ==} '@tanstack/store@0.7.5': resolution: {integrity: sha512-qd/OjkjaFRKqKU4Yjipaen/EOB9MyEg6Wr9fW103RBPACf1ZcKhbhcu2S5mj5IgdPib6xFIgCUti/mKVkl+fRw==} + '@tanstack/store@0.7.7': + resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==} + + '@testing-library/angular@18.0.0': + resolution: {integrity: sha512-0seNMa4ql2I3VD7CtnI9i4sFgxEgRES+EtGid8H4MTuOK/dlj457mVk8tWdFjPQPC/cPromcUNw0is1ogO3DSA==} + peerDependencies: + '@angular/common': '>= 20.0.0' + '@angular/core': '>= 20.0.0' + '@angular/platform-browser': '>= 20.0.0' + '@angular/router': '>= 20.0.0' + '@testing-library/dom': ^10.0.0 + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -3380,20 +2759,8 @@ packages: resolution: {integrity: sha512-WgXcWzVM6idy5JaftTVC8Vs83NKRmGJz4Hqs4oyOuO2J4r/y79vvKZsb+CaGyCSEbUPI6OsewfPd0G1A0/TUZQ==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - '@testing-library/react@16.3.0': - resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} - engines: {node: '>=18'} - peerDependencies: - '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 || ^19.0.0 - '@types/react-dom': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@ts-morph/common@0.22.0': + resolution: {integrity: sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==} '@tufjs/canonical-json@2.0.0': resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} @@ -3412,18 +2779,6 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -3439,9 +2794,6 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} @@ -3496,14 +2848,6 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@19.1.9': - resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} - peerDependencies: - '@types/react': ^19.0.0 - - '@types/react@19.1.12': - resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} - '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} @@ -3522,6 +2866,9 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} @@ -3584,128 +2931,12 @@ packages: resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} - cpu: [x64] - os: [win32] - '@vitejs/plugin-basic-ssl@2.1.0': resolution: {integrity: sha512-dOxxrhgyDIEUADhb/8OlV9JIqYLgos03YorAueTIeOUskLJSEsfwCByjbu98ctXitUN3znXKp0bYD/WHSudCeA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} peerDependencies: vite: ^6.0.0 || ^7.0.0 - '@vitejs/plugin-react@4.7.0': - resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - - '@vitejs/plugin-react@5.0.2': - resolution: {integrity: sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - - '@vitest/coverage-v8@2.1.9': - resolution: {integrity: sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==} - peerDependencies: - '@vitest/browser': 2.1.9 - vitest: 2.1.9 - peerDependenciesMeta: - '@vitest/browser': - optional: true - '@vitest/coverage-v8@3.2.4': resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} peerDependencies: @@ -3715,23 +2946,9 @@ packages: '@vitest/browser': optional: true - '@vitest/expect@2.1.9': - resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} - '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/mocker@2.1.9': - resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - '@vitest/mocker@3.2.4': resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: @@ -3743,43 +2960,23 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} - '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/runner@2.1.9': - resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} - '@vitest/runner@3.2.4': resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/snapshot@2.1.9': - resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} - '@vitest/snapshot@3.2.4': resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/spy@2.1.9': - resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} - '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - '@vitest/ui@2.1.9': - resolution: {integrity: sha512-izzd2zmnk8Nl5ECYkW27328RbQ1nKvkm6Bb5DAaz1Gk59EbLkiCMa6OLT0NoaAYTjOFS6N+SMYW1nh4/9ljPiw==} - peerDependencies: - vitest: 2.1.9 - '@vitest/ui@3.2.4': resolution: {integrity: sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==} peerDependencies: vitest: 3.2.4 - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} - '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} @@ -3812,9 +3009,6 @@ packages: '@vue/shared@3.5.21': resolution: {integrity: sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==} - '@web3-storage/multipart-parser@1.0.0': - resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==} - '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -3869,17 +3063,10 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@zxing/text-encoding@0.9.0': - resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} - abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -4036,10 +3223,6 @@ packages: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - array.prototype.flat@1.3.3: resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} engines: {node: '>= 0.4'} @@ -4060,9 +3243,6 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-types-flow@0.0.8: - resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@0.3.5: resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} @@ -4084,14 +3264,6 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} - engines: {node: '>=4'} - - axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - babel-loader@10.0.0: resolution: {integrity: sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==} engines: {node: ^18.20.0 || ^20.10.0 || >=22.0.0} @@ -4177,10 +3349,6 @@ packages: peerDependencies: esbuild: '>=0.18' - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -4267,9 +3435,6 @@ packages: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -4289,6 +3454,9 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + code-block-writer@12.0.0: + resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -4296,13 +3464,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -4389,10 +3550,6 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} - engines: {node: '>=18'} - copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} @@ -4456,9 +3613,6 @@ packages: resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} engines: {node: '>=18'} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - custom-event@1.0.1: resolution: {integrity: sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==} @@ -4470,13 +3624,6 @@ packages: typescript: optional: true - damerau-levenshtein@1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - - data-uri-to-buffer@3.0.1: - resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==} - engines: {node: '>= 6'} - data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -4508,14 +3655,6 @@ packages: supports-color: optional: true - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -4537,9 +3676,6 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - decode-formdata@0.8.0: - resolution: {integrity: sha512-iUzDgnWsw5ToSkFY7VPFA5Gfph6ROoOxOB7Ybna4miUSzLZ4KaSJk6IAB2AdW6+C9vCVWhjjNA4gjT6wF3eZHQ==} - deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -4755,11 +3891,6 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.25.9: resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} @@ -4776,74 +3907,12 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-next@15.5.4: - resolution: {integrity: sha512-BzgVVuT3kfJes8i2GHenC1SRJ+W3BTML11lAOYFOOPzrk2xp66jBOAGEFRw+3LkYCln5UzvFsLhojrshb5Zfaw==} - peerDependencies: - eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 - typescript: '>=3.3.1' - peerDependenciesMeta: - typescript: - optional: true - eslint-config-prettier@9.1.2: resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-import-resolver-typescript@3.10.1: - resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-jsx-a11y@6.10.2: - resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@5.5.4: resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4864,11 +3933,6 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-refresh@0.4.20: - resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} - peerDependencies: - eslint: '>=8.40' - eslint-plugin-react@7.37.5: resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} @@ -4935,10 +3999,6 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -4990,10 +4050,6 @@ packages: fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - engines: {node: '>=8.6.0'} - fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -5169,9 +4225,6 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -5209,10 +4262,6 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.4.0: - resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} - engines: {node: '>=18'} - globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -5421,10 +4470,6 @@ packages: resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} engines: {node: '>= 10'} - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} - engines: {node: '>= 0.4'} - is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -5432,9 +4477,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -5451,9 +4493,6 @@ packages: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} - is-bun-module@2.0.0: - resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -5773,13 +4812,6 @@ packages: kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - language-subtag-registry@0.3.23: - resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} - - language-tags@1.0.9: - resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} - engines: {node: '>=0.10'} - launch-editor@2.11.1: resolution: {integrity: sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg==} @@ -6149,10 +5181,6 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - mrmime@1.0.1: - resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} - engines: {node: '>=10'} - mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -6197,11 +5225,6 @@ packages: resolution: {integrity: sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw==} engines: {node: ^20.0.0 || >=22.0.0} - napi-postinstall@0.3.3: - resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -6225,27 +5248,6 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next@15.1.7: - resolution: {integrity: sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - ng-packagr@20.3.0: resolution: {integrity: sha512-hwPZNeV/6C3pWojK70AHxe6uk1rz2bzoe+WdH+GIWouUcyXrjYQjOFyLfOGD0ia9D+yWVzjsi4CKVK/dQFDQ6Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -6356,10 +5358,6 @@ packages: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - object.values@1.2.1: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} @@ -6489,9 +5487,6 @@ packages: path-to-regexp@8.3.0: resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -6605,10 +5600,6 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -6695,35 +5686,12 @@ packages: resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} engines: {node: '>= 0.10'} - react-dom@19.1.1: - resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} - peerDependencies: - react: ^19.1.1 - react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react-refresh@0.17.0: - resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} - engines: {node: '>=0.10.0'} - - react-router@7.8.2: - resolution: {integrity: sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==} - engines: {node: '>=20.0.0'} - peerDependencies: - react: '>=18' - react-dom: '>=18' - peerDependenciesMeta: - react-dom: - optional: true - - react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} - engines: {node: '>=0.10.0'} - readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -6797,9 +5765,6 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve-url-loader@5.0.0: resolution: {integrity: sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==} engines: {node: '>=12'} @@ -6943,9 +5908,6 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} - schema-utils@4.3.2: resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} engines: {node: '>= 10.13.0'} @@ -6998,12 +5960,6 @@ packages: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} - server-only@0.0.1: - resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} - - set-cookie-parser@2.7.1: - resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -7026,10 +5982,6 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -7069,9 +6021,6 @@ packages: resolution: {integrity: sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==} engines: {node: ^18.17.0 || >=20.5.0} - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - sirv@3.0.2: resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} @@ -7166,9 +6115,6 @@ packages: resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} engines: {node: ^18.17.0 || >=20.5.0} - stable-hash@0.0.5: - resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -7195,17 +6141,10 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - stream-slice@0.1.2: - resolution: {integrity: sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==} - streamroller@3.1.5: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -7222,10 +6161,6 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string.prototype.includes@2.0.1: - resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} - engines: {node: '>= 0.4'} - string.prototype.matchall@4.0.12: resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} engines: {node: '>= 0.4'} @@ -7274,19 +6209,6 @@ packages: strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - styled-jsx@5.1.6: - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -7311,9 +6233,6 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} - tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - tailwindcss@4.1.13: resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} @@ -7388,18 +6307,10 @@ packages: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} - engines: {node: '>=14.0.0'} - tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} - engines: {node: '>=14.0.0'} - tinyspy@4.0.3: resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} @@ -7457,6 +6368,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-morph@21.0.1: + resolution: {integrity: sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg==} + tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -7499,9 +6413,6 @@ packages: resolution: {integrity: sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==} engines: {node: ^18.17.0 || >=20.5.0} - turbo-stream@2.4.1: - resolution: {integrity: sha512-v8kOJXpG3WoTN/+at8vK7erSzo6nW6CIaeOvNOkHQVDajfz1ZVeSxCbc6tOH4hrGZW7VUCV0TOXd8CPzYnYkrw==} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -7537,11 +6448,6 @@ packages: typed-assert@1.0.9: resolution: {integrity: sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==} - typescript@5.7.3: - resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -7569,10 +6475,6 @@ packages: undici-types@7.10.0: resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} - undici@6.21.3: - resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} - engines: {node: '>=18.17'} - unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} @@ -7597,6 +6499,9 @@ packages: resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} engines: {node: ^18.17.0 || >=20.5.0} + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -7609,9 +6514,6 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -7621,17 +6523,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - use-sync-external-store@1.5.0: - resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} @@ -7651,10 +6545,11 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite-node@2.1.9: - resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} @@ -7678,37 +6573,6 @@ packages: vite: optional: true - vite@5.4.20: - resolution: {integrity: sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - vite@6.3.6: resolution: {integrity: sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -7832,31 +6696,6 @@ packages: vitest-tsconfig-paths@3.4.1: resolution: {integrity: sha512-CnRpA/jcqgZfnkk0yvwFW92UmIpf03wX/wLiQBNWAcOG7nv6Sdz3GsPESAMEqbVy8kHBoWB3XeNamu6PUrFZLA==} - vitest@2.1.9: - resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.9 - '@vitest/ui': 2.1.9 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -7906,13 +6745,6 @@ packages: weak-lru-cache@1.2.2: resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} - web-encoding@1.1.5: - resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==} - - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - web-vitals@4.2.4: resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} @@ -8247,6 +7079,20 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + '@analogjs/vite-plugin-angular@1.21.1(@angular-devkit/build-angular@20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5))(@angular/build@20.3.0(db6b8e5e4e31d8907efeea6f24de2797))': + dependencies: + ts-morph: 21.0.1 + vfile: 6.0.3 + optionalDependencies: + '@angular-devkit/build-angular': 20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5) + '@angular/build': 20.3.0(db6b8e5e4e31d8907efeea6f24de2797) + + '@analogjs/vitest-angular@1.21.1(@analogjs/vite-plugin-angular@1.21.1(@angular-devkit/build-angular@20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5))(@angular/build@20.3.0(db6b8e5e4e31d8907efeea6f24de2797)))(@angular-devkit/architect@0.2003.0(chokidar@4.0.3))(vitest@3.2.4)': + dependencies: + '@analogjs/vite-plugin-angular': 1.21.1(@angular-devkit/build-angular@20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5))(@angular/build@20.3.0(db6b8e5e4e31d8907efeea6f24de2797)) + '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) + vitest: 3.2.4(@types/node@24.3.1)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + '@angular-devkit/architect@0.2003.0(chokidar@4.0.3)': dependencies: '@angular-devkit/core': 20.3.0(chokidar@4.0.3) @@ -8254,13 +7100,13 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@20.3.0(723092ee53b9cea3223901f7a1da068e)': + '@angular-devkit/build-angular@20.3.0(84ed8a12f7a51e3d21a80d3f63eeb9b5)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.2003.0(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2(esbuild@0.25.9)) + '@angular-devkit/build-webpack': 0.2003.0(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9)) '@angular-devkit/core': 20.3.0(chokidar@4.0.3) - '@angular/build': 20.3.0(04b5738b93aadee3f8353f28e6721709) + '@angular/build': 20.3.0(b9e63081279d3d1c86f5313ab8a37b0a) '@angular/compiler-cli': 20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2) '@babel/core': 7.28.3 '@babel/generator': 7.28.3 @@ -8308,8 +7154,8 @@ snapshots: tslib: 2.8.1 typescript: 5.9.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-middleware: 7.4.2(webpack@5.101.2) - webpack-dev-server: 5.2.2(webpack@5.101.2) + webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) + webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.101.2(esbuild@0.25.9)) optionalDependencies: @@ -8348,7 +7194,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.2003.0(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2(esbuild@0.25.9)) + '@angular-devkit/build-webpack': 0.2003.0(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9)) '@angular-devkit/core': 20.3.0(chokidar@4.0.3) '@angular/build': 20.3.0(86ec70b3c2a2b389224b227d5e72fbc3) '@angular/compiler-cli': 20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2) @@ -8398,8 +7244,8 @@ snapshots: tslib: 2.8.1 typescript: 5.9.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-middleware: 7.4.2(webpack@5.101.2) - webpack-dev-server: 5.2.2(webpack@5.101.2) + webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) + webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.101.2(esbuild@0.25.9)) optionalDependencies: @@ -8434,12 +7280,12 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-webpack@0.2003.0(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2(esbuild@0.25.9))': + '@angular-devkit/build-webpack@0.2003.0(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9))': dependencies: '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) rxjs: 7.8.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-server: 5.2.2(webpack@5.101.2) + webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) transitivePeerDependencies: - chokidar @@ -8469,7 +7315,7 @@ snapshots: '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 - '@angular/build@20.3.0(04b5738b93aadee3f8353f28e6721709)': + '@angular/build@20.3.0(86ec70b3c2a2b389224b227d5e72fbc3)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) @@ -8478,8 +7324,8 @@ snapshots: '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 - '@inquirer/confirm': 5.1.14(@types/node@24.3.1) - '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) + '@inquirer/confirm': 5.1.14(@types/node@20.19.13) + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) beasties: 0.3.5 browserslist: 4.25.4 esbuild: 0.25.9 @@ -8499,7 +7345,7 @@ snapshots: tinyglobby: 0.2.14 tslib: 2.8.1 typescript: 5.9.2 - vite: 7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + vite: 7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) watchpack: 2.4.4 optionalDependencies: '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) @@ -8512,7 +7358,7 @@ snapshots: ng-packagr: 20.3.0(@angular/compiler-cli@20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2))(tailwindcss@4.1.13)(tslib@2.8.1)(typescript@5.9.2) postcss: 8.5.6 tailwindcss: 4.1.13 - vitest: 2.1.9(@types/node@24.3.1)(@vitest/ui@2.1.9)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + vitest: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) transitivePeerDependencies: - '@types/node' - chokidar @@ -8526,7 +7372,7 @@ snapshots: - tsx - yaml - '@angular/build@20.3.0(86ec70b3c2a2b389224b227d5e72fbc3)': + '@angular/build@20.3.0(b9e63081279d3d1c86f5313ab8a37b0a)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) @@ -8535,8 +7381,8 @@ snapshots: '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 - '@inquirer/confirm': 5.1.14(@types/node@20.19.13) - '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) + '@inquirer/confirm': 5.1.14(@types/node@24.3.1) + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) beasties: 0.3.5 browserslist: 4.25.4 esbuild: 0.25.9 @@ -8556,7 +7402,7 @@ snapshots: tinyglobby: 0.2.14 tslib: 2.8.1 typescript: 5.9.2 - vite: 7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + vite: 7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) watchpack: 2.4.4 optionalDependencies: '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) @@ -8569,7 +7415,7 @@ snapshots: ng-packagr: 20.3.0(@angular/compiler-cli@20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2))(tailwindcss@4.1.13)(tslib@2.8.1)(typescript@5.9.2) postcss: 8.5.6 tailwindcss: 4.1.13 - vitest: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + vitest: 3.2.4(@types/node@24.3.1)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) transitivePeerDependencies: - '@types/node' - chokidar @@ -8583,33 +7429,91 @@ snapshots: - tsx - yaml - '@angular/cli@20.3.0(@types/node@20.19.13)(chokidar@4.0.3)': + '@angular/build@20.3.0(db6b8e5e4e31d8907efeea6f24de2797)': dependencies: + '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) - '@angular-devkit/core': 20.3.0(chokidar@4.0.3) - '@angular-devkit/schematics': 20.3.0(chokidar@4.0.3) - '@inquirer/prompts': 7.8.2(@types/node@20.19.13) - '@listr2/prompt-adapter-inquirer': 3.0.1(@inquirer/prompts@7.8.2(@types/node@20.19.13))(@types/node@20.19.13)(listr2@9.0.1) - '@modelcontextprotocol/sdk': 1.17.3 - '@schematics/angular': 20.3.0(chokidar@4.0.3) - '@yarnpkg/lockfile': 1.1.0 - algoliasearch: 5.35.0 - ini: 5.0.0 + '@angular/compiler': 20.3.0 + '@angular/compiler-cli': 20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2) + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@inquirer/confirm': 5.1.14(@types/node@24.3.1) + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) + beasties: 0.3.5 + browserslist: 4.25.4 + esbuild: 0.25.9 + https-proxy-agent: 7.0.6 + istanbul-lib-instrument: 6.0.3 jsonc-parser: 3.3.1 listr2: 9.0.1 - npm-package-arg: 13.0.0 - pacote: 21.0.0 - resolve: 1.22.10 + magic-string: 0.30.17 + mrmime: 2.0.1 + parse5-html-rewriting-stream: 8.0.0 + picomatch: 4.0.3 + piscina: 5.1.3 + rolldown: 1.0.0-beta.32 + sass: 1.90.0 semver: 7.7.2 - yargs: 18.0.0 - zod: 3.25.76 - transitivePeerDependencies: - - '@types/node' - - chokidar - - supports-color - - '@angular/cli@20.3.0(@types/node@24.3.1)(chokidar@4.0.3)': - dependencies: + source-map-support: 0.5.21 + tinyglobby: 0.2.14 + tslib: 2.8.1 + typescript: 5.9.2 + vite: 7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + watchpack: 2.4.4 + optionalDependencies: + '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 20.3.0(@angular/animations@20.3.2(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/platform-server': 20.3.2(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@20.3.0)(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@angular/ssr': 20.3.3(29f6c088f2c72629bcb82378a45b895e) + karma: 6.4.4 + less: 4.4.1 + lmdb: 3.4.2 + ng-packagr: 20.3.0(@angular/compiler-cli@20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2))(tailwindcss@4.1.13)(tslib@2.8.1)(typescript@5.9.2) + postcss: 8.5.6 + tailwindcss: 4.1.13 + vitest: 3.2.4(@types/node@24.3.1)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + transitivePeerDependencies: + - '@types/node' + - chokidar + - jiti + - lightningcss + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + optional: true + + '@angular/cli@20.3.0(@types/node@20.19.13)(chokidar@4.0.3)': + dependencies: + '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) + '@angular-devkit/core': 20.3.0(chokidar@4.0.3) + '@angular-devkit/schematics': 20.3.0(chokidar@4.0.3) + '@inquirer/prompts': 7.8.2(@types/node@20.19.13) + '@listr2/prompt-adapter-inquirer': 3.0.1(@inquirer/prompts@7.8.2(@types/node@20.19.13))(@types/node@20.19.13)(listr2@9.0.1) + '@modelcontextprotocol/sdk': 1.17.3 + '@schematics/angular': 20.3.0(chokidar@4.0.3) + '@yarnpkg/lockfile': 1.1.0 + algoliasearch: 5.35.0 + ini: 5.0.0 + jsonc-parser: 3.3.1 + listr2: 9.0.1 + npm-package-arg: 13.0.0 + pacote: 21.0.0 + resolve: 1.22.10 + semver: 7.7.2 + yargs: 18.0.0 + zod: 3.25.76 + transitivePeerDependencies: + - '@types/node' + - chokidar + - supports-color + + '@angular/cli@20.3.0(@types/node@24.3.1)(chokidar@4.0.3)': + dependencies: '@angular-devkit/architect': 0.2003.0(chokidar@4.0.3) '@angular-devkit/core': 20.3.0(chokidar@4.0.3) '@angular-devkit/schematics': 20.3.0(chokidar@4.0.3) @@ -9256,16 +8160,6 @@ snapshots: '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.3)': dependencies: '@babel/core': 7.28.3 @@ -9430,8 +8324,6 @@ snapshots: '@babel/runtime@7.28.3': {} - '@babel/runtime@7.28.4': {} - '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -9455,8 +8347,6 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@bcoe/v8-coverage@0.2.3': {} - '@bcoe/v8-coverage@1.0.2': {} '@colors/colors@1.5.0': @@ -9502,150 +8392,81 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.21.5': - optional: true - '@esbuild/aix-ppc64@0.25.9': optional: true - '@esbuild/android-arm64@0.21.5': - optional: true - '@esbuild/android-arm64@0.25.9': optional: true - '@esbuild/android-arm@0.21.5': - optional: true - '@esbuild/android-arm@0.25.9': optional: true - '@esbuild/android-x64@0.21.5': - optional: true - '@esbuild/android-x64@0.25.9': optional: true - '@esbuild/darwin-arm64@0.21.5': - optional: true - '@esbuild/darwin-arm64@0.25.9': optional: true - '@esbuild/darwin-x64@0.21.5': - optional: true - '@esbuild/darwin-x64@0.25.9': optional: true - '@esbuild/freebsd-arm64@0.21.5': - optional: true - '@esbuild/freebsd-arm64@0.25.9': optional: true - '@esbuild/freebsd-x64@0.21.5': - optional: true - '@esbuild/freebsd-x64@0.25.9': optional: true - '@esbuild/linux-arm64@0.21.5': - optional: true - '@esbuild/linux-arm64@0.25.9': optional: true - '@esbuild/linux-arm@0.21.5': - optional: true - '@esbuild/linux-arm@0.25.9': optional: true - '@esbuild/linux-ia32@0.21.5': - optional: true - '@esbuild/linux-ia32@0.25.9': optional: true - '@esbuild/linux-loong64@0.21.5': - optional: true - '@esbuild/linux-loong64@0.25.9': optional: true - '@esbuild/linux-mips64el@0.21.5': - optional: true - '@esbuild/linux-mips64el@0.25.9': optional: true - '@esbuild/linux-ppc64@0.21.5': - optional: true - '@esbuild/linux-ppc64@0.25.9': optional: true - '@esbuild/linux-riscv64@0.21.5': - optional: true - '@esbuild/linux-riscv64@0.25.9': optional: true - '@esbuild/linux-s390x@0.21.5': - optional: true - '@esbuild/linux-s390x@0.25.9': optional: true - '@esbuild/linux-x64@0.21.5': - optional: true - '@esbuild/linux-x64@0.25.9': optional: true '@esbuild/netbsd-arm64@0.25.9': optional: true - '@esbuild/netbsd-x64@0.21.5': - optional: true - '@esbuild/netbsd-x64@0.25.9': optional: true '@esbuild/openbsd-arm64@0.25.9': optional: true - '@esbuild/openbsd-x64@0.21.5': - optional: true - '@esbuild/openbsd-x64@0.25.9': optional: true '@esbuild/openharmony-arm64@0.25.9': optional: true - '@esbuild/sunos-x64@0.21.5': - optional: true - '@esbuild/sunos-x64@0.25.9': optional: true - '@esbuild/win32-arm64@0.21.5': - optional: true - '@esbuild/win32-arm64@0.25.9': optional: true - '@esbuild/win32-ia32@0.21.5': - optional: true - '@esbuild/win32-ia32@0.25.9': optional: true - '@esbuild/win32-x64@0.21.5': - optional: true - '@esbuild/win32-x64@0.25.9': optional: true @@ -10034,81 +8855,6 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@img/sharp-darwin-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 - optional: true - - '@img/sharp-darwin-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.0.5': - optional: true - - '@img/sharp-libvips-linux-s390x@1.0.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - optional: true - - '@img/sharp-linux-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 - optional: true - - '@img/sharp-linux-arm@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 - optional: true - - '@img/sharp-linux-s390x@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 - optional: true - - '@img/sharp-linux-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - optional: true - - '@img/sharp-wasm32@0.33.5': - dependencies: - '@emnapi/runtime': 1.5.0 - optional: true - - '@img/sharp-win32-ia32@0.33.5': - optional: true - - '@img/sharp-win32-x64@0.33.5': - optional: true - '@inquirer/checkbox@4.2.2(@types/node@20.19.13)': dependencies: '@inquirer/core': 10.2.0(@types/node@20.19.13) @@ -10556,11 +9302,6 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': optional: true - '@nanostores/react@1.0.0(nanostores@1.0.1)(react@19.1.1)': - dependencies: - nanostores: 1.0.1 - react: 19.1.1 - '@napi-rs/nice-android-arm-eabi@1.1.1': optional: true @@ -10633,13 +9374,6 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.10.0 - optional: true - '@napi-rs/wasm-runtime@1.0.4': dependencies: '@emnapi/core': 1.5.0 @@ -10647,36 +9381,6 @@ snapshots: '@tybys/wasm-util': 0.10.0 optional: true - '@next/env@15.1.7': {} - - '@next/eslint-plugin-next@15.5.4': - dependencies: - fast-glob: 3.3.1 - - '@next/swc-darwin-arm64@15.1.7': - optional: true - - '@next/swc-darwin-x64@15.1.7': - optional: true - - '@next/swc-linux-arm64-gnu@15.1.7': - optional: true - - '@next/swc-linux-arm64-musl@15.1.7': - optional: true - - '@next/swc-linux-x64-gnu@15.1.7': - optional: true - - '@next/swc-linux-x64-musl@15.1.7': - optional: true - - '@next/swc-win32-arm64-msvc@15.1.7': - optional: true - - '@next/swc-win32-x64-msvc@15.1.7': - optional: true - '@ngtools/webpack@20.3.0(@angular/compiler-cli@20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9))': dependencies: '@angular/compiler-cli': 20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2) @@ -10695,8 +9399,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nolyfill/is-core-module@1.0.39': {} - '@npmcli/agent@3.0.0': dependencies: agent-base: 7.1.4 @@ -10851,73 +9553,6 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.12)(react@19.1.1)': - dependencies: - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.12 - - '@radix-ui/react-slot@1.2.3(@types/react@19.1.12)(react@19.1.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.12)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.12 - - '@remix-run/node@2.17.0(typescript@5.9.2)': - dependencies: - '@remix-run/server-runtime': 2.17.0(typescript@5.9.2) - '@remix-run/web-fetch': 4.4.2 - '@web3-storage/multipart-parser': 1.0.0 - cookie-signature: 1.2.2 - source-map-support: 0.5.21 - stream-slice: 0.1.2 - undici: 6.21.3 - optionalDependencies: - typescript: 5.9.2 - - '@remix-run/router@1.23.0': {} - - '@remix-run/server-runtime@2.17.0(typescript@5.9.2)': - dependencies: - '@remix-run/router': 1.23.0 - '@types/cookie': 0.6.0 - '@web3-storage/multipart-parser': 1.0.0 - cookie: 0.7.2 - set-cookie-parser: 2.7.1 - source-map: 0.7.6 - turbo-stream: 2.4.1 - optionalDependencies: - typescript: 5.9.2 - - '@remix-run/web-blob@3.1.0': - dependencies: - '@remix-run/web-stream': 1.1.0 - web-encoding: 1.1.5 - - '@remix-run/web-fetch@4.4.2': - dependencies: - '@remix-run/web-blob': 3.1.0 - '@remix-run/web-file': 3.1.0 - '@remix-run/web-form-data': 3.1.0 - '@remix-run/web-stream': 1.1.0 - '@web3-storage/multipart-parser': 1.0.0 - abort-controller: 3.0.0 - data-uri-to-buffer: 3.0.1 - mrmime: 1.0.1 - - '@remix-run/web-file@3.1.0': - dependencies: - '@remix-run/web-blob': 3.1.0 - - '@remix-run/web-form-data@3.1.0': - dependencies: - web-encoding: 1.1.5 - - '@remix-run/web-stream@1.1.0': - dependencies: - web-streams-polyfill: 3.3.3 - '@rolldown/binding-android-arm64@1.0.0-beta.32': optional: true @@ -10962,12 +9597,8 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.0.0-beta.32': optional: true - '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rolldown/pluginutils@1.0.0-beta.32': {} - '@rolldown/pluginutils@1.0.0-beta.34': {} - '@rollup/plugin-json@6.1.0(rollup@4.50.1)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.50.1) @@ -11051,10 +9682,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - '@rtsao/scc@1.1.0': {} - - '@rushstack/eslint-patch@1.12.0': {} - '@rushstack/node-core-library@5.14.0(@types/node@24.3.1)': dependencies: ajv: 8.13.0 @@ -11132,12 +9759,6 @@ snapshots: '@socket.io/component-emitter@3.1.2': optional: true - '@swc/counter@0.1.3': {} - - '@swc/helpers@0.5.15': - dependencies: - tslib: 2.8.1 - '@tailwindcss/node@4.1.13': dependencies: '@jridgewell/remapping': 2.3.5 @@ -11210,13 +9831,6 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.13 - '@tailwindcss/vite@4.1.13(vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1))': - dependencies: - '@tailwindcss/node': 4.1.13 - '@tailwindcss/oxide': 4.1.13 - tailwindcss: 4.1.13 - vite: 6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - '@tanstack/angular-form@0.42.1(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) @@ -11226,11 +9840,11 @@ snapshots: transitivePeerDependencies: - '@angular/common' - '@tanstack/angular-form@1.19.5(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))': + '@tanstack/angular-form@1.23.4(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) - '@tanstack/angular-store': 0.7.5(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)) - '@tanstack/form-core': 1.19.5 + '@tanstack/angular-store': 0.7.7(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@tanstack/form-core': 1.24.0 tslib: 2.8.1 transitivePeerDependencies: - '@angular/common' @@ -11242,42 +9856,41 @@ snapshots: '@tanstack/store': 0.7.5 tslib: 2.8.1 - '@tanstack/form-core@0.41.4': + '@tanstack/angular-store@0.7.7(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@tanstack/store': 0.7.5 + '@angular/common': 20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@tanstack/store': 0.7.7 + tslib: 2.8.1 + + '@tanstack/devtools-event-client@0.3.2': {} '@tanstack/form-core@0.42.1': dependencies: '@tanstack/store': 0.7.5 - '@tanstack/form-core@1.19.5': + '@tanstack/form-core@1.24.0': dependencies: - '@tanstack/store': 0.7.5 + '@tanstack/devtools-event-client': 0.3.2 + '@tanstack/store': 0.7.7 - '@tanstack/react-form@0.41.4(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)': - dependencies: - '@remix-run/node': 2.17.0(typescript@5.9.2) - '@tanstack/form-core': 0.41.4 - '@tanstack/react-store': 0.7.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - decode-formdata: 0.8.0 - react: 19.1.1 - transitivePeerDependencies: - - react-dom - - typescript + '@tanstack/store@0.7.5': {} - '@tanstack/react-store@0.7.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@tanstack/store': 0.7.5 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - use-sync-external-store: 1.5.0(react@19.1.1) + '@tanstack/store@0.7.7': {} - '@tanstack/store@0.7.5': {} + '@testing-library/angular@18.0.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/router@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2))(@testing-library/dom@10.4.1)': + dependencies: + '@angular/common': 20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 20.3.0(@angular/animations@20.3.2(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/router': 20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.0(@angular/common@20.3.0(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.0(@angular/compiler@20.3.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@testing-library/dom': 10.4.1 + tslib: 2.8.1 '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.3 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -11294,15 +9907,12 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@ts-morph/common@0.22.0': dependencies: - '@babel/runtime': 7.28.4 - '@testing-library/dom': 10.4.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.12 - '@types/react-dom': 19.1.9(@types/react@19.1.12) + fast-glob: 3.3.3 + minimatch: 9.0.5 + mkdirp: 3.0.1 + path-browserify: 1.0.1 '@tufjs/canonical-json@2.0.0': {} @@ -11320,27 +9930,6 @@ snapshots: '@types/aria-query@5.0.4': {} - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 - - '@types/babel__generator@7.27.0': - dependencies: - '@babel/types': 7.28.4 - - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - - '@types/babel__traverse@7.28.0': - dependencies: - '@babel/types': 7.28.4 - '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 @@ -11363,8 +9952,6 @@ snapshots: dependencies: '@types/node': 20.19.13 - '@types/cookie@0.6.0': {} - '@types/cors@2.8.19': dependencies: '@types/node': 20.19.13 @@ -11432,14 +10019,6 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.9(@types/react@19.1.12)': - dependencies: - '@types/react': 19.1.12 - - '@types/react@19.1.12': - dependencies: - csstype: 3.1.3 - '@types/retry@0.12.2': {} '@types/send@0.17.5': @@ -11463,27 +10042,12 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/unist@3.0.3': {} + '@types/ws@8.18.1': dependencies: '@types/node': 20.19.13 - '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - '@typescript-eslint/scope-manager': 8.43.0 - '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.43.0 - eslint: 9.35.0(jiti@2.5.1) - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.7.3) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -11501,18 +10065,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.43.0 - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.43.0 - debug: 4.4.1 - eslint: 9.35.0(jiti@2.5.1) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.43.0 @@ -11525,15 +10077,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.43.0(typescript@5.7.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.7.3) - '@typescript-eslint/types': 8.43.0 - debug: 4.4.1 - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/project-service@8.43.0(typescript@5.9.2)': dependencies: '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) @@ -11548,26 +10091,10 @@ snapshots: '@typescript-eslint/types': 8.43.0 '@typescript-eslint/visitor-keys': 8.43.0 - '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.7.3)': - dependencies: - typescript: 5.7.3 - '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)': - dependencies: - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3) - '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - debug: 4.4.1 - eslint: 9.35.0(jiti@2.5.1) - ts-api-utils: 2.1.0(typescript@5.7.3) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.43.0 @@ -11582,22 +10109,6 @@ snapshots: '@typescript-eslint/types@8.43.0': {} - '@typescript-eslint/typescript-estree@8.43.0(typescript@5.7.3)': - dependencies: - '@typescript-eslint/project-service': 8.43.0(typescript@5.7.3) - '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.7.3) - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/visitor-keys': 8.43.0 - debug: 4.4.1 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.7.3) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)': dependencies: '@typescript-eslint/project-service': 8.43.0(typescript@5.9.2) @@ -11614,17 +10125,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) - '@typescript-eslint/scope-manager': 8.43.0 - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3) - eslint: 9.35.0(jiti@2.5.1) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) @@ -11641,65 +10141,6 @@ snapshots: '@typescript-eslint/types': 8.43.0 eslint-visitor-keys: 4.2.1 - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - optional: true - - '@unrs/resolver-binding-android-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true - '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1))': dependencies: vite: 7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) @@ -11708,47 +10149,10 @@ snapshots: dependencies: vite: 7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) - '@vitejs/plugin-react@4.7.0(vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1))': - dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) - '@rolldown/pluginutils': 1.0.0-beta.27 - '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - transitivePeerDependencies: - - supports-color - - '@vitejs/plugin-react@5.0.2(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1))': + '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1))': dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) - '@rolldown/pluginutils': 1.0.0-beta.34 - '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - transitivePeerDependencies: - - supports-color - - '@vitest/coverage-v8@2.1.9(vitest@2.1.9)': - dependencies: - '@ampproject/remapping': 2.3.0 - '@bcoe/v8-coverage': 0.2.3 - debug: 4.4.1 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.2.0 - magic-string: 0.30.19 - magicast: 0.3.5 - std-env: 3.9.0 - test-exclude: 7.0.1 - tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@24.3.1)(@vitest/ui@2.1.9)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) - transitivePeerDependencies: - - supports-color + vite: 7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + optional: true '@vitest/coverage-v8@3.2.4(vitest@3.2.4)': dependencies: @@ -11765,17 +10169,10 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + vitest: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) transitivePeerDependencies: - supports-color - '@vitest/expect@2.1.9': - dependencies: - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - tinyrainbow: 1.2.0 - '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.2 @@ -11784,13 +10181,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@2.1.9(vite@5.4.20(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1))': + '@vitest/mocker@3.2.4(vite@6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1))': dependencies: - '@vitest/spy': 2.1.9 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 5.4.20(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + vite: 6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) '@vitest/mocker@3.2.4(vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1))': dependencies: @@ -11800,56 +10197,26 @@ snapshots: optionalDependencies: vite: 6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - '@vitest/pretty-format@2.1.9': - dependencies: - tinyrainbow: 1.2.0 - '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@2.1.9': - dependencies: - '@vitest/utils': 2.1.9 - pathe: 1.1.2 - '@vitest/runner@3.2.4': dependencies: '@vitest/utils': 3.2.4 pathe: 2.0.3 strip-literal: 3.0.0 - '@vitest/snapshot@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - magic-string: 0.30.19 - pathe: 1.1.2 - '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 magic-string: 0.30.19 pathe: 2.0.3 - '@vitest/spy@2.1.9': - dependencies: - tinyspy: 3.0.2 - '@vitest/spy@3.2.4': dependencies: tinyspy: 4.0.3 - '@vitest/ui@2.1.9(vitest@2.1.9)': - dependencies: - '@vitest/utils': 2.1.9 - fflate: 0.8.2 - flatted: 3.3.3 - pathe: 1.1.2 - sirv: 3.0.2 - tinyglobby: 0.2.15 - tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@24.3.1)(@vitest/ui@2.1.9)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) - '@vitest/ui@3.2.4(vitest@3.2.4)': dependencies: '@vitest/utils': 3.2.4 @@ -11859,13 +10226,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - - '@vitest/utils@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - loupe: 3.2.1 - tinyrainbow: 1.2.0 + vitest: 3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) '@vitest/utils@3.2.4': dependencies: @@ -11918,8 +10279,6 @@ snapshots: '@vue/shared@3.5.21': {} - '@web3-storage/multipart-parser@1.0.0': {} - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -12002,14 +10361,7 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@zxing/text-encoding@0.9.0': - optional: true - - abbrev@3.0.1: {} - - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 + abbrev@3.0.1: {} accepts@1.3.8: dependencies: @@ -12178,16 +10530,6 @@ snapshots: es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - array.prototype.flat@1.3.3: dependencies: call-bind: 1.0.8 @@ -12222,8 +10564,6 @@ snapshots: assertion-error@2.0.1: {} - ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@0.3.5: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -12248,10 +10588,6 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.10.3: {} - - axobject-query@4.1.0: {} - babel-loader@10.0.0(@babel/core@7.28.3)(webpack@5.101.2(esbuild@0.25.9)): dependencies: '@babel/core': 7.28.3 @@ -12373,10 +10709,6 @@ snapshots: esbuild: 0.25.9 load-tsconfig: 0.2.5 - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - bytes@3.1.2: {} cac@6.7.14: {} @@ -12471,8 +10803,6 @@ snapshots: cli-width@4.1.0: {} - client-only@0.0.1: {} - cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -12500,24 +10830,14 @@ snapshots: clsx@2.1.1: {} + code-block-writer@12.0.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - optional: true - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - optional: true - colorette@2.0.20: {} combined-stream@1.0.8: @@ -12592,8 +10912,6 @@ snapshots: cookie@0.7.2: {} - cookie@1.0.2: {} - copy-anything@2.0.6: dependencies: is-what: 3.14.1 @@ -12665,8 +10983,6 @@ snapshots: '@asamuzakjp/css-color': 3.2.0 rrweb-cssom: 0.8.0 - csstype@3.1.3: {} - custom-event@1.0.1: optional: true @@ -12676,10 +10992,6 @@ snapshots: optionalDependencies: typescript: 5.9.2 - damerau-levenshtein@1.0.8: {} - - data-uri-to-buffer@3.0.1: {} - data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -12712,10 +11024,6 @@ snapshots: dependencies: ms: 2.0.0 - debug@3.2.7: - dependencies: - ms: 2.1.3 - debug@4.3.7: dependencies: ms: 2.1.3 @@ -12727,8 +11035,6 @@ snapshots: decimal.js@10.6.0: {} - decode-formdata@0.8.0: {} - deep-eql@5.0.2: {} deep-is@0.1.4: {} @@ -13000,32 +11306,6 @@ snapshots: esbuild-wasm@0.25.9: {} - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - esbuild@0.25.9: optionalDependencies: '@esbuild/aix-ppc64': 0.25.9 @@ -13061,112 +11341,10 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@15.5.4(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3): - dependencies: - '@next/eslint-plugin-next': 15.5.4 - '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - eslint: 9.35.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-react: 7.37.5(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.35.0(jiti@2.5.1)) - optionalDependencies: - typescript: 5.7.3 - transitivePeerDependencies: - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - eslint-config-prettier@9.1.2(eslint@9.35.0(jiti@2.5.1)): dependencies: eslint: 9.35.0(jiti@2.5.1) - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 9.35.0(jiti@2.5.1) - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.15 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - eslint: 9.35.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.35.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-jsx-a11y@6.10.2(eslint@9.35.0(jiti@2.5.1)): - dependencies: - aria-query: 5.3.2 - array-includes: 3.1.9 - array.prototype.flatmap: 1.3.3 - ast-types-flow: 0.0.8 - axe-core: 4.10.3 - axobject-query: 4.1.0 - damerau-levenshtein: 1.0.8 - emoji-regex: 9.2.2 - eslint: 9.35.0(jiti@2.5.1) - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - language-tags: 1.0.9 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - safe-regex-test: 1.1.0 - string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@9.1.2(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2): dependencies: eslint: 9.35.0(jiti@2.5.1) @@ -13181,10 +11359,6 @@ snapshots: dependencies: eslint: 9.35.0(jiti@2.5.1) - eslint-plugin-react-refresh@0.4.20(eslint@9.35.0(jiti@2.5.1)): - dependencies: - eslint: 9.35.0(jiti@2.5.1) - eslint-plugin-react@7.37.5(eslint@9.35.0(jiti@2.5.1)): dependencies: array-includes: 3.1.9 @@ -13291,8 +11465,6 @@ snapshots: etag@1.8.1: {} - event-target-shim@5.0.1: {} - eventemitter3@4.0.7: {} eventemitter3@5.0.1: {} @@ -13390,14 +11562,6 @@ snapshots: fast-diff@1.3.0: {} - fast-glob@3.3.1: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -13629,10 +11793,6 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.10.1: - dependencies: - resolve-pkg-maps: 1.0.0 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -13679,8 +11839,6 @@ snapshots: globals@14.0.0: {} - globals@16.4.0: {} - globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -13886,11 +12044,6 @@ snapshots: ipaddr.js@2.2.0: {} - is-arguments@1.2.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -13899,9 +12052,6 @@ snapshots: is-arrayish@0.2.1: {} - is-arrayish@0.3.2: - optional: true - is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -13923,10 +12073,6 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-bun-module@2.0.0: - dependencies: - semver: 7.7.2 - is-callable@1.2.7: {} is-core-module@2.16.1: @@ -14280,12 +12426,6 @@ snapshots: kolorist@1.8.0: {} - language-subtag-registry@0.3.23: {} - - language-tags@1.0.9: - dependencies: - language-subtag-registry: 0.3.23 - launch-editor@2.11.1: dependencies: picocolors: 1.1.1 @@ -14659,8 +12799,6 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.1 - mrmime@1.0.1: {} - mrmime@2.0.1: {} ms@2.0.0: {} @@ -14705,8 +12843,6 @@ snapshots: nanostores@1.0.1: {} - napi-postinstall@0.3.3: {} - natural-compare@1.4.0: {} needle@3.3.1: @@ -14723,32 +12859,6 @@ snapshots: neo-async@2.6.2: {} - next@15.1.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.92.1): - dependencies: - '@next/env': 15.1.7 - '@swc/counter': 0.1.3 - '@swc/helpers': 0.5.15 - busboy: 1.6.0 - caniuse-lite: 1.0.30001741 - postcss: 8.4.31 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - styled-jsx: 5.1.6(react@19.1.1) - optionalDependencies: - '@next/swc-darwin-arm64': 15.1.7 - '@next/swc-darwin-x64': 15.1.7 - '@next/swc-linux-arm64-gnu': 15.1.7 - '@next/swc-linux-arm64-musl': 15.1.7 - '@next/swc-linux-x64-gnu': 15.1.7 - '@next/swc-linux-x64-musl': 15.1.7 - '@next/swc-win32-arm64-msvc': 15.1.7 - '@next/swc-win32-x64-msvc': 15.1.7 - sass: 1.92.1 - sharp: 0.33.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - ng-packagr@20.3.0(@angular/compiler-cli@20.3.0(@angular/compiler@20.3.0)(typescript@5.9.2))(tailwindcss@4.1.13)(tslib@2.8.1)(typescript@5.9.2): dependencies: '@ampproject/remapping': 2.3.0 @@ -14900,12 +13010,6 @@ snapshots: es-abstract: 1.24.0 es-object-atoms: 1.1.1 - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - object.values@1.2.1: dependencies: call-bind: 1.0.8 @@ -15069,8 +13173,6 @@ snapshots: path-to-regexp@8.3.0: {} - pathe@1.1.2: {} - pathe@2.0.3: {} pathval@2.0.1: {} @@ -15158,12 +13260,6 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.31: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -15262,27 +13358,10 @@ snapshots: iconv-lite: 0.7.0 unpipe: 1.0.0 - react-dom@19.1.1(react@19.1.1): - dependencies: - react: 19.1.1 - scheduler: 0.26.0 - react-is@16.13.1: {} react-is@17.0.2: {} - react-refresh@0.17.0: {} - - react-router@7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): - dependencies: - cookie: 1.0.2 - react: 19.1.1 - set-cookie-parser: 2.7.1 - optionalDependencies: - react-dom: 19.1.1(react@19.1.1) - - react@19.1.1: {} - readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -15373,8 +13452,6 @@ snapshots: resolve-from@5.0.0: {} - resolve-pkg-maps@1.0.0: {} - resolve-url-loader@5.0.0: dependencies: adjust-sourcemap-loader: 4.0.0 @@ -15559,8 +13636,6 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.26.0: {} - schema-utils@4.3.2: dependencies: '@types/json-schema': 7.0.15 @@ -15654,10 +13729,6 @@ snapshots: transitivePeerDependencies: - supports-color - server-only@0.0.1: {} - - set-cookie-parser@2.7.1: {} - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -15688,33 +13759,6 @@ snapshots: dependencies: kind-of: 6.0.3 - sharp@0.33.5: - dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 - optional: true - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -15766,11 +13810,6 @@ snapshots: transitivePeerDependencies: - supports-color - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - optional: true - sirv@3.0.2: dependencies: '@polka/url': 1.0.0-next.29 @@ -15905,8 +13944,6 @@ snapshots: dependencies: minipass: 7.1.2 - stable-hash@0.0.5: {} - stackback@0.0.2: {} statuses@1.5.0: {} @@ -15924,8 +13961,6 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - stream-slice@0.1.2: {} - streamroller@3.1.5: dependencies: date-format: 4.0.14 @@ -15935,8 +13970,6 @@ snapshots: - supports-color optional: true - streamsearch@1.1.0: {} - string-argv@0.3.2: {} string-width@4.2.3: @@ -15957,12 +13990,6 @@ snapshots: get-east-asian-width: 1.4.0 strip-ansi: 7.1.2 - string.prototype.includes@2.0.1: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - string.prototype.matchall@4.0.12: dependencies: call-bind: 1.0.8 @@ -16035,11 +14062,6 @@ snapshots: dependencies: js-tokens: 9.0.1 - styled-jsx@5.1.6(react@19.1.1): - dependencies: - client-only: 0.0.1 - react: 19.1.1 - sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -16066,8 +14088,6 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 - tailwind-merge@3.3.1: {} - tailwindcss@4.1.13: {} tapable@2.2.3: {} @@ -16144,12 +14164,8 @@ snapshots: tinypool@1.1.1: {} - tinyrainbow@1.2.0: {} - tinyrainbow@2.0.0: {} - tinyspy@3.0.2: {} - tinyspy@4.0.3: {} tldts-core@6.1.86: {} @@ -16187,16 +14203,17 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.7.3): - dependencies: - typescript: 5.7.3 - ts-api-utils@2.1.0(typescript@5.9.2): dependencies: typescript: 5.9.2 ts-interface-checker@0.1.13: {} + ts-morph@21.0.1: + dependencies: + '@ts-morph/common': 0.22.0 + code-block-writer: 12.0.0 + tsconfck@3.1.6(typescript@5.9.2): optionalDependencies: typescript: 5.9.2 @@ -16249,8 +14266,6 @@ snapshots: transitivePeerDependencies: - supports-color - turbo-stream@2.4.1: {} - type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -16303,8 +14318,6 @@ snapshots: typed-assert@1.0.9: {} - typescript@5.7.3: {} - typescript@5.8.2: {} typescript@5.9.2: {} @@ -16325,8 +14338,6 @@ snapshots: undici-types@7.10.0: {} - undici@6.21.3: {} - unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: @@ -16346,6 +14357,10 @@ snapshots: dependencies: imurmurhash: 0.1.4 + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + universalify@0.1.2: optional: true @@ -16353,30 +14368,6 @@ snapshots: unpipe@1.0.0: {} - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.3 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - update-browserslist-db@1.1.3(browserslist@4.25.4): dependencies: browserslist: 4.25.4 @@ -16387,20 +14378,8 @@ snapshots: dependencies: punycode: 2.3.1 - use-sync-external-store@1.5.0(react@19.1.1): - dependencies: - react: 19.1.1 - util-deprecate@1.0.2: {} - util@0.12.5: - dependencies: - inherits: 2.0.4 - is-arguments: 1.2.0 - is-generator-function: 1.1.0 - is-typed-array: 1.1.15 - which-typed-array: 1.1.19 - utils-merge@1.0.1: {} uuid@8.3.2: {} @@ -16414,31 +14393,23 @@ snapshots: vary@1.1.2: {} - vite-node@2.1.9(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): + vfile-message@4.0.3: dependencies: - cac: 6.7.14 - debug: 4.4.1 - es-module-lexer: 1.7.0 - pathe: 1.1.2 - vite: 5.4.20(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): + vite-node@3.2.4(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + vite: 6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) transitivePeerDependencies: - '@types/node' - jiti @@ -16504,20 +14475,24 @@ snapshots: - supports-color - typescript - vite@5.4.20(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): + vite@6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): dependencies: - esbuild: 0.21.5 + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.50.1 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.1 + '@types/node': 20.19.13 fsevents: 2.3.3 + jiti: 2.5.1 less: 4.4.0 lightningcss: 1.30.1 sass: 1.90.0 terser: 5.43.1 - vite@6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): + vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -16526,7 +14501,7 @@ snapshots: rollup: 4.50.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.13 + '@types/node': 24.3.1 fsevents: 2.3.3 jiti: 2.5.1 less: 4.4.1 @@ -16534,7 +14509,7 @@ snapshots: sass: 1.92.1 terser: 5.43.1 - vite@6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): + vite@7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -16543,15 +14518,15 @@ snapshots: rollup: 4.50.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.1 + '@types/node': 20.19.13 fsevents: 2.3.3 jiti: 2.5.1 - less: 4.4.1 + less: 4.4.0 lightningcss: 1.30.1 - sass: 1.92.1 + sass: 1.90.0 terser: 5.43.1 - vite@7.1.2(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): + vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -16560,7 +14535,7 @@ snapshots: rollup: 4.50.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.13 + '@types/node': 24.3.1 fsevents: 2.3.3 jiti: 2.5.1 less: 4.4.0 @@ -16568,7 +14543,7 @@ snapshots: sass: 1.90.0 terser: 5.43.1 - vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): + vite@7.1.2(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -16580,10 +14555,11 @@ snapshots: '@types/node': 24.3.1 fsevents: 2.3.3 jiti: 2.5.1 - less: 4.4.0 + less: 4.4.1 lightningcss: 1.30.1 sass: 1.90.0 terser: 5.43.1 + optional: true vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): dependencies: @@ -16611,33 +14587,37 @@ snapshots: transitivePeerDependencies: - supports-color - vitest@2.1.9(@types/node@24.3.1)(@vitest/ui@2.1.9)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): + vitest@3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1): dependencies: - '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.20(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) - '@vitest/pretty-format': 2.1.9 - '@vitest/runner': 2.1.9 - '@vitest/snapshot': 2.1.9 - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.3.3 debug: 4.4.1 expect-type: 1.2.2 magic-string: 0.30.19 - pathe: 1.1.2 + pathe: 2.0.3 + picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 + tinyglobby: 0.2.15 tinypool: 1.1.1 - tinyrainbow: 1.2.0 - vite: 5.4.20(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) - vite-node: 2.1.9(@types/node@24.3.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + tinyrainbow: 2.0.0 + vite: 6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) + vite-node: 3.2.4(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.0)(lightningcss@1.30.1)(sass@1.90.0)(terser@5.43.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.3.1 - '@vitest/ui': 2.1.9(vitest@2.1.9) + '@types/node': 20.19.13 + '@vitest/ui': 3.2.4(vitest@3.2.4) jsdom: 25.0.1 transitivePeerDependencies: + - jiti - less - lightningcss - msw @@ -16647,8 +14627,10 @@ snapshots: - sugarss - supports-color - terser + - tsx + - yaml - vitest@3.2.4(@types/node@20.19.13)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): + vitest@3.2.4(@types/node@24.3.1)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@25.0.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 @@ -16670,11 +14652,11 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.6(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) - vite-node: 3.2.4(@types/node@20.19.13)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + vite: 6.3.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) + vite-node: 3.2.4(@types/node@24.3.1)(jiti@2.5.1)(less@4.4.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.19.13 + '@types/node': 24.3.1 '@vitest/ui': 3.2.4(vitest@3.2.4) jsdom: 25.0.1 transitivePeerDependencies: @@ -16755,21 +14737,13 @@ snapshots: weak-lru-cache@1.2.2: optional: true - web-encoding@1.1.5: - dependencies: - util: 0.12.5 - optionalDependencies: - '@zxing/text-encoding': 0.9.0 - - web-streams-polyfill@3.3.3: {} - web-vitals@4.2.4: {} webidl-conversions@4.0.2: {} webidl-conversions@7.0.0: {} - webpack-dev-middleware@7.4.2(webpack@5.101.2): + webpack-dev-middleware@7.4.2(webpack@5.101.2(esbuild@0.25.9)): dependencies: colorette: 2.0.20 memfs: 4.39.0 @@ -16780,7 +14754,7 @@ snapshots: optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-server@5.2.2(webpack@5.101.2): + webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16808,7 +14782,7 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.101.2) + webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) ws: 8.18.3 optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a0cf1ef4..f900ca8d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,10 +13,11 @@ # limitations under the License. packages: - - packages/* + - packages/angular + - packages/core + - packages/translations + - packages/styles - examples/angular - - examples/nextjs - - examples/react catalog: # Firebase