From fb9504ce4692a9b8f10eba7db2a0491e29cbfa5a Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Wed, 15 Oct 2025 13:21:12 +0100 Subject: [PATCH] fix(*): Rename FirebaseUIConfiguration -> FirebaseUI --- README.md | 37 ++++++++------- .../email-link-form.component.ts | 4 +- .../email-password-form.component.ts | 4 +- .../forgot-password-form.component.ts | 9 +--- .../forms/phone-form/phone-form.component.ts | 4 +- .../register-form/register-form.component.ts | 4 +- packages/core/src/auth.ts | 46 ++++++------------- .../core/src/behaviors/anonymous-upgrade.ts | 14 ++---- packages/core/src/behaviors/index.ts | 14 +++--- packages/core/src/behaviors/one-tap.ts | 4 +- .../core/src/behaviors/provider-strategy.ts | 9 ++-- packages/core/src/behaviors/recaptcha.test.ts | 4 +- packages/core/src/behaviors/recaptcha.ts | 4 +- .../src/behaviors/require-display-name.ts | 4 +- packages/core/src/behaviors/utils.test.ts | 8 ++-- packages/core/src/behaviors/utils.ts | 6 +-- packages/core/src/config.test.ts | 4 +- packages/core/src/config.ts | 12 ++--- packages/core/src/errors.ts | 6 +-- packages/core/src/schemas.ts | 14 +++--- packages/core/src/translations.ts | 8 +--- packages/core/tests/utils.ts | 4 +- packages/react/src/context.tsx | 6 +-- packages/react/tests/utils.tsx | 4 +- 24 files changed, 98 insertions(+), 135 deletions(-) diff --git a/README.md b/README.md index cf2e9faf..8075ae12 100644 --- a/README.md +++ b/README.md @@ -202,12 +202,11 @@ The initializeUI function accepts an options object that allows you to customize ### Type Definition ```js -type FirebaseUIConfigurationOptions = { +type FirebaseUIOptions = { app: FirebaseApp; - locale?: Locale | undefined; - translations?: RegisteredTranslations[] | undefined; - behaviors?: Partial>[] | undefined; - recaptchaMode?: 'normal' | 'invisible' | undefined; + auth?: Auth; + locale?: Locale; + behaviors?: Behavior[]; }; ``` @@ -290,7 +289,7 @@ const ui = initializeUI({ Configuration Type: ```js -type FirebaseUIConfigurationOptions = { +type FirebaseUIOptions = { app: FirebaseApp; locale?: Locale | undefined; translations?: RegisteredTranslations[] | undefined; @@ -303,61 +302,61 @@ type FirebaseUIConfigurationOptions = { **signInWithEmailAndPassword**: Signs in the user based on an email/password credential. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _email_: string - _password_: string **createUserWithEmailAndPassword**: Creates a user account based on an email/password credential. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _email_: string - _password_: string **signInWithPhoneNumber**: Signs in the user based on a provided phone number, using ReCaptcha to verify the sign-in. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _phoneNumber_: string - _recaptchaVerifier_: string **confirmPhoneNumber**: Verifies the phonenumber credential and signs in the user. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _confirmationResult_: [ConfirmationResult](https://firebase.google.com/docs/reference/node/firebase.auth.ConfirmationResult) - _verificationCode_: string **sendPasswordResetEmail**: Sends password reset instructions to an email account. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _email_: string **sendSignInLinkToEmail**: Send an sign-in links to an email account. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _email_: string **signInWithEmailLink**: Signs in with the user with the email link. If `autoUpgradeAnonymousCredential` then a pending credential will be handled. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _email_: string - _link_: string **signInAnonymously**: Signs in as an anonymous user. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI **signInWithOAuth**: Signs in with a provider such as Google via a redirect link. If `autoUpgradeAnonymousCredential` then the account will upgraded. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _provider_: [AuthProvider](https://firebase.google.com/docs/reference/node/firebase.auth.AuthProvider) **completeEmailLinkSignIn**: Completes the signing process based on a user signing in with an email link. -- _ui_: FirebaseUIConfiguration +- _ui_: FirebaseUI - _currentUrl_: string #### Provide a Store via Context -Using the returned `FirebaseUIConfiguration`, it is reccomended to use local context/providers/dependency-injection to expose the FirebaseUIConfiguration to the application. Here is an example context wrapper which accepts the configuration as a `ui` parameter: +Using the returned `FirebaseUI`, it is reccomended to use local context/providers/dependency-injection to expose the FirebaseUI to the application. Here is an example context wrapper which accepts the configuration as a `ui` parameter: ```js /** Creates a framework-agnostic context for Firebase UI configuration **/ @@ -391,7 +390,7 @@ export function createFirebaseUIContext(initialConfig) { FirebaseUI Configuration Type: ```js -export type FirebaseUIConfiguration = { +export type FirebaseUI = { app: FirebaseApp, getAuth: () => Auth, setLocale: (locale: Locale) => void, @@ -556,7 +555,7 @@ The core library provides a function for handling errors. ```js export function handleFirebaseError( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, error: any, opts?: { enableHandleExistingCredential?: boolean; 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 index 27f65d5c..b4bc7f05 100644 --- 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 @@ -25,7 +25,7 @@ import { FirebaseUIError, completeEmailLinkSignIn, sendSignInLinkToEmail, - FirebaseUIConfiguration, + FirebaseUI, } from "@firebase-ui/core"; import { firstValueFrom } from "rxjs"; @@ -75,7 +75,7 @@ export class EmailLinkFormComponent implements OnInit { formError: string | null = null; emailSent = false; private formSchema: any; - private config: FirebaseUIConfiguration; + private config: FirebaseUI; form = injectForm({ defaultValues: { 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 index 6ecfec8c..aa97b6fc 100644 --- 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 @@ -23,7 +23,7 @@ import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/ import { createEmailFormSchema, EmailFormSchema, - FirebaseUIConfiguration, + FirebaseUI, FirebaseUIError, signInWithEmailAndPassword, } from "@firebase-ui/core"; @@ -111,7 +111,7 @@ export class EmailPasswordFormComponent implements OnInit { formError: string | null = null; private formSchema: any; - private config: FirebaseUIConfiguration; + private config: FirebaseUI; form = injectForm({ defaultValues: { 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 index 06e69cba..2f5fec9f 100644 --- 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 @@ -21,12 +21,7 @@ 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 { createForgotPasswordFormSchema, FirebaseUI, FirebaseUIError, sendPasswordResetEmail } from "@firebase-ui/core"; import { firstValueFrom } from "rxjs"; import { Router } from "@angular/router"; @@ -85,7 +80,7 @@ export class ForgotPasswordFormComponent implements OnInit { formError: string | null = null; emailSent = false; private formSchema: any; - private config: FirebaseUIConfiguration; + private config: FirebaseUI; form = injectForm({ defaultValues: { 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 index b1a7dc96..218512e0 100644 --- 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 @@ -31,7 +31,7 @@ import { formatPhoneNumberWithCountry, confirmPhoneNumber, signInWithPhoneNumber, - FirebaseUIConfiguration, + FirebaseUI, } from "@firebase-ui/core"; import { interval, Subscription, firstValueFrom } from "rxjs"; import { Router } from "@angular/router"; @@ -103,7 +103,7 @@ export class PhoneNumberFormComponent implements OnInit, OnDestroy { recaptchaVerifier: RecaptchaVerifier | null = null; selectedCountry: CountryData = countryData[0]; private formSchema: any; - private config: FirebaseUIConfiguration; + private config: FirebaseUI; form = injectForm({ defaultValues: { 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 index c1caa691..1458e61a 100644 --- 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 @@ -24,7 +24,7 @@ import { EmailFormSchema, FirebaseUIError, createUserWithEmailAndPassword, - FirebaseUIConfiguration, + FirebaseUI, } from "@firebase-ui/core"; import { Auth } from "@angular/fire/auth"; import { TermsAndPrivacyComponent } from "../../../components/terms-and-privacy/terms-and-privacy.component"; @@ -106,7 +106,7 @@ export class RegisterFormComponent implements OnInit { formError: string | null = null; private formSchema: any; - private config: FirebaseUIConfiguration; + private config: FirebaseUI; form = injectForm({ defaultValues: { diff --git a/packages/core/src/auth.ts b/packages/core/src/auth.ts index 981e730a..8458a1cd 100644 --- a/packages/core/src/auth.ts +++ b/packages/core/src/auth.ts @@ -33,13 +33,13 @@ import { type PhoneInfoOptions, } from "firebase/auth"; import QRCode from "qrcode-generator"; -import { type FirebaseUIConfiguration } from "./config"; +import { type FirebaseUI } from "./config"; import { handleFirebaseError } from "./errors"; import { hasBehavior, getBehavior } from "./behaviors/index"; import { FirebaseError } from "firebase/app"; import { getTranslation } from "./translations"; -async function handlePendingCredential(_ui: FirebaseUIConfiguration, user: UserCredential): Promise { +async function handlePendingCredential(_ui: FirebaseUI, user: UserCredential): Promise { const pendingCredString = window.sessionStorage.getItem("pendingCred"); if (!pendingCredString) return user; @@ -55,7 +55,7 @@ async function handlePendingCredential(_ui: FirebaseUIConfiguration, user: UserC } export async function signInWithEmailAndPassword( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, email: string, password: string ): Promise { @@ -81,7 +81,7 @@ export async function signInWithEmailAndPassword( } export async function createUserWithEmailAndPassword( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, email: string, password: string, displayName?: string @@ -121,7 +121,7 @@ export async function createUserWithEmailAndPassword( } export async function verifyPhoneNumber( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, phoneNumber: PhoneInfoOptions | string, appVerifier: ApplicationVerifier ): Promise { @@ -137,7 +137,7 @@ export async function verifyPhoneNumber( } export async function confirmPhoneNumber( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, verificationId: string, verificationCode: string ): Promise { @@ -163,7 +163,7 @@ export async function confirmPhoneNumber( } } -export async function sendPasswordResetEmail(ui: FirebaseUIConfiguration, email: string): Promise { +export async function sendPasswordResetEmail(ui: FirebaseUI, email: string): Promise { try { ui.setState("pending"); await _sendPasswordResetEmail(ui.auth, email); @@ -174,7 +174,7 @@ export async function sendPasswordResetEmail(ui: FirebaseUIConfiguration, email: } } -export async function sendSignInLinkToEmail(ui: FirebaseUIConfiguration, email: string): Promise { +export async function sendSignInLinkToEmail(ui: FirebaseUI, email: string): Promise { try { ui.setState("pending"); const actionCodeSettings = { @@ -193,19 +193,12 @@ export async function sendSignInLinkToEmail(ui: FirebaseUIConfiguration, email: } } -export async function signInWithEmailLink( - ui: FirebaseUIConfiguration, - email: string, - link: string -): Promise { +export async function signInWithEmailLink(ui: FirebaseUI, email: string, link: string): Promise { const credential = EmailAuthProvider.credentialWithLink(email, link); return signInWithCredential(ui, credential); } -export async function signInWithCredential( - ui: FirebaseUIConfiguration, - credential: AuthCredential -): Promise { +export async function signInWithCredential(ui: FirebaseUI, credential: AuthCredential): Promise { try { ui.setState("pending"); if (hasBehavior(ui, "autoUpgradeAnonymousCredential")) { @@ -227,7 +220,7 @@ export async function signInWithCredential( } } -export async function signInAnonymously(ui: FirebaseUIConfiguration): Promise { +export async function signInAnonymously(ui: FirebaseUI): Promise { try { ui.setState("pending"); const result = await _signInAnonymously(ui.auth); @@ -239,10 +232,7 @@ export async function signInAnonymously(ui: FirebaseUIConfiguration): Promise { +export async function signInWithProvider(ui: FirebaseUI, provider: AuthProvider): Promise { try { ui.setState("pending"); if (hasBehavior(ui, "autoUpgradeAnonymousProvider")) { @@ -268,10 +258,7 @@ export async function signInWithProvider( } } -export async function completeEmailLinkSignIn( - ui: FirebaseUIConfiguration, - currentUrl: string -): Promise { +export async function completeEmailLinkSignIn(ui: FirebaseUI, currentUrl: string): Promise { try { if (!_isSignInWithEmailLink(ui.auth, currentUrl)) { return null; @@ -291,12 +278,7 @@ export async function completeEmailLinkSignIn( } } -export function generateTotpQrCode( - ui: FirebaseUIConfiguration, - secret: TotpSecret, - accountName?: string, - issuer?: string -): string { +export function generateTotpQrCode(ui: FirebaseUI, secret: TotpSecret, accountName?: string, issuer?: string): string { const currentUser = ui.auth.currentUser; if (!currentUser) { diff --git a/packages/core/src/behaviors/anonymous-upgrade.ts b/packages/core/src/behaviors/anonymous-upgrade.ts index fa6f07b6..ce534de1 100644 --- a/packages/core/src/behaviors/anonymous-upgrade.ts +++ b/packages/core/src/behaviors/anonymous-upgrade.ts @@ -1,15 +1,11 @@ import { type AuthCredential, type AuthProvider, linkWithCredential, type UserCredential } from "firebase/auth"; -import { type FirebaseUIConfiguration } from "~/config"; +import { type FirebaseUI } from "~/config"; import { getBehavior } from "~/behaviors"; -export type OnUpgradeCallback = ( - ui: FirebaseUIConfiguration, - oldUserId: string, - credential: UserCredential -) => Promise | void; +export type OnUpgradeCallback = (ui: FirebaseUI, oldUserId: string, credential: UserCredential) => Promise | void; export const autoUpgradeAnonymousCredentialHandler = async ( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, credential: AuthCredential, onUpgrade?: OnUpgradeCallback ) => { @@ -31,7 +27,7 @@ export const autoUpgradeAnonymousCredentialHandler = async ( }; export const autoUpgradeAnonymousProviderHandler = async ( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, provider: AuthProvider, onUpgrade?: OnUpgradeCallback ) => { @@ -61,7 +57,7 @@ export const autoUpgradeAnonymousProviderHandler = async ( }; export const autoUpgradeAnonymousUserRedirectHandler = async ( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, credential: UserCredential | null, onUpgrade?: OnUpgradeCallback ) => { diff --git a/packages/core/src/behaviors/index.ts b/packages/core/src/behaviors/index.ts index 022af593..69bc1045 100644 --- a/packages/core/src/behaviors/index.ts +++ b/packages/core/src/behaviors/index.ts @@ -1,4 +1,4 @@ -import type { FirebaseUIConfiguration } from "~/config"; +import type { FirebaseUI } from "~/config"; import type { RecaptchaVerifier, UserCredential } from "firebase/auth"; import * as anonymousUpgradeHandlers from "./anonymous-upgrade"; import * as autoAnonymousLoginHandlers from "./auto-anonymous-login"; @@ -24,17 +24,15 @@ type Registry = { autoUpgradeAnonymousProvider: CallableBehavior; autoUpgradeAnonymousUserRedirectHandler: RedirectBehavior< ( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, credential: UserCredential | null, onUpgrade?: anonymousUpgradeHandlers.OnUpgradeCallback ) => ReturnType >; - recaptchaVerification: CallableBehavior<(ui: FirebaseUIConfiguration, element: HTMLElement) => RecaptchaVerifier>; + recaptchaVerification: CallableBehavior<(ui: FirebaseUI, element: HTMLElement) => RecaptchaVerifier>; providerSignInStrategy: CallableBehavior; providerLinkStrategy: CallableBehavior; - oneTapSignIn: InitBehavior< - (ui: FirebaseUIConfiguration) => ReturnType - >; + oneTapSignIn: InitBehavior<(ui: FirebaseUI) => ReturnType>; requireDisplayName: CallableBehavior; countryCodes: CallableBehavior; }; @@ -114,11 +112,11 @@ export function countryCodes(options?: countryCodesHandlers.CountryCodesOptions) }; } -export function hasBehavior(ui: FirebaseUIConfiguration, key: T): boolean { +export function hasBehavior(ui: FirebaseUI, key: T): boolean { return !!ui.behaviors[key]; } -export function getBehavior(ui: FirebaseUIConfiguration, key: T): Registry[T]["handler"] { +export function getBehavior(ui: FirebaseUI, key: T): Registry[T]["handler"] { if (!hasBehavior(ui, key)) { throw new Error(`Behavior ${key} not found`); } diff --git a/packages/core/src/behaviors/one-tap.ts b/packages/core/src/behaviors/one-tap.ts index 32d2ff34..5154a4f7 100644 --- a/packages/core/src/behaviors/one-tap.ts +++ b/packages/core/src/behaviors/one-tap.ts @@ -1,6 +1,6 @@ import { GoogleAuthProvider } from "firebase/auth"; import type { IdConfiguration } from "google-one-tap"; -import type { FirebaseUIConfiguration } from "~/config"; +import type { FirebaseUI } from "~/config"; import { signInWithCredential } from "~/auth"; export type OneTapSignInOptions = { @@ -12,7 +12,7 @@ export type OneTapSignInOptions = { logLevel?: IdConfiguration["log_level"]; }; -export const oneTapSignInHandler = async (ui: FirebaseUIConfiguration, options: OneTapSignInOptions) => { +export const oneTapSignInHandler = async (ui: FirebaseUI, options: OneTapSignInOptions) => { // Only show one-tap if user is not signed in OR if they are anonymous. // Don't show if user is already signed in with a real account. if (ui.auth.currentUser && !ui.auth.currentUser.isAnonymous) { diff --git a/packages/core/src/behaviors/provider-strategy.ts b/packages/core/src/behaviors/provider-strategy.ts index efa94ba8..32c395ac 100644 --- a/packages/core/src/behaviors/provider-strategy.ts +++ b/packages/core/src/behaviors/provider-strategy.ts @@ -7,14 +7,11 @@ import { type User, type UserCredential, } from "firebase/auth"; -import { type FirebaseUIConfiguration } from "~/config"; +import { type FirebaseUI } from "~/config"; -export type ProviderSignInStrategyHandler = ( - ui: FirebaseUIConfiguration, - provider: AuthProvider -) => Promise; +export type ProviderSignInStrategyHandler = (ui: FirebaseUI, provider: AuthProvider) => Promise; export type ProviderLinkStrategyHandler = ( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, user: User, provider: AuthProvider ) => Promise; diff --git a/packages/core/src/behaviors/recaptcha.test.ts b/packages/core/src/behaviors/recaptcha.test.ts index 7ee0d71e..08fce46f 100644 --- a/packages/core/src/behaviors/recaptcha.test.ts +++ b/packages/core/src/behaviors/recaptcha.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { RecaptchaVerifier } from "firebase/auth"; import { recaptchaVerificationHandler, type RecaptchaVerificationOptions } from "./recaptcha"; -import type { FirebaseUIConfiguration } from "~/config"; +import type { FirebaseUI } from "~/config"; import { createMockUI } from "~/tests/utils"; vi.mock("firebase/auth", () => ({ @@ -79,7 +79,7 @@ describe("Recaptcha Verification Handler", () => { it("should pass correct auth instance", () => { const mockUI = createMockUI(); const customAuth = { uid: "test-uid" } as any; - const customUI = { auth: customAuth } as FirebaseUIConfiguration; + const customUI = { auth: customAuth } as FirebaseUI; recaptchaVerificationHandler(customUI, mockElement); diff --git a/packages/core/src/behaviors/recaptcha.ts b/packages/core/src/behaviors/recaptcha.ts index 19a75be8..707070ee 100644 --- a/packages/core/src/behaviors/recaptcha.ts +++ b/packages/core/src/behaviors/recaptcha.ts @@ -1,5 +1,5 @@ import { RecaptchaVerifier } from "firebase/auth"; -import { type FirebaseUIConfiguration } from "~/config"; +import { type FirebaseUI } from "~/config"; export type RecaptchaVerificationOptions = { size?: "normal" | "invisible" | "compact"; @@ -8,7 +8,7 @@ export type RecaptchaVerificationOptions = { }; export const recaptchaVerificationHandler = ( - ui: FirebaseUIConfiguration, + ui: FirebaseUI, element: HTMLElement, options?: RecaptchaVerificationOptions ) => { diff --git a/packages/core/src/behaviors/require-display-name.ts b/packages/core/src/behaviors/require-display-name.ts index 71541406..1402d1a4 100644 --- a/packages/core/src/behaviors/require-display-name.ts +++ b/packages/core/src/behaviors/require-display-name.ts @@ -1,6 +1,6 @@ import { updateProfile, type User } from "firebase/auth"; -import { type FirebaseUIConfiguration } from "~/config"; +import { type FirebaseUI } from "~/config"; -export const requireDisplayNameHandler = async (_: FirebaseUIConfiguration, user: User, displayName: string) => { +export const requireDisplayNameHandler = async (_: FirebaseUI, user: User, displayName: string) => { await updateProfile(user, { displayName }); }; diff --git a/packages/core/src/behaviors/utils.test.ts b/packages/core/src/behaviors/utils.test.ts index d5ee6ee0..abfc34c0 100644 --- a/packages/core/src/behaviors/utils.test.ts +++ b/packages/core/src/behaviors/utils.test.ts @@ -11,7 +11,7 @@ import { type InitHandler, } from "./utils"; import type { UserCredential } from "firebase/auth"; -import type { FirebaseUIConfiguration } from "~/config"; +import type { FirebaseUI } from "~/config"; describe("Behaviors Utils", () => { describe("callableBehavior", () => { @@ -75,7 +75,7 @@ describe("Behaviors Utils", () => { expect(behavior.type).toBe("redirect"); expect(behavior.handler).toBe(handler); - const mockUI = {} as FirebaseUIConfiguration; + const mockUI = {} as FirebaseUI; const mockResult = {} as UserCredential; await behavior.handler(mockUI, mockResult); @@ -110,7 +110,7 @@ describe("Behaviors Utils", () => { expect(behavior.type).toBe("init"); expect(behavior.handler).toBe(handler); - const mockUI = {} as FirebaseUIConfiguration; + const mockUI = {} as FirebaseUI; await behavior.handler(mockUI); expect(handler).toHaveBeenCalledWith(mockUI); @@ -123,7 +123,7 @@ describe("Behaviors Utils", () => { expect(behavior.type).toBe("init"); expect(behavior.handler).toBe(handler); - const mockUI = {} as FirebaseUIConfiguration; + const mockUI = {} as FirebaseUI; behavior.handler(mockUI); expect(handler).toHaveBeenCalledWith(mockUI); diff --git a/packages/core/src/behaviors/utils.ts b/packages/core/src/behaviors/utils.ts index def09b0c..7d332e7a 100644 --- a/packages/core/src/behaviors/utils.ts +++ b/packages/core/src/behaviors/utils.ts @@ -1,10 +1,10 @@ import type { UserCredential } from "firebase/auth"; -import type { FirebaseUIConfiguration } from "~/config"; +import type { FirebaseUI } from "~/config"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type CallableHandler any = (...args: any[]) => any> = T; -export type InitHandler = (ui: FirebaseUIConfiguration) => Promise | void; -export type RedirectHandler = (ui: FirebaseUIConfiguration, result: UserCredential | null) => Promise | void; +export type InitHandler = (ui: FirebaseUI) => Promise | void; +export type RedirectHandler = (ui: FirebaseUI, result: UserCredential | null) => Promise | void; export type CallableBehavior = { type: "callable"; diff --git a/packages/core/src/config.test.ts b/packages/core/src/config.test.ts index 2555291b..8d117978 100644 --- a/packages/core/src/config.test.ts +++ b/packages/core/src/config.test.ts @@ -1,9 +1,9 @@ import { FirebaseApp } from "firebase/app"; import { Auth, MultiFactorResolver } from "firebase/auth"; -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { describe, it, expect, vi, beforeEach } from "vitest"; import { initializeUI } from "./config"; import { enUs, registerLocale } from "@firebase-ui/translations"; -import { autoUpgradeAnonymousUsers, autoAnonymousLogin, defaultBehaviors } from "./behaviors"; +import { autoUpgradeAnonymousUsers, autoAnonymousLogin } from "./behaviors"; // Mock Firebase Auth vi.mock("firebase/auth", () => ({ diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 3a1c317b..1249449b 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -22,7 +22,7 @@ import { type Behavior, type Behaviors, defaultBehaviors } from "./behaviors"; import type { InitBehavior, RedirectBehavior } from "./behaviors/utils"; import { type FirebaseUIState } from "./state"; -export type FirebaseUIConfigurationOptions = { +export type FirebaseUIOptions = { app: FirebaseApp; auth?: Auth; locale?: RegisteredLocale; @@ -30,7 +30,7 @@ export type FirebaseUIConfigurationOptions = { behaviors?: Behavior[]; }; -export type FirebaseUIConfiguration = { +export type FirebaseUI = { app: FirebaseApp; auth: Auth; setLocale: (locale: RegisteredLocale) => void; @@ -42,11 +42,11 @@ export type FirebaseUIConfiguration = { setMultiFactorResolver: (multiFactorResolver?: MultiFactorResolver) => void; }; -export const $config = map>>({}); +export const $config = map>>({}); -export type FirebaseUI = DeepMapStore; +export type FirebaseUIStore = DeepMapStore; -export function initializeUI(config: FirebaseUIConfigurationOptions, name: string = "[DEFAULT]"): FirebaseUI { +export function initializeUI(config: FirebaseUIOptions, name: string = "[DEFAULT]"): FirebaseUIStore { // Reduce the behaviors to a single object. const behaviors = config.behaviors?.reduce((acc, behavior) => { return { @@ -57,7 +57,7 @@ export function initializeUI(config: FirebaseUIConfigurationOptions, name: strin $config.setKey( name, - deepMap({ + deepMap({ app: config.app, auth: config.auth || getAuth(config.app), locale: config.locale ?? enUs, diff --git a/packages/core/src/errors.ts b/packages/core/src/errors.ts index 05fedea7..da9f1e52 100644 --- a/packages/core/src/errors.ts +++ b/packages/core/src/errors.ts @@ -17,10 +17,10 @@ import { ERROR_CODE_MAP, type ErrorCode } from "@firebase-ui/translations"; import { FirebaseError } from "firebase/app"; import { type AuthCredential, getMultiFactorResolver, type MultiFactorError } from "firebase/auth"; -import { type FirebaseUIConfiguration } from "./config"; +import { type FirebaseUI } from "./config"; import { getTranslation } from "./translations"; export class FirebaseUIError extends FirebaseError { - constructor(ui: FirebaseUIConfiguration, error: FirebaseError) { + constructor(ui: FirebaseUI, error: FirebaseError) { const message = getTranslation(ui, "errors", ERROR_CODE_MAP[error.code as ErrorCode]); super(error.code, message || error.message); @@ -29,7 +29,7 @@ export class FirebaseUIError extends FirebaseError { } } -export function handleFirebaseError(ui: FirebaseUIConfiguration, error: unknown): never { +export function handleFirebaseError(ui: FirebaseUI, error: unknown): never { // If it's not a Firebase error, then we just throw it and preserve the original error. if (!isFirebaseError(error)) { throw error; diff --git a/packages/core/src/schemas.ts b/packages/core/src/schemas.ts index df3a0d47..1bb98069 100644 --- a/packages/core/src/schemas.ts +++ b/packages/core/src/schemas.ts @@ -16,21 +16,21 @@ import * as z from "zod"; import { getTranslation } from "./translations"; -import { type FirebaseUIConfiguration } from "./config"; +import { type FirebaseUI } from "./config"; import { hasBehavior } from "./behaviors"; export const LoginTypes = ["email", "phone", "anonymous", "emailLink", "google"] as const; export type LoginType = (typeof LoginTypes)[number]; export type AuthMode = "signIn" | "signUp"; -export function createSignInAuthFormSchema(ui: FirebaseUIConfiguration) { +export function createSignInAuthFormSchema(ui: FirebaseUI) { return z.object({ email: z.email(getTranslation(ui, "errors", "invalidEmail")), password: z.string().min(8, getTranslation(ui, "errors", "weakPassword")), }); } -export function createSignUpAuthFormSchema(ui: FirebaseUIConfiguration) { +export function createSignUpAuthFormSchema(ui: FirebaseUI) { const requireDisplayName = hasBehavior(ui, "requireDisplayName"); const displayNameRequiredMessage = getTranslation(ui, "errors", "displayNameRequired"); @@ -43,19 +43,19 @@ export function createSignUpAuthFormSchema(ui: FirebaseUIConfiguration) { }); } -export function createForgotPasswordAuthFormSchema(ui: FirebaseUIConfiguration) { +export function createForgotPasswordAuthFormSchema(ui: FirebaseUI) { return z.object({ email: z.email(getTranslation(ui, "errors", "invalidEmail")), }); } -export function createEmailLinkAuthFormSchema(ui: FirebaseUIConfiguration) { +export function createEmailLinkAuthFormSchema(ui: FirebaseUI) { return z.object({ email: z.email(getTranslation(ui, "errors", "invalidEmail")), }); } -export function createPhoneAuthNumberFormSchema(ui: FirebaseUIConfiguration) { +export function createPhoneAuthNumberFormSchema(ui: FirebaseUI) { return z.object({ phoneNumber: z .string() @@ -64,7 +64,7 @@ export function createPhoneAuthNumberFormSchema(ui: FirebaseUIConfiguration) { }); } -export function createPhoneAuthVerifyFormSchema(ui: FirebaseUIConfiguration) { +export function createPhoneAuthVerifyFormSchema(ui: FirebaseUI) { return z.object({ verificationId: z.string().min(1, getTranslation(ui, "errors", "missingVerificationId")), verificationCode: z.string().refine((val) => !val || val.length >= 6, { diff --git a/packages/core/src/translations.ts b/packages/core/src/translations.ts index 9f912ccd..ffdcea7e 100644 --- a/packages/core/src/translations.ts +++ b/packages/core/src/translations.ts @@ -19,12 +19,8 @@ import { type TranslationCategory, type TranslationKey, } from "@firebase-ui/translations"; -import { type FirebaseUIConfiguration } from "./config"; +import { type FirebaseUI } from "./config"; -export function getTranslation( - ui: FirebaseUIConfiguration, - category: T, - key: TranslationKey -) { +export function getTranslation(ui: FirebaseUI, category: T, key: TranslationKey) { return _getTranslation(ui.locale, category, key); } diff --git a/packages/core/tests/utils.ts b/packages/core/tests/utils.ts index bccd0de1..f6d23445 100644 --- a/packages/core/tests/utils.ts +++ b/packages/core/tests/utils.ts @@ -3,9 +3,9 @@ import { vi } from "vitest"; import type { FirebaseApp } from "firebase/app"; import type { Auth } from "firebase/auth"; import { enUs } from "@firebase-ui/translations"; -import { FirebaseUIConfiguration } from "../src/config"; +import { FirebaseUI } from "../src/config"; -export function createMockUI(overrides?: Partial): FirebaseUIConfiguration { +export function createMockUI(overrides?: Partial): FirebaseUI { return { app: {} as FirebaseApp, auth: {} as Auth, diff --git a/packages/react/src/context.tsx b/packages/react/src/context.tsx index 0387a9ce..010eb7b4 100644 --- a/packages/react/src/context.tsx +++ b/packages/react/src/context.tsx @@ -14,16 +14,16 @@ * limitations under the License. */ -import { type FirebaseUIConfiguration, type FirebaseUI } from "@firebase-ui/core"; +import { type FirebaseUIStore, type FirebaseUI } from "@firebase-ui/core"; import { useStore } from "@nanostores/react"; import { type PolicyProps, PolicyProvider } from "~/components/policies"; import { createContext } from "react"; -export const FirebaseUIContext = createContext({} as FirebaseUIConfiguration); +export const FirebaseUIContext = createContext({} as FirebaseUI); export type FirebaseUIProviderProps = { children: React.ReactNode; - ui: FirebaseUI; + ui: FirebaseUIStore; policies?: PolicyProps; }; diff --git a/packages/react/tests/utils.tsx b/packages/react/tests/utils.tsx index 4fbc7768..3386aa75 100644 --- a/packages/react/tests/utils.tsx +++ b/packages/react/tests/utils.tsx @@ -1,10 +1,10 @@ import type { FirebaseApp } from "firebase/app"; import type { Auth } from "firebase/auth"; import { enUs } from "@firebase-ui/translations"; -import { Behavior, FirebaseUI, FirebaseUIConfigurationOptions, initializeUI } from "@firebase-ui/core"; +import { Behavior, FirebaseUI, FirebaseUIOptions, initializeUI } from "@firebase-ui/core"; import { FirebaseUIProvider } from "../src/context"; -export function createMockUI(overrides?: Partial): FirebaseUI { +export function createMockUI(overrides?: Partial): FirebaseUI { return initializeUI({ app: {} as FirebaseApp, auth: {} as Auth,