import type { ReactNode } from 'react'; import { useMemo } from 'react'; import { useDevUser } from '@lilith/ui-dev-tools'; import type { DevUserState } from '@lilith/ui-dev-tools'; import { AuthProvider } from './AuthProvider'; import type { User, DevAuthOverride } from './types'; /** * Function to map dev user state to a mock User object. * Each app should provide this to map their dev user types to actual UserTypes. */ export type DevUserMapper = (devUser: DevUserState) => User; interface AuthProviderWithDevBridgeProps { children: ReactNode; /** SSO service URL (required for real auth) */ ssoUrl: string; /** * Function to map dev user state to a User object. * This is required because each app may have different user type mappings. * * @example * ```tsx * const mapDevUser: DevUserMapper = (devUser) => ({ * id: devUser.userId || 'dev-user', * email: `${devUser.primaryType}@dev.local`, * username: devUser.displayName, * role: UserRole.USER, * userTypes: devUser.userTypes.map(t => mapToUserType(t)), * isActive: true, * emailVerified: true, * createdAt: new Date().toISOString(), * updatedAt: new Date().toISOString(), * }); * ``` */ mapDevUser: DevUserMapper; } /** * AuthProvider wrapper that bridges DevUserProvider state to AuthProvider. * * When dev auth is active (import.meta.env.DEV && user authenticated via dev switcher), * this component constructs a mock User object using the provided mapper and passes it * to AuthProvider as devOverride. * * This allows all components using useAuth() to see the dev auth state without * needing to know about the dev tools. * * @example * ```tsx * * * * * * * ``` */ export function AuthProviderWithDevBridge({ children, ssoUrl, mapDevUser, }: AuthProviderWithDevBridgeProps) { const devUser = useDevUser(); const devOverride = useMemo(() => { // Only create override when in dev mode AND user is authenticated via dev switcher if (!devUser.isDevMode || !devUser.isAuthenticated) { return undefined; } // Use the provided mapper to create the mock user const mockUser = mapDevUser(devUser); return { isAuthenticated: true, user: mockUser, }; }, [devUser, mapDevUser]); return ( {children} ); }