UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

355 lines (354 loc) 9.94 kB
'use client'; import { jsx as c } from "react/jsx-runtime"; import { useReducer as I, useMemo as w, useEffect as g, useCallback as l, createContext as k, useContext as _ } from "react"; import { createFrankAuthConfig as L, ConfigManager as N } from "../config/index.js"; import { DEFAULT_FRANK_AUTH_CONFIG as p } from "../config/defaults.js"; import { validateFrankAuthConfig as U } from "../config/validators.js"; const f = k(null); function P(e, a) { switch (a.type) { case "SET_LOADED": return { ...e, isLoaded: a.payload }; case "SET_CONFIG": return { ...e, config: a.payload, publishableKey: a.payload.publishableKey, secretKey: a.payload.secretKey, projectId: a.payload.projectId, userType: a.payload.userType, apiUrl: a.payload.apiUrl || e.apiUrl, theme: a.payload.theme || e.theme, appearance: a.payload.appearance || e.appearance, localization: a.payload.localization || e.localization, components: a.payload.components || e.components, linksPath: { ...e.linksPath ?? {}, ...a.payload.linksPath }, features: a.payload.features || e.features, debug: a.payload.debug || e.debug, frontendUrl: a.payload.frontendUrl || e.frontendUrl }; case "UPDATE_CONFIG": const t = { ...e.config, ...a.payload }; return { ...e, config: t, // secretKey: action.payload.secretKey, // projectId: action.payload.projectId, theme: a.payload.theme || e.theme, appearance: a.payload.appearance || e.appearance, localization: a.payload.localization || e.localization, components: a.payload.components || e.components, linksPath: { ...e.linksPath ?? {}, ...a.payload.linksPath }, features: a.payload.features || e.features, debug: a.payload.debug !== void 0 ? a.payload.debug : e.debug, frontendUrl: a.payload.frontendUrl || e.frontendUrl }; case "SET_ORGANIZATION": return { ...e, organizationConfig: a.payload, config: { ...e.config, organization: a.payload, projectId: a.payload.id } }; case "SET_ORGANIZATION_SETTINGS": return { ...e, organizationSettings: a.payload }; case "SET_THEME": return { ...e, theme: a.payload, config: { ...e.config, theme: a.payload } }; case "SET_APPEARANCE": return { ...e, appearance: a.payload, config: { ...e.config, appearance: a.payload } }; case "SET_LOCALIZATION": return { ...e, localization: a.payload, config: { ...e.config, localization: a.payload } }; case "SET_COMPONENTS": return { ...e, components: a.payload, config: { ...e.config, components: a.payload } }; case "SET_FEATURES": return { ...e, features: a.payload, config: { ...e.config, features: a.payload } }; case "SET_DEBUG": return { ...e, debug: a.payload, config: { ...e.config, debug: a.payload } }; case "RESET_CONFIG": return { ...y, publishableKey: e.publishableKey, secretKey: e.secretKey, projectId: e.projectId, userType: e.userType, apiUrl: e.apiUrl, isLoaded: !0 }; default: return e; } } const y = { isLoaded: !1, config: p, publishableKey: "", userType: "external", apiUrl: "https://api.frankauth.com", theme: p.theme, appearance: p.appearance, localization: p.localization, components: {}, linksPath: { signUp: "/auth/sign-up", magicLink: "/auth/magic-link", verify: "/auth/verify", signIn: "/auth/sign-in", resetPassword: "/auth/reset-password", forgotPassword: "/auth/forgot-password", signOut: "/auth/sign-out" }, features: { signUp: !0, signIn: !0, passwordReset: !0, mfa: !1, passkeys: !1, oauth: !1, magicLink: !1, sso: !1, organizationManagement: !1, userProfile: !0, sessionManagement: !0 }, debug: !1 }; function x({ children: e, config: a, onConfigChange: t }) { const [s, i] = I(P, y), o = w(() => { try { const r = L(a); return new N(r); } catch (r) { throw console.error("[FrankAuth] Invalid configuration:", r), r; } }, [a]); g(() => { const r = o.getConfig(); i({ type: "SET_CONFIG", payload: r }), i({ type: "SET_LOADED", payload: !0 }); }, [o]), g(() => o.subscribe((n) => { i({ type: "SET_CONFIG", payload: n }), t?.(n); }), [o, t]), g(() => { typeof window < "u" && s.isLoaded && o.applyToDOM(); }, [o, s.isLoaded, s.theme, s.appearance]); const h = l((r) => { try { const n = U({ ...s.config, ...r }); if (!n.isValid) { const d = n.errors.map((F) => F.message).join(", "); throw new Error(`Configuration validation failed: ${d}`); } o.updateConfig(r), i({ type: "UPDATE_CONFIG", payload: r }); } catch (n) { throw console.error("[FrankAuth] Configuration update failed:", n), n; } }, [o, s.config]), m = l((r) => { try { const n = { id: r.id, name: r.name, slug: r.slug || "", settings: r.settings || {}, features: { sso: r.ssoEnabled || !1, mfa: r.settings?.mfaSettings?.enabled || !1, auditLogs: r.settings?.auditSettings?.enabled || !1, customBranding: !!r.settings?.branding, apiAccess: r.apiEnabled || !1 }, limits: { maxUsers: r.userLimit || 100, maxSessions: r.sessionLimit || 10, apiRequestLimit: r.apiRequestLimit || 1e3 } }; o.setOrganization(n), i({ type: "SET_ORGANIZATION", payload: n }); const d = S(n); i({ type: "SET_FEATURES", payload: d }); } catch (n) { throw console.error("[FrankAuth] Failed to set organization:", n), n; } }, [o]), E = l((r) => { try { o.getThemeManager().setTheme(r), i({ type: "SET_THEME", payload: o.getThemeManager().getTheme() }); } catch (n) { throw console.error("[FrankAuth] Failed to set theme:", n), n; } }, [o]), T = l((r) => { try { o.getAppearanceManager().updateConfig(r), i({ type: "SET_APPEARANCE", payload: o.getAppearanceManager().getConfig() }); } catch (n) { throw console.error("[FrankAuth] Failed to set appearance:", n), n; } }, [o]), b = l((r) => { try { o.getLocalizationManager().setLocale(r), i({ type: "SET_LOCALIZATION", payload: { ...s.localization, defaultLocale: r } }); } catch (n) { throw console.error("[FrankAuth] Failed to set locale:", n), n; } }, [o, s.localization]), C = l((r) => { try { if (r.settings?.branding) { const n = { logo: { url: r.logoUrl, alt: r.name }, colors: { primary: r.settings.branding.primaryColor || "#3b82f6", secondary: r.settings.branding.secondaryColor || "#64748b" }, fonts: { primary: "Inter, ui-sans-serif, system-ui, sans-serif" }, customCSS: r.settings.branding.customCSS }; o.getThemeManager().applyBranding(n), o.getAppearanceManager().applyOrganizationBranding(r); } } catch (n) { throw console.error("[FrankAuth] Failed to apply organization branding:", n), n; } }, [o]), A = l(() => { try { o.reset(), i({ type: "RESET_CONFIG" }); } catch (r) { throw console.error("[FrankAuth] Failed to reset configuration:", r), r; } }, [o]), S = (r) => { const n = r.settings; return { signUp: n.allowPublicSignup || !1, signIn: !0, passwordReset: !0, mfa: r.features.mfa, passkeys: n.authConfig?.passkeysEnabled || !1, oauth: n.authConfig?.oauthEnabled || !1, magicLink: n.authConfig?.magicLinkEnabled || !1, sso: r.features.sso, organizationManagement: !0, userProfile: !0, sessionManagement: !0 }; }, O = { // State ...s, // Methods updateConfig: h, setOrganization: m, setTheme: E, setAppearance: T, setLocale: b, applyOrganizationBranding: C, resetToDefaults: A }; return /* @__PURE__ */ c(f.Provider, { value: O, children: e }); } function u() { const e = _(f); if (!e) throw new Error("useConfig must be used within a ConfigProvider"); return e; } function D() { const { features: e } = u(); return { ...e, hasFeature: (a) => e[a], requireFeature: (a) => { if (!e[a]) throw new Error(`Feature ${a} is not enabled`); } }; } function K() { const { organizationConfig: e, organizationSettings: a, setOrganization: t, applyOrganizationBranding: s } = u(); return { organization: e, settings: a, setOrganization: t, applyBranding: s, hasOrganization: !!e, isMultiTenant: !!e }; } function j() { const { components: e } = u(), a = l((t, s) => e[t] || s, [e]); return { components: e, getComponent: a, hasOverride: (t) => !!e[t] }; } function B(e) { const a = (t) => { const s = u(); return /* @__PURE__ */ c(e, { ...t, config: s }); }; return a.displayName = `withConfig(${e.displayName || e.name})`, a; } export { f as ConfigContext, x as ConfigProvider, j as useComponentOverrides, u as useConfig, D as useFeatures, K as useOrganizationConfig, B as withConfig }; //# sourceMappingURL=config-provider.js.map