clefbase 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -33932,10 +33932,6 @@ async function runInit(cwd = process.cwd()) {
33932
33932
  hosting: services.includes("hosting"),
33933
33933
  functions: services.includes("functions")
33934
33934
  };
33935
- let authSetup;
33936
- if (cfg.services.auth) {
33937
- authSetup = await setupAuth(cwd);
33938
- }
33939
33935
  if (cfg.services.hosting) {
33940
33936
  await setupHosting(cfg, cwd);
33941
33937
  }
@@ -33947,10 +33943,6 @@ async function runInit(cwd = process.cwd()) {
33947
33943
  ensureGitignore(cwd);
33948
33944
  writeEnvExample(cfg, cwd);
33949
33945
  const libResult = scaffoldLib(cfg, cwd);
33950
- let authResult;
33951
- if (cfg.services.auth && authSetup) {
33952
- authResult = await scaffoldAuth(cwd, authSetup);
33953
- }
33954
33946
  console.log();
33955
33947
  console.log(source_default.green.bold(" \u2713 Project initialised!"));
33956
33948
  console.log();
@@ -33961,127 +33953,12 @@ async function runInit(cwd = process.cwd()) {
33961
33953
  console.log(source_default.dim(` Lib config: ${libResult.configCopy}`));
33962
33954
  console.log(source_default.dim(` Lib entry: ${libResult.libFile}`));
33963
33955
  }
33964
- if (authResult == null ? void 0 : authResult.hasAuth) {
33965
- if (authResult.context) console.log(source_default.dim(` Auth context: ${authResult.context}`));
33966
- if (authResult.modal) console.log(source_default.dim(` Auth modal: ${authResult.modal}`));
33967
- if (authResult.protected) console.log(source_default.dim(` Protected: ${authResult.protected}`));
33968
- }
33969
33956
  if (cfg.services.functions) {
33970
33957
  console.log(source_default.dim(` Functions: functions/ (${functionsRuntime ?? "node"})`));
33971
33958
  console.log(source_default.dim(` run: node functions/deploy.mjs`));
33972
33959
  }
33973
33960
  console.log();
33974
- printUsageHint(cfg, authSetup);
33975
- }
33976
- async function setupAuth(cwd) {
33977
- console.log();
33978
- console.log(source_default.bold(" Auth Setup"));
33979
- console.log();
33980
- const { scaffoldContext } = await lib_default.prompt([{
33981
- type: "confirm",
33982
- name: "scaffoldContext",
33983
- message: "Scaffold React AuthContext?",
33984
- default: true
33985
- }]);
33986
- const { scaffoldModal } = await lib_default.prompt([{
33987
- type: "confirm",
33988
- name: "scaffoldModal",
33989
- message: "Scaffold AuthModal component?",
33990
- default: true
33991
- }]);
33992
- const { updateApp } = await lib_default.prompt([{
33993
- type: "confirm",
33994
- name: "updateApp",
33995
- message: "Update App.tsx to use AuthProvider?",
33996
- default: false
33997
- }]);
33998
- return { scaffoldContext, scaffoldModal, updateApp };
33999
- }
34000
- function getTemplatePath(filename) {
34001
- let dir = __dirname;
34002
- if (dir.includes("/dist-src/")) {
34003
- return import_path2.default.join(dir, "../templates", filename);
34004
- }
34005
- return import_path2.default.join(dir, "../templates", filename);
34006
- }
34007
- function readTemplate(filename, fallback2) {
34008
- try {
34009
- const templatePath = getTemplatePath(filename);
34010
- return import_fs3.default.readFileSync(templatePath, "utf-8");
34011
- } catch {
34012
- return fallback2;
34013
- }
34014
- }
34015
- async function scaffoldAuth(cwd, setup) {
34016
- const result = { hasAuth: false };
34017
- const contextDir = import_path2.default.join(cwd, "src", "context");
34018
- import_fs3.default.mkdirSync(contextDir, { recursive: true });
34019
- if (setup.scaffoldContext) {
34020
- const contextFile = import_path2.default.join(contextDir, "AuthContext.tsx");
34021
- try {
34022
- const content = readTemplate("AuthContext.tsx.template", AUTH_CONTEXT_FALLBACK);
34023
- import_fs3.default.writeFileSync(contextFile, content);
34024
- result.context = import_path2.default.relative(cwd, contextFile);
34025
- result.hasAuth = true;
34026
- } catch (err) {
34027
- console.warn(source_default.yellow(` Warning: Could not scaffold AuthContext: ${err.message}`));
34028
- }
34029
- }
34030
- if (setup.scaffoldModal) {
34031
- const componentDir = import_path2.default.join(cwd, "src", "components");
34032
- import_fs3.default.mkdirSync(componentDir, { recursive: true });
34033
- const modalFile = import_path2.default.join(componentDir, "AuthModal.tsx");
34034
- try {
34035
- const content = readTemplate("AuthModal.tsx.template", AUTH_MODAL_FALLBACK);
34036
- import_fs3.default.writeFileSync(modalFile, content);
34037
- result.modal = import_path2.default.relative(cwd, modalFile);
34038
- result.hasAuth = true;
34039
- } catch (err) {
34040
- console.warn(source_default.yellow(` Warning: Could not scaffold AuthModal: ${err.message}`));
34041
- }
34042
- const protectedFile = import_path2.default.join(componentDir, "ProtectedRoute.tsx");
34043
- try {
34044
- const content = readTemplate("ProtectedRoute.tsx.template", PROTECTED_ROUTE_FALLBACK);
34045
- import_fs3.default.writeFileSync(protectedFile, content);
34046
- result.protected = import_path2.default.relative(cwd, protectedFile);
34047
- } catch (err) {
34048
- console.warn(source_default.yellow(` Warning: Could not scaffold ProtectedRoute: ${err.message}`));
34049
- }
34050
- }
34051
- if (setup.updateApp) {
34052
- const appPath = import_path2.default.join(cwd, "src", "App.tsx");
34053
- if (import_fs3.default.existsSync(appPath)) {
34054
- try {
34055
- updateAppWithAuth(appPath);
34056
- } catch (err) {
34057
- console.warn(source_default.yellow(` Warning: Could not update App.tsx: ${err.message}`));
34058
- }
34059
- }
34060
- }
34061
- return result;
34062
- }
34063
- function updateAppWithAuth(appPath) {
34064
- let content = import_fs3.default.readFileSync(appPath, "utf-8");
34065
- if (content.includes("AuthProvider")) {
34066
- return;
34067
- }
34068
- if (!content.includes("import { AuthProvider, useAuth }")) {
34069
- const importLine = "import { AuthProvider, useAuth } from '@/context/AuthContext';\n";
34070
- content = importLine + content;
34071
- }
34072
- const exportMatch = content.match(/export\s+default\s+(function\s+\w+\s*\(|const\s+\w+\s*=|\(\)|=>)/);
34073
- if (exportMatch) {
34074
- const returnMatch = content.match(/export\s+default\s+(?:function\s+\w+\s*\([^)]*\)\s*\{|\(.*?\)\s*=>\s*)[\s\S]*?return\s+/);
34075
- if (returnMatch) {
34076
- if (content.includes("return (") || content.includes("return <")) {
34077
- const beforeReturn = content.substring(0, content.lastIndexOf("return"));
34078
- const afterReturn = content.substring(content.lastIndexOf("return"));
34079
- const wrappedReturn = afterReturn.replace(/return\s+(<[^>]+>[\s\S]*)/m, "return (\n <AuthProvider>\n $1\n </AuthProvider>\n )");
34080
- content = beforeReturn + wrappedReturn;
34081
- }
34082
- }
34083
- }
34084
- import_fs3.default.writeFileSync(appPath, content);
33961
+ printUsageHint(cfg);
34085
33962
  }
34086
33963
  async function setupFunctions(cfg, cwd) {
34087
33964
  console.log();
@@ -34707,7 +34584,7 @@ function buildLibTs(cfg) {
34707
34584
  ` * const { user } = await auth.signIn("alice@example.com", "pass");`,
34708
34585
  ` *`,
34709
34586
  ` * // Google sign-in \u2014 add this to your root component / entry point:`,
34710
- ` * await auth.handleGatewayCallback(); // handles ?cfx_token= on return`,
34587
+ ` * const result = await auth.handleAuthCallback(); // handles ?cfx_token= on return`,
34711
34588
  ` *`,
34712
34589
  ` * // On sign-in button click:`,
34713
34590
  ` * await auth.signInWithGateway("google");`
@@ -34748,20 +34625,6 @@ function buildLibTs(cfg) {
34748
34625
  lines.push(`/** Clefbase Auth \u2014 sign up, sign in, manage sessions. */`);
34749
34626
  lines.push(`export const auth: Auth = getAuth(app);`);
34750
34627
  lines.push("");
34751
- lines.push(`/**`);
34752
- lines.push(` * Call this once on every page load (before rendering your UI).`);
34753
- lines.push(` * Detects the ?cfx_token= param the gateway appends after OAuth,`);
34754
- lines.push(` * saves the session, and cleans the URL.`);
34755
- lines.push(` *`);
34756
- lines.push(` * @example`);
34757
- lines.push(` * // React / Next.js \u2014 in your root layout or _app.tsx:`);
34758
- lines.push(` * useEffect(() => { auth.handleGatewayCallback(); }, []);`);
34759
- lines.push(` *`);
34760
- lines.push(` * // Vanilla JS \u2014 at the top of your entry point:`);
34761
- lines.push(` * await auth.handleGatewayCallback();`);
34762
- lines.push(` */`);
34763
- lines.push(`export { auth };`);
34764
- lines.push("");
34765
34628
  }
34766
34629
  if (storage) {
34767
34630
  lines.push(`/** Clefbase Storage \u2014 upload and manage files. */`);
@@ -34899,16 +34762,12 @@ function printUsageHint(cfg, authSetup) {
34899
34762
  console.log(source_default.cyan(` import { AuthProvider, useAuth } from "@/context/AuthContext";`));
34900
34763
  console.log(source_default.cyan(` const { user, signIn, signOut } = useAuth();`));
34901
34764
  }
34902
- if (authSetup == null ? void 0 : authSetup.scaffoldModal) {
34903
- console.log(source_default.cyan(` import AuthModal from "@/components/AuthModal";`));
34904
- }
34905
34765
  if (authSetup == null ? void 0 : authSetup.scaffoldContext) {
34906
34766
  console.log(source_default.cyan(` import { EmailVerificationCard } from "clefbase/react";`));
34907
34767
  }
34908
34768
  if (!(authSetup == null ? void 0 : authSetup.scaffoldContext)) {
34909
34769
  console.log(source_default.cyan(` const { user } = await auth.signIn("email", "pass");`));
34910
- console.log(source_default.cyan(` await auth.signInWithGateway("google"); // redirects to auth.cleforyx.com`));
34911
- console.log(source_default.cyan(` await auth.handleGatewayCallback(); // call on every page load`));
34770
+ console.log(source_default.cyan(` const result = await auth.handleAuthCallback(); // call on every page load`));
34912
34771
  }
34913
34772
  }
34914
34773
  if (cfg.services.storage) {
@@ -34936,432 +34795,6 @@ function printUsageHint(cfg, authSetup) {
34936
34795
  }
34937
34796
  console.log();
34938
34797
  }
34939
- var AUTH_CONTEXT_FALLBACK = `'use client';
34940
-
34941
- import React, { createContext, useContext, useEffect, useState } from 'react';
34942
- import type { AuthUser } from 'clefbase';
34943
- import { getAuth, getDatabase } from 'clefbase';
34944
-
34945
- /**
34946
- * Base user data interface stored in the 'users' collection.
34947
- * Extend this in your app for custom fields.
34948
- */
34949
- export interface UserData {
34950
- uid: string;
34951
- email: string;
34952
- displayName?: string;
34953
- photoUrl?: string;
34954
- createdAt?: string;
34955
- [key: string]: unknown;
34956
- }
34957
-
34958
- /**
34959
- * Auth context for managing authentication state and user data in your React app.
34960
- * Wraps the clefbase Auth SDK with React Context integration.
34961
- *
34962
- * Features:
34963
- * - User state management with auth listener
34964
- * - User profile data synced from database's 'users' collection
34965
- * - Token persistence (handled by SDK)
34966
- * - Auth modal state
34967
- * - Error handling and loading states
34968
- * - Auto-create user doc on first signup
34969
- * - Auto-sync user data on signin
34970
- */
34971
-
34972
- interface AuthContextType<T extends UserData = UserData> {
34973
- /** Currently authenticated user, or null if not signed in */
34974
- user: AuthUser | null;
34975
- /** User profile data from the 'users' collection, or null if not signed in */
34976
- userData: T | null;
34977
- /** Authentication token */
34978
- token: string | null;
34979
- /** True while auth state is being restored or operations are pending */
34980
- loading: boolean;
34981
- /** Error message from last failed operation */
34982
- error: string | null;
34983
- /** True if auth modal is open */
34984
- isAuthModalOpen: boolean;
34985
-
34986
- // \u2500\u2500 Auth modal management \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
34987
-
34988
- /**
34989
- * Open the auth modal for sign in / sign up.
34990
- * The modal at auth.cleforyx.com handles the actual authentication.
34991
- * After success, auth state updates automatically.
34992
- */
34993
- openAuthModal: () => void;
34994
-
34995
- /**
34996
- * Close the auth modal programmatically.
34997
- */
34998
- closeAuthModal: () => void;
34999
-
35000
- /**
35001
- * Manually sync user data from the database.
35002
- */
35003
- syncUserData: () => Promise<void>;
35004
-
35005
- /**
35006
- * Update user data in the database.
35007
- */
35008
- updateUserData: (updates: Partial<Omit<T, 'uid'>>) => Promise<void>;
35009
-
35010
- /**
35011
- * Verify email with a verification code.
35012
- */
35013
- verifyEmail: (code: string) => Promise<void>;
35014
-
35015
- /**
35016
- * Request a password reset email.
35017
- */
35018
- sendPasswordResetEmail: (email: string) => Promise<void>;
35019
-
35020
- /**
35021
- * Sign out the current user and clear data.
35022
- */
35023
- signOut: () => Promise<void>;
35024
-
35025
- /**
35026
- * Refresh user data from auth server.
35027
- */
35028
- refreshUser: () => Promise<void>;
35029
- }
35030
-
35031
- const AuthContext = createContext<AuthContextType | undefined>(undefined);
35032
-
35033
- /**
35034
- * Hook to use auth context in your components.
35035
- */
35036
- export function useAuth<T extends UserData = UserData>(): AuthContextType<T> {
35037
- const context = useContext(AuthContext);
35038
- if (!context) {
35039
- throw new Error('useAuth() must be used within <AuthProvider>');
35040
- }
35041
- return context as AuthContextType<T>;
35042
- }
35043
-
35044
- /**
35045
- * Provider component that wraps your app with authentication.
35046
- */
35047
- export function AuthProvider({ children }: { children: React.ReactNode }) {
35048
- // State
35049
- const [user, setUser] = useState<AuthUser | null>(null);
35050
- const [userData, setUserData] = useState<UserData | null>(null);
35051
- const [token, setToken] = useState<string | null>(null);
35052
- const [loading, setLoading] = useState(true);
35053
- const [error, setError] = useState<string | null>(null);
35054
- const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
35055
-
35056
- // Get auth and database services from clefbase
35057
- const auth = getAuth();
35058
- const db = getDatabase();
35059
-
35060
- // \u2500\u2500 Helper: sync user data from database \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35061
-
35062
- const syncUserDataInternal = async (uid: string): Promise<void> => {
35063
- try {
35064
- const doc = await db.collection('users').doc(uid).get();
35065
- if (doc) {
35066
- setUserData(doc as UserData);
35067
- } else {
35068
- // First login - create user doc
35069
- const authUser = auth.currentUser;
35070
- if (authUser) {
35071
- const newUserData: UserData = {
35072
- uid: authUser.uid,
35073
- email: authUser.email,
35074
- displayName: authUser.displayName,
35075
- photoUrl: authUser.photoUrl,
35076
- createdAt: new Date().toISOString(),
35077
- };
35078
- await db.collection('users').doc(uid).set(newUserData);
35079
- setUserData(newUserData);
35080
- }
35081
- }
35082
- } catch (err) {
35083
- console.error('Error syncing user data:', err);
35084
- }
35085
- };
35086
-
35087
- // \u2500\u2500 Initialize on mount \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35088
-
35089
- useEffect(() => {
35090
- const initAuth = async () => {
35091
- try {
35092
- setLoading(true);
35093
-
35094
- const currentUser = auth.currentUser;
35095
- const currentToken = auth.currentToken;
35096
-
35097
- setUser(currentUser);
35098
- setToken(currentToken);
35099
-
35100
- if (currentUser) {
35101
- await syncUserDataInternal(currentUser.uid);
35102
- }
35103
-
35104
- const unsubscribe = auth.onAuthStateChanged(async (newUser) => {
35105
- setUser(newUser);
35106
- if (newUser) {
35107
- setToken(auth.currentToken);
35108
- await syncUserDataInternal(newUser.uid);
35109
- } else {
35110
- setToken(null);
35111
- setUserData(null);
35112
- }
35113
- });
35114
-
35115
- setLoading(false);
35116
-
35117
- return () => unsubscribe();
35118
- } catch (err) {
35119
- console.error('Auth initialization error:', err);
35120
- setLoading(false);
35121
- }
35122
- };
35123
-
35124
- initAuth();
35125
- }, [auth, db]);
35126
-
35127
- // \u2500\u2500 Error handling helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35128
-
35129
- const handleError = (err: unknown): string => {
35130
- if (err instanceof Error) {
35131
- return err.message;
35132
- }
35133
- if (typeof err === 'string') {
35134
- return err;
35135
- }
35136
- return 'An unknown error occurred';
35137
- };
35138
-
35139
- // \u2500\u2500 User data methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35140
-
35141
- const syncUserData = async (): Promise<void> => {
35142
- if (!user) {
35143
- setUserData(null);
35144
- return;
35145
- }
35146
-
35147
- try {
35148
- await syncUserDataInternal(user.uid);
35149
- } catch (err) {
35150
- const message = handleError(err);
35151
- setError(message);
35152
- throw err;
35153
- }
35154
- };
35155
-
35156
- const updateUserData = async (
35157
- updates: Partial<Omit<UserData, 'uid'>>
35158
- ): Promise<void> => {
35159
- if (!user) {
35160
- throw new Error('User not authenticated');
35161
- }
35162
-
35163
- try {
35164
- setError(null);
35165
- setLoading(true);
35166
-
35167
- const authUpdates: Record<string, unknown> = {};
35168
- if ('displayName' in updates) {
35169
- authUpdates.displayName = updates.displayName;
35170
- }
35171
- if ('photoUrl' in updates) {
35172
- authUpdates.photoUrl = updates.photoUrl;
35173
- }
35174
-
35175
- if (Object.keys(authUpdates).length > 0) {
35176
- await auth.updateProfile(authUpdates);
35177
- }
35178
-
35179
- await db.collection('users').doc(user.uid).update(updates);
35180
-
35181
- setUserData((prev) => (prev ? { ...prev, ...updates } : null));
35182
- } catch (err) {
35183
- const message = handleError(err);
35184
- setError(message);
35185
- throw err;
35186
- } finally {
35187
- setLoading(false);
35188
- }
35189
- };
35190
-
35191
- // \u2500\u2500 Auth methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35192
-
35193
- const signOut = async () => {
35194
- try {
35195
- setError(null);
35196
- setLoading(true);
35197
- await auth.signOut();
35198
- setUser(null);
35199
- setToken(null);
35200
- setUserData(null);
35201
- } catch (err) {
35202
- const message = handleError(err);
35203
- setError(message);
35204
- throw err;
35205
- } finally {
35206
- setLoading(false);
35207
- }
35208
- };
35209
-
35210
- const verifyEmail = async (code: string) => {
35211
- try {
35212
- setError(null);
35213
- setLoading(true);
35214
- const result = await auth.verifyEmail(code);
35215
- setUser(result);
35216
- } catch (err) {
35217
- const message = handleError(err);
35218
- setError(message);
35219
- throw err;
35220
- } finally {
35221
- setLoading(false);
35222
- }
35223
- };
35224
-
35225
- const sendPasswordResetEmail = async (email: string) => {
35226
- try {
35227
- setError(null);
35228
- setLoading(true);
35229
- await auth.sendPasswordResetEmail(email);
35230
- } catch (err) {
35231
- const message = handleError(err);
35232
- setError(message);
35233
- throw err;
35234
- } finally {
35235
- setLoading(false);
35236
- }
35237
- };
35238
-
35239
- const refreshUser = async () => {
35240
- try {
35241
- setError(null);
35242
- const updated = await auth.refreshCurrentUser();
35243
- if (updated) setUser(updated);
35244
- } catch (err) {
35245
- const message = handleError(err);
35246
- setError(message);
35247
- throw err;
35248
- }
35249
- };
35250
-
35251
- // \u2500\u2500 Modal management \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35252
-
35253
- const openAuthModal = () => {
35254
- setIsAuthModalOpen(true);
35255
- };
35256
-
35257
- const closeAuthModal = () => {
35258
- setIsAuthModalOpen(false);
35259
- };
35260
-
35261
- // \u2500\u2500 Provider value \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
35262
-
35263
- const value: AuthContextType = {
35264
- user,
35265
- userData,
35266
- token,
35267
- loading,
35268
- error,
35269
- isAuthModalOpen,
35270
- syncUserData,
35271
- updateUserData,
35272
- verifyEmail,
35273
- sendPasswordResetEmail,
35274
- signOut,
35275
- refreshUser,
35276
- openAuthModal,
35277
- closeAuthModal,
35278
- };
35279
-
35280
- return (
35281
- <AuthContext.Provider value={value}>
35282
- {!loading && children}
35283
- </AuthContext.Provider>
35284
- );
35285
- }
35286
-
35287
- /**
35288
- * CUSTOMIZATION GUIDE
35289
- *
35290
- * Extend UserData with custom fields, sync to database, and use useAuth<MyType>().
35291
- */
35292
- `;
35293
- var AUTH_MODAL_FALLBACK = `'use client';
35294
- import React, { useEffect, CSSProperties } from 'react';
35295
- import { useAuth } from '@/context/AuthContext';
35296
-
35297
- export default function AuthModal({ isOpen, onClose, overlayStyle, cardStyle, showCloseButton = true, backdropDismiss = true }: any) {
35298
- const { closeAuthModal } = useAuth();
35299
- const projectId = typeof window !== 'undefined' && (window as any).__CLEFORYX_PROJECT_ID;
35300
-
35301
- useEffect(() => {
35302
- if (!isOpen) return;
35303
- const handleMessage = (e: MessageEvent) => {
35304
- if (e.data?.source === 'cleforyx-auth' && e.data?.type === 'auth_success') {
35305
- closeAuthModal();
35306
- onClose();
35307
- }
35308
- };
35309
- window.addEventListener('message', handleMessage);
35310
- return () => window.removeEventListener('message', handleMessage);
35311
- }, [isOpen, closeAuthModal, onClose]);
35312
-
35313
- if (!isOpen) return null;
35314
-
35315
- const currentUrl = typeof window !== 'undefined' ? window.location.origin : '';
35316
- const iframeUrl = \`https://auth.cleforyx.com/login?project=\${projectId}&redirect=\${encodeURIComponent(currentUrl)}&embed=popup\`;
35317
-
35318
- const defaultOverlayStyle: CSSProperties = {
35319
- position: 'fixed', inset: 0, backgroundColor: 'rgba(15, 23, 42, 0.6)',
35320
- display: 'flex', alignItems: 'center', justifyContent: 'center',
35321
- zIndex: 9999, backdropFilter: 'blur(4px)', padding: '16px', boxSizing: 'border-box',
35322
- };
35323
-
35324
- const defaultCardStyle: CSSProperties = {
35325
- backgroundColor: 'white', borderRadius: '20px',
35326
- boxShadow: '0 24px 64px rgba(0, 0, 0, 0.2)',
35327
- overflow: 'hidden', width: '100%', maxWidth: '460px', position: 'relative',
35328
- };
35329
-
35330
- const handleBackdropClick = (e: React.MouseEvent) => {
35331
- if (backdropDismiss && e.target === e.currentTarget) onClose();
35332
- };
35333
-
35334
- return (
35335
- <div style={{ ...defaultOverlayStyle, ...overlayStyle }} onClick={handleBackdropClick}>
35336
- <div style={{ ...defaultCardStyle, ...cardStyle }}>
35337
- {showCloseButton && (
35338
- <button style={{ position: 'absolute', top: '14px', right: '16px', background: 'rgba(0,0,0,0.06)', border: 'none', width: '28px', height: '28px', borderRadius: '50%', cursor: 'pointer', zIndex: 1 }} onClick={onClose} aria-label="Close">\u2715</button>
35339
- )}
35340
- <iframe src={iframeUrl} style={{ width: '100%', height: '560px', border: 'none', display: 'block' }} title="Sign in" allow="identity-credentials-get" />
35341
- </div>
35342
- </div>
35343
- );
35344
- }`;
35345
- var PROTECTED_ROUTE_FALLBACK = `'use client';
35346
- import React from 'react';
35347
- import { useAuth } from '@/context/AuthContext';
35348
-
35349
- export function ProtectedRoute({ children, LoadingComponent, onUnauthorized }: any) {
35350
- const { user, loading, openAuthModal } = useAuth();
35351
-
35352
- if (loading) {
35353
- if (LoadingComponent) return <LoadingComponent />;
35354
- return <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100vh' }}>Loading...</div>;
35355
- }
35356
-
35357
- if (!user) {
35358
- onUnauthorized?.();
35359
- openAuthModal();
35360
- return null;
35361
- }
35362
-
35363
- return <>{children}</>;
35364
- }`;
35365
34798
 
35366
34799
  // src/cli/commands/deploy.ts
35367
34800
  var import_path3 = __toESM(require("path"));
@@ -36114,7 +35547,7 @@ async function promptRequired(message) {
36114
35547
  }
36115
35548
 
36116
35549
  // package.json
36117
- var version = "2.0.5";
35550
+ var version = "2.0.7";
36118
35551
 
36119
35552
  // src/cli/index.ts
36120
35553
  var program2 = new Command();
package/dist/index.d.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  * // ^ redirects to auth.cleforyx.com, then back to your app with ?cfx_token=
23
23
  *
24
24
  * // 2. On every page load (before rendering):
25
- * const result = await auth.handleGatewayCallback();
25
+ * const result = await auth.handleAuthCallback();
26
26
  * if (result) console.log("Signed in:", result.user.email);
27
27
  *
28
28
  * // ── Database ──────────────────────────────────────────────────────────────
@@ -48,7 +48,7 @@
48
48
  export { ClefbaseApp, initClefbase, getApp, getDatabase, getAuth, getStorage, getHosting, getFunctions, getAI, } from "./app";
49
49
  export { Database, CollectionReference, CollectionGroup, DocumentReference, Query, WriteBatch, Transaction, runTransaction, } from "./db";
50
50
  export { Auth } from "./auth";
51
- export type { GatewaySignInOptions, OpenAuthUIOptions } from "./auth";
51
+ export type { GatewaySignInOptions } from "./auth";
52
52
  export { ClefbaseStorage, StorageReference, BucketReference } from "./storage";
53
53
  export type { StorageFile } from "./storage";
54
54
  export type { StorageImageStatus } from "./react/StorageImage";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,KAAK,GACN,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,MAAM,CAAC;AAEd,YAAY,EACV,OAAO,EACP,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,aAAa,EACb,YAAY,GACb,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,KAAK,GACN,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,MAAM,CAAC;AAEd,YAAY,EACV,OAAO,EACP,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,aAAa,EACb,YAAY,GACb,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@
23
23
  * // ^ redirects to auth.cleforyx.com, then back to your app with ?cfx_token=
24
24
  *
25
25
  * // 2. On every page load (before rendering):
26
- * const result = await auth.handleGatewayCallback();
26
+ * const result = await auth.handleAuthCallback();
27
27
  * if (result) console.log("Signed in:", result.user.email);
28
28
  *
29
29
  * // ── Database ──────────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clefbase",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "Firebase-style SDK and CLI for Clefbase — database, auth, storage, hosting, and functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",