@ezcoder.dev/sdk 1.5.0 → 1.6.0
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/{DatabaseProvider-BtYMJRqh.d.ts → DatabaseProvider-DRnx_V_u.d.ts} +7 -0
- package/dist/analytics/index.js +2 -2
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.js +2 -2
- package/dist/{chunk-HX7IFB7C.js → chunk-L326T7UV.js} +35 -5
- package/dist/chunk-L326T7UV.js.map +1 -0
- package/dist/chunk-VHKTBOFU.js +124 -0
- package/dist/chunk-VHKTBOFU.js.map +1 -0
- package/dist/{chunk-RU2GHN7O.js → chunk-WFDQ4YUZ.js} +447 -124
- package/dist/chunk-WFDQ4YUZ.js.map +1 -0
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +9 -8
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -7
- package/dist/notifications/index.js +2 -2
- package/dist/payments/index.d.ts +1 -1
- package/dist/payments/index.js +2 -2
- package/dist/roles/index.js +34 -11
- package/dist/roles/index.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js +2 -2
- package/dist/{types-1uP3V_pe.d.ts → types-BET19sj2.d.ts} +1 -0
- package/package.json +1 -1
- package/dist/chunk-HX7IFB7C.js.map +0 -1
- package/dist/chunk-OIAKVQGD.js +0 -389
- package/dist/chunk-OIAKVQGD.js.map +0 -1
- package/dist/chunk-RU2GHN7O.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/bootstrap.ts","../src/core/platform.ts","../src/database/errors.ts","../src/database/QueryBuilder.ts","../src/database/DatabaseClient.ts"],"sourcesContent":["/**\n * Runtime config bootstrap (Parity Doctrine W2).\n *\n * The SDK fetches /api/sdk/bootstrap ONCE at startup and overlays the result on\n * the build-time-baked `env`. This means a bundle that baked NO env (the\n * herdmark \"loads but crashes on boot\" class) still works — it learns its\n * config live — and preview and deployed take the identical path.\n *\n * Resolution order for any config value: runtime bootstrap → baked env. The\n * baked env is the OFFLINE FALLBACK, never the primary source. Secrets never\n * appear here — the endpoint returns public config only.\n */\n\nimport { env } from './config';\n\nexport interface RuntimeConfig {\n projectId: string;\n apiUrl: string;\n authUrl: string | null;\n authAnonKey: string | null;\n supabaseUrl: string | null;\n supabaseAnonKey: string | null;\n stripePublishableKey: string | null;\n storageBucketPublic: string | null;\n storageBucketPrivate: string | null;\n publicToken: string | null;\n manifest: unknown | null;\n}\n\nlet cached: RuntimeConfig | null = null;\nlet inflight: Promise<RuntimeConfig | null> | null = null;\n\n/** The base URL of the platform API. Baked value is the offline fallback. */\nfunction apiBase(): string {\n return (env.EZCODER_API_URL || 'https://ezcoder.dev').replace(/\\/$/, '');\n}\n\n/**\n * Fetch the runtime config once (coalesced). Safe to call from multiple\n * providers — only one network request is made. Never throws: on failure it\n * returns null and the SDK falls back to baked env.\n *\n * @param opts.force re-fetch even if cached\n */\nexport async function loadBootstrap(opts: { force?: boolean } = {}): Promise<RuntimeConfig | null> {\n if (cached && !opts.force) return cached;\n if (inflight && !opts.force) return inflight;\n if (typeof fetch === 'undefined') return null;\n\n inflight = (async () => {\n try {\n const headers: Record<string, string> = {};\n // If a token IS baked, send it so the endpoint resolves the project even\n // off a non-deployment origin (e.g. preview). Otherwise the endpoint\n // resolves by origin — no baked config required.\n const tok = env.EZC_PROJECT_TOKEN_PUBLIC || env.EZC_PROJECT_TOKEN_LEGACY || '';\n if (tok) headers['X-EzCoder-Public-Token'] = tok;\n // Pass the baked projectId as a preview fallback (honored only for trusted origins server-side).\n const qs = env.EZC_PROJECT_ID ? `?projectId=${encodeURIComponent(env.EZC_PROJECT_ID)}` : '';\n const res = await fetch(`${apiBase()}/api/sdk/bootstrap${qs}`, { method: 'GET', headers });\n if (!res.ok) return null;\n const body = await res.json().catch(() => null);\n if (!body?.success || !body.config?.projectId) return null;\n cached = body.config as RuntimeConfig;\n return cached;\n } catch {\n return null;\n } finally {\n inflight = null;\n }\n })();\n return inflight;\n}\n\n/** The loaded runtime config, or null if not yet loaded / unavailable. */\nexport function getRuntimeConfig(): RuntimeConfig | null {\n return cached;\n}\n\n/** Test seam. */\nexport function _resetBootstrap(): void {\n cached = null;\n inflight = null;\n}\n\n/**\n * Resolve a config value preferring runtime bootstrap over baked env. Use this\n * for any SDK-critical value so an env-less build still resolves it at runtime.\n */\nexport function configValue<K extends keyof RuntimeConfig>(key: K, bakedFallback: string): string {\n const rc = cached;\n const v = rc ? rc[key] : null;\n return (typeof v === 'string' && v) ? v : bakedFallback;\n}\n","import { env } from './config';\r\nimport type { AnalyticsResult, CheckoutOptions, EzcoderClient, AuthIntegration, AuthUser } from './types';\r\n\r\nconst isConfigured = (): boolean => Boolean(env.EZCODER_API_URL && env.EZC_PROJECT_ID);\r\n\r\nfunction getSessionId(): string {\r\n if (typeof sessionStorage === 'undefined') return 'server';\r\n let sessionId = sessionStorage.getItem('ezcoder_session_id');\r\n if (!sessionId) {\r\n sessionId = `sess_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n sessionStorage.setItem('ezcoder_session_id', sessionId);\r\n }\r\n return sessionId;\r\n}\r\n\r\nfunction getVisitorId(): string {\r\n if (typeof localStorage === 'undefined') return 'server';\r\n let visitorId = localStorage.getItem('ezcoder_visitor_id');\r\n if (!visitorId) {\r\n visitorId = `vis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n localStorage.setItem('ezcoder_visitor_id', visitorId);\r\n }\r\n return visitorId;\r\n}\r\n\r\nlet pageEntryTime: number = typeof window !== 'undefined' ? Date.now() : 0;\r\nlet currentPath: string = typeof window !== 'undefined' ? window.location.pathname : '/';\r\nlet maxScrollDepth: number = 0;\r\n\r\nconst trackPageEntry = (): void => {\r\n pageEntryTime = Date.now();\r\n currentPath = window.location.pathname;\r\n maxScrollDepth = 0;\r\n};\r\n\r\nconst getTimeOnPage = (): number => Date.now() - pageEntryTime;\r\n\r\nconst throttle = <T extends (...args: never[]) => void>(fn: T, wait: number): ((...args: Parameters<T>) => void) => {\r\n let lastTime = 0;\r\n return (...args: Parameters<T>) => {\r\n const now = Date.now();\r\n if (now - lastTime >= wait) {\r\n lastTime = now;\r\n fn(...args);\r\n }\r\n };\r\n};\r\n\r\nconst trackScrollDepth = (): void => {\r\n if (typeof window === 'undefined') return;\r\n const scrollTop = window.scrollY;\r\n const docHeight = document.documentElement.scrollHeight - window.innerHeight;\r\n if (docHeight > 0) {\r\n const scrollPercent = Math.round((scrollTop / docHeight) * 100);\r\n if (scrollPercent > maxScrollDepth) {\r\n maxScrollDepth = Math.min(scrollPercent, 100);\r\n }\r\n }\r\n};\r\n\r\nconst analyticsPost = async (endpoint: string, body: Record<string, unknown>): Promise<AnalyticsResult> => {\r\n if (!isConfigured()) {\r\n return { success: false, error: 'Platform not configured' };\r\n }\r\n\r\n try {\r\n const response = await fetch(`${env.EZCODER_API_URL}${endpoint}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.text();\r\n return { success: false, error };\r\n }\r\n\r\n return await response.json();\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'Unknown error';\r\n return { success: false, error: message };\r\n }\r\n};\r\n\r\nconst stripePost = async (endpoint: string, body: Record<string, unknown>): Promise<AnalyticsResult & Record<string, unknown>> => {\r\n if (!env.EZCODER_API_URL) {\r\n return { success: false, error: 'Platform not configured' };\r\n }\r\n\r\n if (!env.EZC_SECRET_KEY) {\r\n return {\r\n success: false,\r\n error: 'Payment configuration incomplete. The site owner needs to redeploy from EzCoder to enable checkout.',\r\n };\r\n }\r\n\r\n try {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${env.EZC_SECRET_KEY}`,\r\n };\r\n\r\n const response = await fetch(`${env.EZCODER_API_URL}${endpoint}`, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.text();\r\n return { success: false, error };\r\n }\r\n\r\n return await response.json();\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'Unknown error';\r\n return { success: false, error: message };\r\n }\r\n};\r\n\r\nconst stripeGet = async (endpoint: string): Promise<AnalyticsResult & Record<string, unknown>> => {\r\n if (!env.EZCODER_API_URL) {\r\n return { success: false, error: 'Platform not configured' };\r\n }\r\n\r\n try {\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (env.EZC_SECRET_KEY) {\r\n headers['Authorization'] = `Bearer ${env.EZC_SECRET_KEY}`;\r\n }\r\n\r\n const response = await fetch(`${env.EZCODER_API_URL}${endpoint}`, {\r\n method: 'GET',\r\n headers,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.text();\r\n return { success: false, error };\r\n }\r\n\r\n return await response.json();\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'Unknown error';\r\n return { success: false, error: message };\r\n }\r\n};\r\n\r\nconst sendPageExit = (): void => {\r\n if (!isConfigured() || typeof navigator === 'undefined') return;\r\n\r\n const payload = JSON.stringify({\r\n type: 'page_exit',\r\n projectId: env.EZC_PROJECT_ID,\r\n sessionId: getSessionId(),\r\n visitorId: getVisitorId(),\r\n pathname: currentPath,\r\n timeOnPage: getTimeOnPage(),\r\n scrollDepth: maxScrollDepth,\r\n timestamp: new Date().toISOString(),\r\n });\r\n\r\n if (navigator.sendBeacon) {\r\n navigator.sendBeacon(`${env.EZCODER_API_URL}/api/analytics/collect`, payload);\r\n }\r\n};\r\n\r\nexport const ezcoder: EzcoderClient = {\r\n isConfigured,\r\n\r\n analytics: {\r\n track: (eventType: string, properties: Record<string, unknown> = {}) => {\r\n return analyticsPost('/api/analytics/collect', {\r\n type: eventType,\r\n projectId: env.EZC_PROJECT_ID,\r\n sessionId: getSessionId(),\r\n visitorId: getVisitorId(),\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n pathname: typeof window !== 'undefined' ? window.location.pathname : '/',\r\n referrer: typeof document !== 'undefined' ? document.referrer : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n screenResolution: typeof window !== 'undefined'\r\n ? `${window.screen.width}x${window.screen.height}`\r\n : '',\r\n viewport: typeof window !== 'undefined'\r\n ? `${window.innerWidth}x${window.innerHeight}`\r\n : '',\r\n timestamp: new Date().toISOString(),\r\n metadata: properties,\r\n });\r\n },\r\n\r\n pageView: (path?: string) => {\r\n trackPageEntry();\r\n return ezcoder.analytics.track('page_view', {\r\n path: path || (typeof window !== 'undefined' ? window.location.pathname : '/'),\r\n title: typeof document !== 'undefined' ? document.title : '',\r\n });\r\n },\r\n\r\n identify: (userId: string, traits: Record<string, unknown> = {}) => {\r\n return ezcoder.analytics.track('identify', { userId, ...traits });\r\n },\r\n\r\n error: (message: string, context: Record<string, unknown> = {}) => {\r\n return ezcoder.analytics.track('error', {\r\n message,\r\n ...context,\r\n stack: (context.stack as string) || new Error().stack,\r\n });\r\n },\r\n },\r\n\r\n stripe: {\r\n createCheckout: async (priceId: string, options: CheckoutOptions = {}) => {\r\n const result = await stripePost('/api/stripe/create-checkout', {\r\n priceId,\r\n projectId: env.EZC_PROJECT_ID,\r\n successUrl: options.successUrl || `${typeof window !== 'undefined' ? window.location.origin : ''}/payment/success`,\r\n cancelUrl: options.cancelUrl || `${typeof window !== 'undefined' ? window.location.origin : ''}/payment/cancel`,\r\n customerEmail: options.customerEmail,\r\n quantity: options.quantity || 1,\r\n });\r\n\r\n if (result.url && options.redirect !== false && typeof window !== 'undefined') {\r\n window.location.href = result.url as string;\r\n }\r\n\r\n return result;\r\n },\r\n\r\n getProducts: async () => {\r\n return { products: [], message: 'Products managed via EzCoder dashboard' };\r\n },\r\n\r\n verifySession: async (sessionId: string) => {\r\n if (!sessionId) {\r\n return { success: false, error: 'Session ID is required' };\r\n }\r\n return stripeGet(`/api/stripe/verify-session?session_id=${encodeURIComponent(sessionId)}`);\r\n },\r\n\r\n getCustomerStatus: async (options: { customerId?: string; email?: string } = {}) => {\r\n const params = new URLSearchParams();\r\n if (options.customerId) params.set('customer_id', options.customerId);\r\n if (options.email) params.set('email', options.email);\r\n\r\n if (!options.customerId && !options.email) {\r\n return { success: false, error: 'Either customerId or email is required' };\r\n }\r\n\r\n return stripeGet(`/api/stripe/customer-status?${params.toString()}`);\r\n },\r\n\r\n createPortalSession: async (customerId: string, options: { returnUrl?: string; redirect?: boolean } = {}) => {\r\n const result = await stripePost('/api/stripe/customer-portal', {\r\n customerId,\r\n returnUrl: options.returnUrl || window.location.href,\r\n });\r\n\r\n if (result.url && options.redirect !== false && typeof window !== 'undefined') {\r\n window.location.href = result.url as string;\r\n }\r\n\r\n return result;\r\n },\r\n\r\n getInvoices: async (customerId: string, options: { limit?: number } = {}) => {\r\n const params = new URLSearchParams();\r\n params.set('customer_id', customerId);\r\n if (options.limit) params.set('limit', String(options.limit));\r\n return stripeGet(`/api/stripe/invoices?${params.toString()}`);\r\n },\r\n },\r\n\r\n users: {\r\n trackSignup: (userId: string, email: string, role: string | null = null) => {\r\n return ezcoder.analytics.track('user_signup', { userId, email, role, signupMethod: 'email' });\r\n },\r\n\r\n trackLogin: (userId: string) => {\r\n return ezcoder.analytics.track('user_login', { userId });\r\n },\r\n\r\n trackLogout: (userId: string) => {\r\n return ezcoder.analytics.track('user_logout', { userId });\r\n },\r\n\r\n trackRoleChange: (userId: string, oldRole: string, newRole: string) => {\r\n return ezcoder.analytics.track('role_change', { userId, oldRole, newRole });\r\n },\r\n },\r\n};\r\n\r\nexport const ezcoderAuthIntegration: AuthIntegration = {\r\n onLogin: (user: AuthUser) => {\r\n if (user?.id) {\r\n ezcoder.analytics.identify(user.id, {\r\n email: user.email,\r\n name: user.user_metadata?.full_name,\r\n });\r\n ezcoder.users.trackLogin(user.id);\r\n }\r\n },\r\n onSignup: (user: AuthUser) => {\r\n if (user?.id) {\r\n ezcoder.analytics.identify(user.id, { email: user.email });\r\n ezcoder.users.trackSignup(user.id, user.email || '');\r\n }\r\n },\r\n onLogout: (userId: string) => {\r\n if (userId) {\r\n ezcoder.users.trackLogout(userId);\r\n }\r\n },\r\n};\r\n\r\ninterface LayoutShift extends PerformanceEntry {\r\n hadRecentInput: boolean;\r\n value: number;\r\n}\r\n\r\ninterface PerformanceEventTiming extends PerformanceEntry {\r\n processingStart: number;\r\n}\r\n\r\nconst trackWebVitals = (): void => {\r\n if (typeof window === 'undefined' || !('PerformanceObserver' in window)) return;\r\n\r\n try {\r\n new PerformanceObserver((list) => {\r\n const entries = list.getEntries();\r\n const lastEntry = entries[entries.length - 1];\r\n if (lastEntry) {\r\n ezcoder.analytics.track('web_vital', {\r\n metric: 'LCP',\r\n value: Math.round(lastEntry.startTime),\r\n pathname: window.location.pathname,\r\n });\r\n }\r\n }).observe({ type: 'largest-contentful-paint', buffered: true });\r\n } catch { /* LCP not supported */ }\r\n\r\n try {\r\n new PerformanceObserver((list) => {\r\n const entry = list.getEntries()[0] as PerformanceEventTiming;\r\n if (entry) {\r\n ezcoder.analytics.track('web_vital', {\r\n metric: 'FID',\r\n value: Math.round(entry.processingStart - entry.startTime),\r\n pathname: window.location.pathname,\r\n });\r\n }\r\n }).observe({ type: 'first-input', buffered: true });\r\n } catch { /* FID not supported */ }\r\n\r\n try {\r\n let clsValue = 0;\r\n new PerformanceObserver((list) => {\r\n for (const entry of list.getEntries()) {\r\n if (!(entry as LayoutShift).hadRecentInput) {\r\n clsValue += (entry as LayoutShift).value;\r\n }\r\n }\r\n }).observe({ type: 'layout-shift', buffered: true });\r\n\r\n document.addEventListener('visibilitychange', () => {\r\n if (document.hidden && clsValue > 0) {\r\n ezcoder.analytics.track('web_vital', {\r\n metric: 'CLS',\r\n value: Math.round(clsValue * 1000) / 1000,\r\n pathname: window.location.pathname,\r\n });\r\n }\r\n });\r\n } catch { /* CLS not supported */ }\r\n};\r\n\r\nconst setupErrorTracking = (): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n window.onerror = (message, source, lineno, colno, error) => {\r\n ezcoder.analytics.track('js_error', {\r\n message: String(message),\r\n source,\r\n lineno,\r\n colno,\r\n stack: error?.stack,\r\n pathname: window.location.pathname,\r\n });\r\n return false;\r\n };\r\n\r\n window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent) => {\r\n ezcoder.analytics.track('promise_rejection', {\r\n reason: event.reason?.message || String(event.reason),\r\n stack: event.reason?.stack,\r\n pathname: window.location.pathname,\r\n });\r\n });\r\n};\r\n\r\nif (typeof window !== 'undefined') {\r\n window.addEventListener('scroll', throttle(trackScrollDepth, 500), { passive: true });\r\n window.addEventListener('beforeunload', sendPageExit);\r\n\r\n document.addEventListener('visibilitychange', () => {\r\n if (!isConfigured()) return;\r\n if (document.hidden) {\r\n ezcoder.analytics.track('page_blur', {\r\n timeOnPage: getTimeOnPage(),\r\n scrollDepth: maxScrollDepth,\r\n pathname: currentPath,\r\n });\r\n } else {\r\n ezcoder.analytics.track('page_focus', { pathname: window.location.pathname });\r\n }\r\n });\r\n\r\n const originalPushState = history.pushState;\r\n history.pushState = function (...args: Parameters<typeof history.pushState>) {\r\n sendPageExit();\r\n originalPushState.apply(this, args);\r\n trackPageEntry();\r\n if (isConfigured()) ezcoder.analytics.pageView();\r\n };\r\n\r\n const originalReplaceState = history.replaceState;\r\n history.replaceState = function (...args: Parameters<typeof history.replaceState>) {\r\n originalReplaceState.apply(this, args);\r\n trackPageEntry();\r\n };\r\n\r\n window.addEventListener('popstate', () => {\r\n sendPageExit();\r\n trackPageEntry();\r\n if (isConfigured()) ezcoder.analytics.pageView();\r\n });\r\n\r\n if (isConfigured()) {\r\n setTimeout(() => {\r\n ezcoder.analytics.pageView();\r\n trackWebVitals();\r\n setupErrorTracking();\r\n }, 100);\r\n }\r\n\r\n // EZCODER_SECRET_KEY is a SERVER-ONLY secret (never prefixed VITE_/NEXT_PUBLIC_),\r\n // so it is legitimately absent in the browser bundle — warning there is a false\r\n // positive that spams every visitor's console. Only warn on the server.\r\n if (typeof window === 'undefined' && env.EZCODER_API_URL && !env.EZC_SECRET_KEY) {\r\n console.warn(\r\n '[EzCoder SDK] EZCODER_SECRET_KEY is not set — Stripe checkout and authenticated API calls will fail. ' +\r\n 'Redeploy your project from the EzCoder editor to auto-provision keys.'\r\n );\r\n }\r\n}\r\n","export class DatabaseError extends Error {\r\n readonly code: string;\r\n readonly statusCode: number;\r\n\r\n constructor(message: string, code = 'DATABASE_ERROR', statusCode = 500) {\r\n super(message);\r\n this.name = 'DatabaseError';\r\n this.code = code;\r\n this.statusCode = statusCode;\r\n }\r\n}\r\n\r\nexport class QueryError extends DatabaseError {\r\n readonly sql?: string;\r\n\r\n constructor(message: string, sql?: string) {\r\n super(message, 'QUERY_ERROR', 400);\r\n this.name = 'QueryError';\r\n this.sql = sql;\r\n }\r\n}\r\n\r\nexport class ValidationError extends DatabaseError {\r\n constructor(message: string) {\r\n super(message, 'VALIDATION_ERROR', 422);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\nexport class ConnectionError extends DatabaseError {\r\n constructor(message: string) {\r\n super(message, 'CONNECTION_ERROR', 503);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\nexport class NotFoundError extends DatabaseError {\r\n constructor(message = 'Record not found') {\r\n super(message, 'NOT_FOUND', 404);\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\nexport function mapRpcError(rpcResult: { success: boolean; error?: string; code?: string }): DatabaseError | null {\r\n if (rpcResult.success) return null;\r\n const msg = rpcResult.error || 'Unknown database error';\r\n if (msg.includes('No database schema exists')) return new NotFoundError(msg);\r\n if (msg.includes('Authentication required')) return new ConnectionError(msg);\r\n if (msg.includes('blocked') || msg.includes('forbidden')) return new ValidationError(msg);\r\n return new QueryError(msg);\r\n}\r\n","import type { SupabaseClient } from '@supabase/supabase-js';\r\nimport type { DatabaseResult, SingleResult, MutationResult, FilterValue, OrderOption } from './types';\r\nimport { QueryError, ValidationError, mapRpcError } from './errors';\r\n\r\nfunction escapeSqlValue(value: FilterValue): string {\r\n if (value === null) return 'NULL';\r\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\r\n if (typeof value === 'number') {\r\n if (!Number.isFinite(value)) throw new ValidationError('Non-finite numbers are not allowed');\r\n return String(value);\r\n }\r\n return `'${String(value).replace(/'/g, \"''\")}'`;\r\n}\r\n\r\nfunction escapeIdentifier(name: string): string {\r\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\r\n throw new ValidationError(`Invalid identifier: ${name}`);\r\n }\r\n return `\"${name}\"`;\r\n}\r\n\r\n/**\r\n * Validate a .select() column list. The list is concatenated into the SELECT\r\n * clause, so it must not be able to break out of the column position. We allow\r\n * the shapes generated apps actually use — column names, dotted refs, double-\r\n * quoted idents, `AS` aliases, commas, `*`, and simple function calls like\r\n * count(*) — but reject statement terminators, comment markers, and nested\r\n * sub-SELECTs that would change the query's meaning (security review finding 3).\r\n */\r\nfunction assertSafeSelectColumns(columns: string): void {\r\n if (columns === '*') return;\r\n if (/[;]|--|\\/\\*|\\*\\//.test(columns)) {\r\n throw new ValidationError('select() columns may not contain statement separators or comments');\r\n }\r\n if (/\\bselect\\b/i.test(columns)) {\r\n throw new ValidationError('select() columns may not contain a sub-SELECT');\r\n }\r\n // Allowed character set: identifiers, dots, commas, whitespace, parens, star,\r\n // quotes (for quoted idents / string-literal aliases). No operators that\r\n // enable injection (e.g. semicolons handled above).\r\n if (!/^[A-Za-z0-9_.,*()\\s\"']+$/.test(columns)) {\r\n throw new ValidationError('select() columns contain unsupported characters');\r\n }\r\n}\r\n\r\ntype Operation = 'select' | 'insert' | 'update' | 'delete' | 'count' | 'upsert';\r\n\r\ninterface Filter {\r\n column: string;\r\n op: string;\r\n value: FilterValue | FilterValue[];\r\n}\r\n\r\nexport interface ServerProxy {\r\n serverQuery?: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n serverExec?: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n}\r\n\r\nexport class QueryBuilder<T = Record<string, unknown>> {\r\n private readonly supabase: SupabaseClient;\r\n private readonly projectId: string;\r\n private readonly table: string;\r\n private readonly serverProxy?: ServerProxy;\r\n\r\n private operation: Operation = 'select';\r\n private selectColumns = '*';\r\n private filters: Filter[] = [];\r\n private orderClauses: string[] = [];\r\n private limitValue: number | null = null;\r\n private offsetValue: number | null = null;\r\n private insertData: Record<string, FilterValue>[] | null = null;\r\n private updateData: Record<string, FilterValue> | null = null;\r\n private upsertConflict: string | null = null;\r\n private singleMode = false;\r\n private maybeSingleMode = false;\r\n\r\n constructor(supabase: SupabaseClient, projectId: string, table: string, serverProxy?: ServerProxy) {\r\n this.supabase = supabase;\r\n this.projectId = projectId;\r\n this.table = table;\r\n this.serverProxy = serverProxy;\r\n }\r\n\r\n select(columns = '*'): this {\r\n assertSafeSelectColumns(columns);\r\n this.operation = 'select';\r\n this.selectColumns = columns;\r\n return this;\r\n }\r\n\r\n // --- Filters ---\r\n\r\n eq(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '=', value });\r\n return this;\r\n }\r\n\r\n neq(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '!=', value });\r\n return this;\r\n }\r\n\r\n gt(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '>', value });\r\n return this;\r\n }\r\n\r\n lt(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '<', value });\r\n return this;\r\n }\r\n\r\n gte(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '>=', value });\r\n return this;\r\n }\r\n\r\n lte(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '<=', value });\r\n return this;\r\n }\r\n\r\n like(column: string, pattern: string): this {\r\n this.filters.push({ column, op: 'LIKE', value: pattern });\r\n return this;\r\n }\r\n\r\n ilike(column: string, pattern: string): this {\r\n this.filters.push({ column, op: 'ILIKE', value: pattern });\r\n return this;\r\n }\r\n\r\n in(column: string, values: FilterValue[]): this {\r\n this.filters.push({ column, op: 'IN', value: values });\r\n return this;\r\n }\r\n\r\n is(column: string, value: null | boolean): this {\r\n this.filters.push({ column, op: 'IS', value });\r\n return this;\r\n }\r\n\r\n // --- Ordering & Pagination ---\r\n\r\n order(column: string, options: OrderOption = {}): this {\r\n const dir = options.ascending === false ? 'DESC' : 'ASC';\r\n const nulls = options.nullsFirst ? 'NULLS FIRST' : 'NULLS LAST';\r\n this.orderClauses.push(`${escapeIdentifier(column)} ${dir} ${nulls}`);\r\n return this;\r\n }\r\n\r\n limit(count: number): this {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n offset(count: number): this {\r\n this.offsetValue = count;\r\n return this;\r\n }\r\n\r\n // --- Mutations ---\r\n\r\n insert(records: Record<string, FilterValue> | Record<string, FilterValue>[]): this {\r\n this.operation = 'insert';\r\n this.insertData = Array.isArray(records) ? records : [records];\r\n return this;\r\n }\r\n\r\n update(values: Record<string, FilterValue>): this {\r\n this.operation = 'update';\r\n this.updateData = values;\r\n return this;\r\n }\r\n\r\n delete(): this {\r\n this.operation = 'delete';\r\n return this;\r\n }\r\n\r\n upsert(records: Record<string, FilterValue> | Record<string, FilterValue>[], options?: { onConflict?: string }): this {\r\n this.operation = 'upsert';\r\n this.insertData = Array.isArray(records) ? records : [records];\r\n this.upsertConflict = options?.onConflict || null;\r\n return this;\r\n }\r\n\r\n // --- Result Helpers ---\r\n\r\n count(): QueryBuilder<{ count: number }> {\r\n this.operation = 'count';\r\n return this as unknown as QueryBuilder<{ count: number }>;\r\n }\r\n\r\n single(): QueryBuilder<T> {\r\n this.singleMode = true;\r\n this.limitValue = 1;\r\n return this;\r\n }\r\n\r\n maybeSingle(): QueryBuilder<T> {\r\n this.maybeSingleMode = true;\r\n this.limitValue = 1;\r\n return this;\r\n }\r\n\r\n // --- SQL Building ---\r\n\r\n private buildWhereClause(): string {\r\n if (this.filters.length === 0) return '';\r\n const conditions = this.filters.map((f) => {\r\n const col = escapeIdentifier(f.column);\r\n if (f.op === 'IS') {\r\n const val = f.value === null ? 'NULL' : f.value ? 'TRUE' : 'FALSE';\r\n return `${col} IS ${val}`;\r\n }\r\n if (f.op === 'IN') {\r\n const vals = (f.value as FilterValue[]).map(escapeSqlValue).join(', ');\r\n return `${col} IN (${vals})`;\r\n }\r\n return `${col} ${f.op} ${escapeSqlValue(f.value as FilterValue)}`;\r\n });\r\n return ` WHERE ${conditions.join(' AND ')}`;\r\n }\r\n\r\n private buildSelectSql(): string {\r\n let sql = `SELECT ${this.selectColumns} FROM \"${this.table}\"`;\r\n sql += this.buildWhereClause();\r\n if (this.orderClauses.length > 0) sql += ` ORDER BY ${this.orderClauses.join(', ')}`;\r\n if (this.limitValue !== null) sql += ` LIMIT ${this.limitValue}`;\r\n if (this.offsetValue !== null && this.offsetValue > 0) sql += ` OFFSET ${this.offsetValue}`;\r\n return sql;\r\n }\r\n\r\n private buildCountSql(): string {\r\n let sql = `SELECT COUNT(*) as count FROM \"${this.table}\"`;\r\n sql += this.buildWhereClause();\r\n return sql;\r\n }\r\n\r\n private buildInsertSql(): string {\r\n if (!this.insertData || this.insertData.length === 0) {\r\n throw new ValidationError('No data provided for insert');\r\n }\r\n const columns = Object.keys(this.insertData[0]);\r\n const colList = columns.map(escapeIdentifier).join(', ');\r\n const rows = this.insertData.map(\r\n (row) => `(${columns.map((c) => escapeSqlValue(row[c] ?? null)).join(', ')})`\r\n );\r\n return `INSERT INTO \"${this.table}\" (${colList}) VALUES ${rows.join(', ')}`;\r\n }\r\n\r\n private buildUpsertSql(): string {\r\n let sql = this.buildInsertSql();\r\n const conflict = this.upsertConflict || 'id';\r\n const columns = Object.keys(this.insertData![0]);\r\n const updateCols = columns\r\n .filter((c) => c !== conflict)\r\n .map((c) => `${escapeIdentifier(c)} = EXCLUDED.${escapeIdentifier(c)}`)\r\n .join(', ');\r\n sql += ` ON CONFLICT (${escapeIdentifier(conflict)}) DO UPDATE SET ${updateCols}`;\r\n return sql;\r\n }\r\n\r\n private buildUpdateSql(): string {\r\n if (!this.updateData || Object.keys(this.updateData).length === 0) {\r\n throw new ValidationError('No data provided for update');\r\n }\r\n if (this.filters.length === 0) {\r\n throw new ValidationError('UPDATE without filters is not allowed — add .eq() or other filters');\r\n }\r\n const setClauses = Object.entries(this.updateData)\r\n .map(([col, val]) => `${escapeIdentifier(col)} = ${escapeSqlValue(val)}`)\r\n .join(', ');\r\n return `UPDATE \"${this.table}\" SET ${setClauses}${this.buildWhereClause()}`;\r\n }\r\n\r\n private buildDeleteSql(): string {\r\n if (this.filters.length === 0) {\r\n throw new ValidationError('DELETE without filters is not allowed — add .eq() or other filters');\r\n }\r\n return `DELETE FROM \"${this.table}\"${this.buildWhereClause()}`;\r\n }\r\n\r\n // --- Execution ---\r\n\r\n private async executeQuery(): Promise<DatabaseResult<T>> {\r\n const isRead = this.operation === 'select' || this.operation === 'count';\r\n\r\n let sql: string;\r\n switch (this.operation) {\r\n case 'select': sql = this.buildSelectSql(); break;\r\n case 'count': sql = this.buildCountSql(); break;\r\n case 'insert': sql = this.buildInsertSql(); break;\r\n case 'upsert': sql = this.buildUpsertSql(); break;\r\n case 'update': sql = this.buildUpdateSql(); break;\r\n case 'delete': sql = this.buildDeleteSql(); break;\r\n default: throw new QueryError(`Unknown operation: ${this.operation}`);\r\n }\r\n\r\n // ONE path (Parity Doctrine W1): every read/write goes through the platform\r\n // proxy. The DatabaseClient supplies serverQuery/serverExec, which attach the\r\n // right credential (end-user JWT → token → origin) — identical in preview and\r\n // deployed, so there is no environment branching here.\r\n const fn = isRead ? this.serverProxy?.serverQuery : this.serverProxy?.serverExec;\r\n if (!fn) throw new QueryError('Database client is not configured', sql);\r\n const data = await fn(sql);\r\n if (!data.success) {\r\n const dbError = mapRpcError(data);\r\n if (dbError) throw dbError;\r\n throw new QueryError(data.error || 'Query failed', sql);\r\n }\r\n return {\r\n success: true,\r\n data: (isRead ? data.data || [] : []) as T[],\r\n rowCount: data.rowCount ?? (isRead ? (data.data?.length || 0) : 0),\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n then<TResult1 = DatabaseResult<T> | SingleResult<T>, TResult2 = never>(\r\n onfulfilled?: ((value: DatabaseResult<T> | SingleResult<T>) => TResult1 | PromiseLike<TResult1>) | null,\r\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\r\n ): Promise<TResult1 | TResult2> {\r\n const promise = this.executeQuery().then((result) => {\r\n if (this.singleMode) {\r\n if (result.data.length === 0) {\r\n throw new QueryError('Expected exactly one row, got 0');\r\n }\r\n return { success: true, data: result.data[0], error: undefined } as SingleResult<T>;\r\n }\r\n if (this.maybeSingleMode) {\r\n return {\r\n success: true,\r\n data: result.data.length > 0 ? result.data[0] : null,\r\n error: undefined,\r\n } as SingleResult<T>;\r\n }\r\n return result;\r\n });\r\n return promise.then(onfulfilled, onrejected);\r\n }\r\n}\r\n","import type { SupabaseClient } from '@supabase/supabase-js';\nimport type { DatabaseResult, MutationResult, SchemaInfo } from './types';\nimport { QueryBuilder } from './QueryBuilder';\nimport { QueryError, ConnectionError } from './errors';\nimport { ezcoder } from '../core/platform';\nimport { features, env, isNeonAuthConfigured } from '../core/config';\nimport { getRuntimeConfig } from '../core/bootstrap';\n\nfunction trackDbEvent(event: string, props: Record<string, unknown>) {\n if (!features.analytics) return;\n try { ezcoder.analytics.track(event, props); } catch { /* non-critical */ }\n}\n\n// In-memory Neon session JWT cache (browser). Better Auth's jwt plugin mints a\n// short-lived JWT from the HttpOnly session cookie at `${NEON_AUTH_URL}/token`.\n// We cache it with its decoded `exp` and refresh ~30s early so the platform DB\n// proxy always receives a fresh bearer (RLS runs under the end user's identity).\nlet cachedNeonJwt: { token: string; exp: number } | null = null;\nconst NEON_JWT_REFRESH_SKEW_MS = 30_000;\n\n/** Decode a JWT's `exp` (seconds since epoch) without verifying the signature.\n * Returns 0 when the token is malformed or carries no exp. Browser-safe (atob). */\nfunction decodeJwtExp(token: string): number {\n try {\n const parts = token.split('.');\n if (parts.length < 2) return 0;\n let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n while (b64.length % 4) b64 += '=';\n const json = typeof atob === 'function'\n ? atob(b64)\n : Buffer.from(b64, 'base64').toString('binary');\n const payload = JSON.parse(json) as { exp?: number };\n return typeof payload.exp === 'number' ? payload.exp : 0;\n } catch {\n return 0;\n }\n}\n\ninterface ProxyResult {\n success: boolean;\n data?: unknown[];\n rowCount?: number;\n error?: string;\n schema?: string;\n exists?: boolean;\n tables?: unknown[];\n tablesCount?: number;\n createdAt?: string;\n lastAccessedAt?: string;\n executed_sql?: string;\n}\n\nconst MAX_RETRIES = 3;\nconst SERVER_TIMEOUT_MS = 8000;\n\n/**\n * ONE data path (Parity Doctrine W1). Every database call — preview & deployed,\n * read & write, anonymous & authenticated, browser & server — goes through the\n * platform proxy `/api/platform/db/{projectId}/{query|execute|schema}`. The\n * ONLY thing that varies is the credential attached:\n *\n * - server mode → Authorization: Bearer <server API key>\n * - logged-in user → Authorization: Bearer <tenant session JWT> (RLS applies)\n * - anonymous + token → X-EzCoder-Public-Token: <public/legacy token>\n * - anonymous, no tok → nothing; the server authorizes by deployment origin\n *\n * No environment branching, no RPC-vs-proxy fork, no preview-only fallback —\n * preview and deployed take byte-identical paths, which is the whole point.\n */\nexport class DatabaseClient {\n private readonly supabase: SupabaseClient | null;\n private readonly projectId: string;\n private apiKey?: string;\n private platformUrl: string;\n private serverMode: boolean = false;\n\n constructor(supabase: SupabaseClient | null, projectId: string) {\n this.supabase = supabase;\n this.projectId = projectId;\n this.platformUrl = env.EZCODER_API_URL || 'https://ezcoder.dev';\n }\n\n static createServerClient(\n projectId: string,\n apiKey: string,\n platformUrl?: string\n ): DatabaseClient {\n const client = new DatabaseClient(null, projectId);\n client.apiKey = apiKey;\n client.platformUrl = platformUrl\n || (typeof process !== 'undefined' && process.env?.EZCODER_API_URL)\n || env.EZCODER_API_URL\n || 'https://ezcoder.dev';\n client.serverMode = true;\n return client;\n }\n\n from<T = Record<string, unknown>>(table: string): QueryBuilder<T> {\n return new QueryBuilder<T>(null as unknown as SupabaseClient, this.projectId, table, {\n serverQuery: (sql: string) => this._proxy('/query', sql),\n serverExec: (sql: string) => this._proxy('/execute', sql),\n });\n }\n\n async sql<T = Record<string, unknown>>(query: string): Promise<DatabaseResult<T>> {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed.startsWith('select')) {\n throw new QueryError('sql() is for read-only queries. Use execute() for mutations.');\n }\n const start = Date.now();\n const result = await this._proxy('/query', query);\n const latencyMs = Date.now() - start;\n if (!result.success) {\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: result.error });\n throw new QueryError(result.error || 'Query failed', query);\n }\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: true, rowCount: result.rowCount ?? 0 });\n return {\n success: true,\n data: (result.data || []) as T[],\n rowCount: result.rowCount ?? (result.data?.length || 0),\n schema: result.schema,\n };\n }\n\n async execute(sql: string): Promise<MutationResult> {\n const start = Date.now();\n const result = await this._proxy('/execute', sql);\n const latencyMs = Date.now() - start;\n if (!result.success) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: result.error });\n throw new QueryError(result.error || 'Execution failed', sql);\n }\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: true, rowCount: result.rowCount ?? 0 });\n return {\n success: true,\n rowCount: result.rowCount ?? 0,\n schema: result.schema,\n executed_sql: result.executed_sql,\n };\n }\n\n async getSchema(): Promise<SchemaInfo> {\n const result = await this._proxy('/schema', null);\n if (!result.success) throw new ConnectionError(result.error || 'Schema fetch failed');\n return {\n exists: result.exists ?? false,\n schema: result.schema,\n tables: (result.tables || []) as SchemaInfo['tables'],\n tablesCount: result.tablesCount ?? 0,\n createdAt: result.createdAt,\n lastAccessedAt: result.lastAccessedAt,\n };\n }\n\n /**\n * Resolve the credential for this call. Order mirrors the server's auth tiers:\n * server key → end-user session JWT → public/legacy token → none (origin).\n */\n private async _authHeaders(): Promise<Record<string, string>> {\n if (this.serverMode && this.apiKey) {\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n // Neon Auth (Better Auth) apps: mint a short-lived session JWT from the\n // HttpOnly cookie via `${NEON_AUTH_URL}/token`. The platform DB proxy\n // verifies it (verify-neon-user-jwt) and runs the query as the end user\n // (per-row RLS). Gated on isNeonAuthConfigured so Supabase apps are\n // untouched. On ANY failure or logged-out (no token) we FALL THROUGH to the\n // public-token/origin path below — anonymous reads must keep working, so we\n // never throw here.\n if (isNeonAuthConfigured && env.NEON_AUTH_URL) {\n const token = await this._neonSessionJwt();\n if (token) return { Authorization: `Bearer ${token}` };\n // No token (logged out / fetch failed): fall through to anon path.\n }\n // Browser: prefer the logged-in user's session so the server runs the query\n // under their identity and RLS applies.\n if (this.supabase?.auth?.getSession) {\n let sessionResult: { data?: { session?: { access_token?: string } | null } } | undefined;\n try {\n sessionResult = await this.supabase.auth.getSession();\n } catch {\n // getSession THREW (network/refresh race). Do NOT silently fall through\n // to the public/origin path — that runs without per-user RLS and would\n // leak other users' rows to a logged-in user. Send no credential so the\n // server rejects (401) and the app re-authenticates. A NULL session\n // (logged out) is different and DOES fall through below.\n return {};\n }\n const token = sessionResult?.data?.session?.access_token;\n if (token) return { Authorization: `Bearer ${token}` };\n }\n // Anonymous (no session): send the browser-safe project token. Prefer the\n // runtime-bootstrapped token (works even when the build baked none); fall\n // back to the baked token; otherwise send nothing and let the server\n // authorize by origin.\n const pub = getRuntimeConfig()?.publicToken\n || env.EZC_PROJECT_TOKEN_PUBLIC || env.EZC_PROJECT_TOKEN_LEGACY || '';\n if (pub) return { 'X-EzCoder-Public-Token': pub };\n return {};\n }\n\n /**\n * Return a fresh Neon Better Auth session JWT (cached in-memory until ~30s\n * before its exp), or '' when logged out / unavailable. NEVER throws — a\n * failure falls through to the anonymous data path. Browser-only by nature\n * (relies on the HttpOnly session cookie via credentials:'include').\n */\n private async _neonSessionJwt(): Promise<string> {\n // Browser-only: the token is minted from the per-user HttpOnly session cookie\n // (credentials:'include'). On the server there is no per-request cookie here, and the\n // cache is MODULE-LEVEL (process-global) — populating it server-side could leak one\n // user's token to another request. Hard-gate to the browser so that can never happen.\n if (typeof window === 'undefined') return '';\n const now = Date.now();\n if (cachedNeonJwt && cachedNeonJwt.exp * 1000 - NEON_JWT_REFRESH_SKEW_MS > now) {\n return cachedNeonJwt.token;\n }\n const base = (env.NEON_AUTH_URL || '').replace(/\\/$/, '');\n if (!base) return '';\n try {\n const res = await fetch(`${base}/token`, {\n method: 'GET',\n credentials: 'include',\n signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),\n });\n if (!res.ok) {\n cachedNeonJwt = null;\n return '';\n }\n const body = await res.json().catch(() => null) as { token?: string } | null;\n const token = body?.token;\n if (!token) {\n cachedNeonJwt = null;\n return '';\n }\n const exp = decodeJwtExp(token);\n cachedNeonJwt = { token, exp };\n return token;\n } catch {\n // Logged out, network error, non-JSON, or timeout — treat as anonymous.\n cachedNeonJwt = null;\n return '';\n }\n }\n\n /** Platform API base — runtime bootstrap wins over the baked value so an\n * env-less build still reaches the right host. */\n private baseUrl(): string {\n return (getRuntimeConfig()?.apiUrl || this.platformUrl).replace(/\\/$/, '');\n }\n\n private async _proxy(endpoint: '/query' | '/execute' | '/schema', sql: string | null): Promise<ProxyResult> {\n const url = `${this.baseUrl()}/api/platform/db/${this.projectId}${endpoint}`;\n const method = endpoint === '/schema' ? 'GET' : 'POST';\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const headers: Record<string, string> = { ...(await this._authHeaders()) };\n if (method === 'POST') headers['Content-Type'] = 'application/json';\n const res = await fetch(url, {\n method,\n headers,\n body: method === 'POST' ? JSON.stringify({ sql }) : undefined,\n signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),\n });\n\n if (res.status === 429) {\n const retryAfter = parseInt(res.headers.get('retry-after') || '60', 10);\n await new Promise(r => setTimeout(r, Math.min(retryAfter, 5) * 1000));\n continue;\n }\n if (res.status === 503) {\n await new Promise(r => setTimeout(r, (attempt + 1) * 2000));\n continue;\n }\n return await res.json() as ProxyResult;\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n // A thrown error (timeout / connection drop) on /execute may mean the\n // write already committed server-side — retrying could double-insert.\n // Reads and schema are idempotent and safe to retry. (429/503 above are\n // explicit \"not processed\" signals and DO retry for all endpoints.)\n if (endpoint === '/execute') break;\n }\n }\n return { success: false, error: lastError?.message || 'Request failed after retries' };\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/database/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as ColumnInfo, D as DatabaseClient, a as DatabaseProvider, b as DatabaseResult, F as FilterValue, c as ForeignKeyInfo, I as IndexInfo, M as MutationResult, O as OrderOption, P as PolicyInfo, Q as QueryBuilder, S as SchemaInfo, d as SingleResult, T as TableInfo, u as useDatabase, e as useDatabaseOptional, f as useIsDatabaseConfigured } from '../DatabaseProvider-
|
|
1
|
+
export { C as ColumnInfo, D as DatabaseClient, a as DatabaseProvider, b as DatabaseResult, F as FilterValue, c as ForeignKeyInfo, I as IndexInfo, M as MutationResult, O as OrderOption, P as PolicyInfo, Q as QueryBuilder, S as SchemaInfo, d as SingleResult, T as TableInfo, u as useDatabase, e as useDatabaseOptional, f as useIsDatabaseConfigured } from '../DatabaseProvider-DRnx_V_u.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
4
4
|
import '@supabase/supabase-js';
|
package/dist/database/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DatabaseProvider,
|
|
3
|
+
useDatabase,
|
|
4
|
+
useDatabaseOptional,
|
|
5
|
+
useIsDatabaseConfigured,
|
|
6
|
+
useRealtime
|
|
7
|
+
} from "../chunk-VHKTBOFU.js";
|
|
1
8
|
import {
|
|
2
9
|
ConnectionError,
|
|
3
10
|
DatabaseClient,
|
|
4
11
|
DatabaseError,
|
|
5
|
-
DatabaseProvider,
|
|
6
12
|
NotFoundError,
|
|
7
13
|
QueryBuilder,
|
|
8
14
|
QueryError,
|
|
9
|
-
ValidationError
|
|
10
|
-
|
|
11
|
-
useDatabaseOptional,
|
|
12
|
-
useIsDatabaseConfigured,
|
|
13
|
-
useRealtime
|
|
14
|
-
} from "../chunk-RU2GHN7O.js";
|
|
15
|
-
import "../chunk-OIAKVQGD.js";
|
|
15
|
+
ValidationError
|
|
16
|
+
} from "../chunk-WFDQ4YUZ.js";
|
|
16
17
|
import "../chunk-FPSSXTQG.js";
|
|
17
18
|
import "../chunk-KWR4PA5I.js";
|
|
18
19
|
export {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { e as env, f as features, i as isFeatureConfigured, a as isNeonAuthConfigured } from './config-Cb4MMhGa.js';
|
|
2
2
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
-
import { E as EzcoderClient, A as AuthIntegration } from './types-
|
|
4
|
-
export { a as AnalyticsResult, b as AuthUser, C as CheckoutOptions, S as StorageFile, c as StorageResult, d as SubscriptionStatus, e as SubscriptionTier, U as UserProfile } from './types-
|
|
5
|
-
export { D as DatabaseClient, a as DatabaseProvider, u as useDatabase } from './DatabaseProvider-
|
|
3
|
+
import { E as EzcoderClient, A as AuthIntegration } from './types-BET19sj2.js';
|
|
4
|
+
export { a as AnalyticsResult, b as AuthUser, C as CheckoutOptions, S as StorageFile, c as StorageResult, d as SubscriptionStatus, e as SubscriptionTier, U as UserProfile } from './types-BET19sj2.js';
|
|
5
|
+
export { D as DatabaseClient, a as DatabaseProvider, u as useDatabase } from './DatabaseProvider-DRnx_V_u.js';
|
|
6
6
|
import 'react/jsx-runtime';
|
|
7
7
|
import 'react';
|
|
8
8
|
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DatabaseClient,
|
|
3
2
|
DatabaseProvider,
|
|
4
|
-
configValue,
|
|
5
|
-
getRuntimeConfig,
|
|
6
|
-
loadBootstrap,
|
|
7
3
|
useDatabase
|
|
8
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VHKTBOFU.js";
|
|
9
5
|
import {
|
|
6
|
+
DatabaseClient,
|
|
7
|
+
configValue,
|
|
10
8
|
ezcoder,
|
|
11
|
-
ezcoderAuthIntegration
|
|
12
|
-
|
|
9
|
+
ezcoderAuthIntegration,
|
|
10
|
+
getRuntimeConfig,
|
|
11
|
+
loadBootstrap
|
|
12
|
+
} from "./chunk-WFDQ4YUZ.js";
|
|
13
13
|
import {
|
|
14
14
|
isSupabaseConfigured,
|
|
15
15
|
supabase
|
package/dist/payments/index.d.ts
CHANGED
package/dist/payments/index.js
CHANGED
package/dist/roles/index.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AuthContext
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import
|
|
3
|
+
} from "../chunk-L326T7UV.js";
|
|
4
|
+
import {
|
|
5
|
+
DatabaseClient,
|
|
6
|
+
getRuntimeConfig
|
|
7
|
+
} from "../chunk-WFDQ4YUZ.js";
|
|
5
8
|
import {
|
|
6
9
|
supabase
|
|
7
10
|
} from "../chunk-FPSSXTQG.js";
|
|
8
11
|
import {
|
|
9
|
-
|
|
12
|
+
env,
|
|
13
|
+
features,
|
|
14
|
+
isNeonAuthConfigured
|
|
10
15
|
} from "../chunk-KWR4PA5I.js";
|
|
11
16
|
|
|
12
17
|
// src/roles/useRoles.ts
|
|
@@ -27,15 +32,33 @@ function useRoles() {
|
|
|
27
32
|
return;
|
|
28
33
|
}
|
|
29
34
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
let roleData;
|
|
36
|
+
if (isNeonAuthConfigured) {
|
|
37
|
+
const projectId = env.EZC_PROJECT_ID || getRuntimeConfig()?.projectId || "";
|
|
38
|
+
if (!projectId) {
|
|
39
|
+
setRoles([]);
|
|
40
|
+
setPermissions([]);
|
|
41
|
+
setAccessibleRoutes([]);
|
|
42
|
+
setError(null);
|
|
43
|
+
setLoading(false);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const db = new DatabaseClient(supabase, projectId);
|
|
47
|
+
const result = await db.sql(
|
|
48
|
+
"SELECT role_name, display_name, permissions, can_access_routes FROM get_user_roles()"
|
|
49
|
+
);
|
|
50
|
+
roleData = result?.data || [];
|
|
51
|
+
} else {
|
|
52
|
+
const { data, error: rpcError } = await supabase.rpc("get_user_roles", {
|
|
53
|
+
user_uuid: auth.user.id
|
|
54
|
+
});
|
|
55
|
+
if (rpcError) {
|
|
56
|
+
setError(rpcError.message);
|
|
57
|
+
setLoading(false);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
roleData = data || [];
|
|
37
61
|
}
|
|
38
|
-
const roleData = data || [];
|
|
39
62
|
const allRoles = roleData.map((r) => r.role_name);
|
|
40
63
|
const allPerms = [...new Set(roleData.flatMap((r) => r.permissions || []))];
|
|
41
64
|
const allRoutes = [...new Set(roleData.flatMap((r) => r.can_access_routes || []))];
|
package/dist/roles/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/roles/useRoles.ts","../../src/roles/RoleGate.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useContext } from 'react';\r\nimport { supabase } from '../core/supabase';\r\nimport { features } from '../core/config';\r\nimport { AuthContext } from '../auth/AuthProvider';\r\n\r\ninterface RoleData {\r\n role_name: string;\r\n display_name: string;\r\n permissions: string[];\r\n can_access_routes: string[];\r\n}\r\n\r\ninterface UseRolesReturn {\r\n roles: string[];\r\n permissions: string[];\r\n accessibleRoutes: string[];\r\n loading: boolean;\r\n error: string | null;\r\n hasRole: (name: string) => boolean;\r\n hasAnyRole: (names: string[]) => boolean;\r\n hasAllRoles: (names: string[]) => boolean;\r\n hasPermission: (perm: string) => boolean;\r\n hasAnyPermission: (perms: string[]) => boolean;\r\n hasAllPermissions: (perms: string[]) => boolean;\r\n canAccessRoute: (path: string) => boolean;\r\n refreshRoles: () => Promise<void>;\r\n}\r\n\r\nexport function useRoles(): UseRolesReturn {\r\n const auth = useContext(AuthContext);\r\n const [roles, setRoles] = useState<string[]>([]);\r\n const [permissions, setPermissions] = useState<string[]>([]);\r\n const [accessibleRoutes, setAccessibleRoutes] = useState<string[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const fetchRoles = useCallback(async () => {\r\n if (!auth?.user?.id || !features.auth) {\r\n setRoles([]);\r\n setPermissions([]);\r\n setAccessibleRoutes([]);\r\n setLoading(false);\r\n return;\r\n }\r\n\r\n try {\r\n const { data, error: rpcError } = await supabase.rpc('get_user_roles', {\r\n user_uuid: auth.user.id,\r\n });\r\n\r\n if (rpcError) {\r\n setError(rpcError.message);\r\n setLoading(false);\r\n return;\r\n }\r\n\r\n const roleData = (data || []) as RoleData[];\r\n const allRoles = roleData.map((r) => r.role_name);\r\n const allPerms = [...new Set(roleData.flatMap((r) => r.permissions || []))];\r\n const allRoutes = [...new Set(roleData.flatMap((r) => r.can_access_routes || []))];\r\n\r\n setRoles(allRoles);\r\n setPermissions(allPerms);\r\n setAccessibleRoutes(allRoutes);\r\n setError(null);\r\n } catch (err: unknown) {\r\n setError(err instanceof Error ? err.message : 'Failed to fetch roles');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [auth?.user?.id]);\r\n\r\n useEffect(() => {\r\n fetchRoles();\r\n }, [fetchRoles]);\r\n\r\n const hasRole = useCallback((name: string) => roles.includes(name), [roles]);\r\n const hasAnyRole = useCallback((names: string[]) => names.some((n) => roles.includes(n)), [roles]);\r\n const hasAllRoles = useCallback((names: string[]) => names.every((n) => roles.includes(n)), [roles]);\r\n const hasPermission = useCallback((perm: string) => permissions.includes(perm), [permissions]);\r\n const hasAnyPermission = useCallback((perms: string[]) => perms.some((p) => permissions.includes(p)), [permissions]);\r\n const hasAllPermissions = useCallback((perms: string[]) => perms.every((p) => permissions.includes(p)), [permissions]);\r\n\r\n const canAccessRoute = useCallback((path: string) => {\r\n return accessibleRoutes.some((route) => {\r\n if (route.endsWith('/*')) {\r\n return path.startsWith(route.slice(0, -2));\r\n }\r\n return route === path;\r\n });\r\n }, [accessibleRoutes]);\r\n\r\n return {\r\n roles, permissions, accessibleRoutes, loading, error,\r\n hasRole, hasAnyRole, hasAllRoles, hasPermission, hasAnyPermission, hasAllPermissions,\r\n canAccessRoute, refreshRoles: fetchRoles,\r\n };\r\n}\r\n","import { useRoles } from './useRoles';\r\n\r\ninterface RoleGateProps {\r\n children: React.ReactNode;\r\n roles?: string[];\r\n permissions?: string[];\r\n requireAll?: boolean;\r\n fallback?: React.ReactNode;\r\n loadingFallback?: React.ReactNode;\r\n}\r\n\r\ninterface RouteGateProps {\r\n children: React.ReactNode;\r\n route: string;\r\n fallback?: React.ReactNode;\r\n loadingFallback?: React.ReactNode;\r\n}\r\n\r\nexport function RoleGate({\r\n children,\r\n roles: requiredRoles,\r\n permissions: requiredPerms,\r\n requireAll = false,\r\n fallback = null,\r\n loadingFallback = null,\r\n}: RoleGateProps) {\r\n const { hasRole, hasAnyRole, hasAllRoles, hasPermission, hasAnyPermission, hasAllPermissions, loading } = useRoles();\r\n\r\n if (loading) return <>{loadingFallback}</>;\r\n\r\n let hasAccess = true;\r\n\r\n if (requiredRoles?.length) {\r\n hasAccess = requireAll ? hasAllRoles(requiredRoles) : hasAnyRole(requiredRoles);\r\n }\r\n\r\n if (hasAccess && requiredPerms?.length) {\r\n hasAccess = requireAll ? hasAllPermissions(requiredPerms) : hasAnyPermission(requiredPerms);\r\n }\r\n\r\n if (!hasAccess && !requiredRoles?.length && !requiredPerms?.length) {\r\n hasAccess = true;\r\n }\r\n\r\n // Use individual checks to satisfy linter\r\n void hasRole;\r\n void hasPermission;\r\n\r\n return hasAccess ? <>{children}</> : <>{fallback}</>;\r\n}\r\n\r\nexport function RouteGate({ children, route, fallback = null, loadingFallback = null }: RouteGateProps) {\r\n const { canAccessRoute, loading } = useRoles();\r\n\r\n if (loading) return <>{loadingFallback}</>;\r\n\r\n return canAccessRoute(route) ? <>{children}</> : <>{fallback}</>;\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/roles/useRoles.ts","../../src/roles/RoleGate.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useContext } from 'react';\r\nimport { supabase } from '../core/supabase';\r\nimport { features, env, isNeonAuthConfigured } from '../core/config';\r\nimport { getRuntimeConfig } from '../core/bootstrap';\r\nimport { DatabaseClient } from '../database/DatabaseClient';\r\nimport { AuthContext } from '../auth/AuthProvider';\r\n\r\ninterface RoleData {\r\n role_name: string;\r\n display_name: string;\r\n permissions: string[];\r\n can_access_routes: string[];\r\n}\r\n\r\n// Reject anything that is not a canonical UUID before interpolating it into the\r\n// Neon data-path SQL (the id is from a verified session, but defense in depth).\r\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\r\n\r\ninterface UseRolesReturn {\r\n roles: string[];\r\n permissions: string[];\r\n accessibleRoutes: string[];\r\n loading: boolean;\r\n error: string | null;\r\n hasRole: (name: string) => boolean;\r\n hasAnyRole: (names: string[]) => boolean;\r\n hasAllRoles: (names: string[]) => boolean;\r\n hasPermission: (perm: string) => boolean;\r\n hasAnyPermission: (perms: string[]) => boolean;\r\n hasAllPermissions: (perms: string[]) => boolean;\r\n canAccessRoute: (path: string) => boolean;\r\n refreshRoles: () => Promise<void>;\r\n}\r\n\r\nexport function useRoles(): UseRolesReturn {\r\n const auth = useContext(AuthContext);\r\n const [roles, setRoles] = useState<string[]>([]);\r\n const [permissions, setPermissions] = useState<string[]>([]);\r\n const [accessibleRoutes, setAccessibleRoutes] = useState<string[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const fetchRoles = useCallback(async () => {\r\n if (!auth?.user?.id || !features.auth) {\r\n setRoles([]);\r\n setPermissions([]);\r\n setAccessibleRoutes([]);\r\n setLoading(false);\r\n return;\r\n }\r\n\r\n try {\r\n let roleData: RoleData[];\r\n\r\n if (isNeonAuthConfigured) {\r\n // Neon path: read roles via the platform DB proxy. NO user id is interpolated —\r\n // get_user_roles() (no-arg) reads the CURRENT user from the server-set\r\n // auth.user_id() GUC, so there is NO client-controlled value in the SQL at all\r\n // (no injection surface). The bearer is the Neon session JWT so RLS applies and\r\n // the GUC is pinned to the verified user server-side.\r\n const projectId = env.EZC_PROJECT_ID || getRuntimeConfig()?.projectId || '';\r\n if (!projectId) {\r\n setRoles([]);\r\n setPermissions([]);\r\n setAccessibleRoutes([]);\r\n setError(null);\r\n setLoading(false);\r\n return;\r\n }\r\n const db = new DatabaseClient(supabase, projectId);\r\n const result = await db.sql<RoleData>(\r\n 'SELECT role_name, display_name, permissions, can_access_routes FROM get_user_roles()'\r\n );\r\n roleData = (result?.data || []) as RoleData[];\r\n } else {\r\n const { data, error: rpcError } = await supabase.rpc('get_user_roles', {\r\n user_uuid: auth.user.id,\r\n });\r\n\r\n if (rpcError) {\r\n setError(rpcError.message);\r\n setLoading(false);\r\n return;\r\n }\r\n roleData = (data || []) as RoleData[];\r\n }\r\n\r\n const allRoles = roleData.map((r) => r.role_name);\r\n const allPerms = [...new Set(roleData.flatMap((r) => r.permissions || []))];\r\n const allRoutes = [...new Set(roleData.flatMap((r) => r.can_access_routes || []))];\r\n\r\n setRoles(allRoles);\r\n setPermissions(allPerms);\r\n setAccessibleRoutes(allRoutes);\r\n setError(null);\r\n } catch (err: unknown) {\r\n setError(err instanceof Error ? err.message : 'Failed to fetch roles');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [auth?.user?.id]);\r\n\r\n useEffect(() => {\r\n fetchRoles();\r\n }, [fetchRoles]);\r\n\r\n const hasRole = useCallback((name: string) => roles.includes(name), [roles]);\r\n const hasAnyRole = useCallback((names: string[]) => names.some((n) => roles.includes(n)), [roles]);\r\n const hasAllRoles = useCallback((names: string[]) => names.every((n) => roles.includes(n)), [roles]);\r\n const hasPermission = useCallback((perm: string) => permissions.includes(perm), [permissions]);\r\n const hasAnyPermission = useCallback((perms: string[]) => perms.some((p) => permissions.includes(p)), [permissions]);\r\n const hasAllPermissions = useCallback((perms: string[]) => perms.every((p) => permissions.includes(p)), [permissions]);\r\n\r\n const canAccessRoute = useCallback((path: string) => {\r\n return accessibleRoutes.some((route) => {\r\n if (route.endsWith('/*')) {\r\n return path.startsWith(route.slice(0, -2));\r\n }\r\n return route === path;\r\n });\r\n }, [accessibleRoutes]);\r\n\r\n return {\r\n roles, permissions, accessibleRoutes, loading, error,\r\n hasRole, hasAnyRole, hasAllRoles, hasPermission, hasAnyPermission, hasAllPermissions,\r\n canAccessRoute, refreshRoles: fetchRoles,\r\n };\r\n}\r\n","import { useRoles } from './useRoles';\r\n\r\ninterface RoleGateProps {\r\n children: React.ReactNode;\r\n roles?: string[];\r\n permissions?: string[];\r\n requireAll?: boolean;\r\n fallback?: React.ReactNode;\r\n loadingFallback?: React.ReactNode;\r\n}\r\n\r\ninterface RouteGateProps {\r\n children: React.ReactNode;\r\n route: string;\r\n fallback?: React.ReactNode;\r\n loadingFallback?: React.ReactNode;\r\n}\r\n\r\nexport function RoleGate({\r\n children,\r\n roles: requiredRoles,\r\n permissions: requiredPerms,\r\n requireAll = false,\r\n fallback = null,\r\n loadingFallback = null,\r\n}: RoleGateProps) {\r\n const { hasRole, hasAnyRole, hasAllRoles, hasPermission, hasAnyPermission, hasAllPermissions, loading } = useRoles();\r\n\r\n if (loading) return <>{loadingFallback}</>;\r\n\r\n let hasAccess = true;\r\n\r\n if (requiredRoles?.length) {\r\n hasAccess = requireAll ? hasAllRoles(requiredRoles) : hasAnyRole(requiredRoles);\r\n }\r\n\r\n if (hasAccess && requiredPerms?.length) {\r\n hasAccess = requireAll ? hasAllPermissions(requiredPerms) : hasAnyPermission(requiredPerms);\r\n }\r\n\r\n if (!hasAccess && !requiredRoles?.length && !requiredPerms?.length) {\r\n hasAccess = true;\r\n }\r\n\r\n // Use individual checks to satisfy linter\r\n void hasRole;\r\n void hasPermission;\r\n\r\n return hasAccess ? <>{children}</> : <>{fallback}</>;\r\n}\r\n\r\nexport function RouteGate({ children, route, fallback = null, loadingFallback = null }: RouteGateProps) {\r\n const { canAccessRoute, loading } = useRoles();\r\n\r\n if (loading) return <>{loadingFallback}</>;\r\n\r\n return canAccessRoute(route) ? <>{children}</> : <>{fallback}</>;\r\n}\r\n"],"mappings":"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","names":[]}
|
package/dist/storage/index.d.ts
CHANGED
package/dist/storage/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/neonAuthClient.ts","../src/auth/AuthProvider.tsx"],"sourcesContent":["import { createAuthClient } from 'better-auth/react';\nimport { env, isNeonAuthConfigured } from '../core/config';\n\n/**\n * Per-project Neon Auth (Better Auth) client.\n *\n * A project uses Neon Auth when `env.NEON_AUTH_URL` (the per-project Better Auth\n * `base_url`, e.g. `https://ep-xxx.neonauth.<region>.aws.neon.tech/neondb/auth`)\n * is injected as `VITE_NEON_AUTH_URL`. When present, the SDK authenticates the\n * generated app against its OWN isolated Neon Auth server rather than the shared\n * tenant Supabase.\n *\n * The client is created lazily so that:\n * - non-Neon projects never instantiate it (zero behavioural change), and\n * - SSR/build passes that import the SDK without a base URL don't throw.\n *\n * This is the official Better Auth React client (`createAuthClient` from\n * `better-auth/react`). It owns token storage and cross-origin session handling;\n * do NOT hand-roll fetch against the Better Auth endpoints.\n */\nexport type NeonAuthClient = ReturnType<typeof createAuthClient>;\n\nlet cachedClient: NeonAuthClient | null = null;\n\n/**\n * Returns the lazily-created Better Auth client, or `null` when Neon Auth is not\n * configured for this project. Callers on the Neon path should treat a `null`\n * return as \"not configured\" and surface a clear error.\n */\nexport function getNeonAuthClient(): NeonAuthClient | null {\n if (!isNeonAuthConfigured || !env.NEON_AUTH_URL) {\n return null;\n }\n if (!cachedClient) {\n cachedClient = createAuthClient({\n baseURL: env.NEON_AUTH_URL,\n });\n }\n return cachedClient;\n}\n\n/** True when this project ships its own per-project Neon Auth server. */\nexport { isNeonAuthConfigured };\n","import { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';\nimport type { User, Session } from '@supabase/supabase-js';\nimport { supabase, isSupabaseConfigured } from '../core/supabase';\nimport { env, isNeonAuthConfigured } from '../core/config';\nimport { ezcoder, ezcoderAuthIntegration } from '../core/platform';\nimport { getNeonAuthClient } from './neonAuthClient';\nimport type { UserProfile } from '../core/types';\n\ninterface AuthResult<T = unknown> {\n data: T | null;\n error: Error | null;\n}\n\ninterface SignUpOptions {\n metadata?: Record<string, unknown>;\n}\n\ninterface SignInWithProviderOptions {\n redirectTo?: string;\n [key: string]: unknown;\n}\n\nexport interface AuthContextType {\n user: User | null;\n profile: UserProfile | null;\n session: Session | null;\n loading: boolean;\n isConfigured: boolean;\n signUp: (email: string, password: string, options?: SignUpOptions) => Promise<AuthResult>;\n signIn: (email: string, password: string) => Promise<AuthResult>;\n signInWithProvider: (provider: string, options?: SignInWithProviderOptions) => Promise<AuthResult>;\n signOut: () => Promise<{ error: Error | null }>;\n resetPassword: (email: string) => Promise<AuthResult>;\n updatePassword: (newPassword: string) => Promise<AuthResult>;\n updateProfile: (updates: Partial<UserProfile>) => Promise<AuthResult>;\n refetchProfile: (userId: string) => Promise<UserProfile | null>;\n}\n\nconst NOT_CONFIGURED_MSG = 'Authentication is not configured. Ensure EzCoder platform credentials are injected, or connect your own Supabase database in Settings → Databases.';\nfunction notConfiguredError() {\n return new Error(NOT_CONFIGURED_MSG);\n}\n\nexport const AuthContext = createContext<AuthContextType>({\n user: null,\n profile: null,\n session: null,\n loading: true,\n isConfigured: false,\n signUp: async () => ({ data: null, error: null }),\n signIn: async () => ({ data: null, error: null }),\n signInWithProvider: async () => ({ data: null, error: null }),\n signOut: async () => ({ error: null }),\n resetPassword: async () => ({ data: null, error: null }),\n updatePassword: async () => ({ data: null, error: null }),\n updateProfile: async () => ({ data: null, error: null }),\n refetchProfile: async () => null,\n});\n\n// ─── Path selector ──────────────────────────────────────────────────────────\n//\n// A project authenticates against its OWN per-project Neon Auth (Better Auth)\n// server when `VITE_NEON_AUTH_URL` is injected. Otherwise it falls back to the\n// existing shared-tenant Supabase path, which is behaviour-preserved verbatim\n// below in `SupabaseAuthProvider`.\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n if (isNeonAuthConfigured) {\n return <NeonAuthProvider>{children}</NeonAuthProvider>;\n }\n return <SupabaseAuthProvider>{children}</SupabaseAuthProvider>;\n}\n\n// ─── Neon Auth (Better Auth) path ────────────────────────────────────────────\n\n// The Better Auth user shape (subset we rely on). The full object also carries\n// emailVerified, image, role, banned, createdAt, updatedAt, etc.\ninterface BetterAuthUser {\n id?: string;\n email?: string;\n name?: string;\n image?: string | null;\n emailVerified?: boolean;\n role?: string;\n createdAt?: string;\n updatedAt?: string;\n [key: string]: unknown;\n}\n\n/**\n * Normalize a Better Auth user into the SDK's `user` shape. The context type\n * declares `User` (Supabase) for backwards compatibility, so we project the\n * Better Auth fields onto a Supabase-User-compatible object: `id`, `email`, and\n * a `user_metadata` carrying the display name + avatar. Consumers that read\n * `user.id`, `user.email`, or `user.user_metadata.full_name` keep working.\n */\nfunction mapNeonUser(u: BetterAuthUser | null | undefined): User | null {\n if (!u || !u.id) return null;\n const nowIso = new Date().toISOString();\n return {\n id: u.id,\n email: u.email,\n app_metadata: { provider: 'neon-auth', ...(u.role ? { role: u.role } : {}) },\n user_metadata: {\n full_name: u.name,\n name: u.name,\n avatar_url: u.image ?? undefined,\n email_verified: u.emailVerified,\n },\n aud: 'authenticated',\n created_at: u.createdAt || nowIso,\n updated_at: u.updatedAt || nowIso,\n role: u.role,\n } as unknown as User;\n}\n\n/**\n * Project the Better Auth session payload onto the SDK's `session` shape. Better\n * Auth manages the real token + cookie internally; this object exists only so\n * consumers reading `session.user` / truthiness keep working. The bearer token\n * (when exposed by useSession) is surfaced as `access_token` best-effort.\n */\nfunction mapNeonSession(rawSession: unknown, user: User | null): Session | null {\n if (!user) return null;\n const s = (rawSession || {}) as Record<string, unknown>;\n const token =\n (s.token as string | undefined) ||\n ((s.session as Record<string, unknown> | undefined)?.token as string | undefined) ||\n '';\n return {\n access_token: token,\n refresh_token: '',\n token_type: 'bearer',\n expires_in: 0,\n expires_at: undefined,\n user,\n } as unknown as Session;\n}\n\nconst NEON_NOT_SUPPORTED = (feature: string) =>\n new Error(`${feature} is not supported on the Neon Auth path yet.`);\n\nfunction NeonAuthProvider({ children }: { children: React.ReactNode }) {\n const authClient = getNeonAuthClient();\n const [user, setUser] = useState<User | null>(null);\n const [profile, setProfile] = useState<UserProfile | null>(null);\n const [session, setSession] = useState<Session | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const previousUserIdRef = useRef<string | null>(null);\n\n // Drive user/session/loading off Better Auth's reactive session hook. The hook\n // is stable across renders and re-renders the provider on auth state changes.\n const sessionState = authClient?.useSession?.() as\n | { data?: { user?: BetterAuthUser; session?: unknown } | null; isPending?: boolean }\n | undefined;\n\n const rawUser = sessionState?.data?.user ?? null;\n const isPending = sessionState?.isPending ?? false;\n\n useEffect(() => {\n const mappedUser = mapNeonUser(rawUser);\n setUser(mappedUser);\n setSession(mapNeonSession(sessionState?.data?.session ?? sessionState?.data ?? null, mappedUser));\n setLoading(Boolean(isPending));\n\n // Fire login/logout analytics on transitions, mirroring the Supabase path.\n const currentId = mappedUser?.id ?? null;\n const prevId = previousUserIdRef.current;\n if (currentId && currentId !== prevId) {\n ezcoderAuthIntegration.onLogin(mappedUser as unknown as { id: string; email?: string });\n previousUserIdRef.current = currentId;\n } else if (!currentId && prevId) {\n ezcoderAuthIntegration.onLogout(prevId);\n previousUserIdRef.current = null;\n setProfile(null);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rawUser, isPending]);\n\n const signUp = useCallback(async (email: string, password: string, options: SignUpOptions = {}): Promise<AuthResult> => {\n if (!authClient) return { data: null, error: notConfiguredError() };\n const { metadata = {} } = options;\n const name = (metadata.display_name as string | undefined) || (metadata.name as string | undefined) || email;\n try {\n const result = await authClient.signUp.email({ email, password, name });\n const error = (result as { error?: unknown })?.error;\n if (error) {\n return { data: null, error: toError(error, 'Sign up failed') };\n }\n const data = (result as { data?: unknown })?.data ?? result;\n const newUser = (data as { user?: BetterAuthUser })?.user;\n if (newUser?.id) {\n ezcoderAuthIntegration.onSignup({ id: newUser.id, email: newUser.email });\n }\n return { data, error: null };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Sign up failed') };\n }\n }, [authClient]);\n\n const signIn = useCallback(async (email: string, password: string): Promise<AuthResult> => {\n if (!authClient) return { data: null, error: notConfiguredError() };\n try {\n const result = await authClient.signIn.email({ email, password });\n const error = (result as { error?: unknown })?.error;\n if (error) {\n return { data: null, error: toError(error, 'Sign in failed') };\n }\n const data = (result as { data?: unknown })?.data ?? result;\n return { data, error: null };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Sign in failed') };\n }\n }, [authClient]);\n\n const signInWithProvider = useCallback(async (provider: string, options: SignInWithProviderOptions = {}): Promise<AuthResult> => {\n if (!authClient) return { data: null, error: notConfiguredError() };\n try {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n const callbackURL = options.redirectTo || origin;\n const framed = typeof window !== 'undefined' && window.self !== window.top;\n const social = provider as 'google' | 'github';\n\n // ── Proxy path ────────────────────────────────────────────────────────\n // When APP_AUTH_PROXY is enabled AND we have the platform coordinates,\n // delegate social login to the central EzCoder auth proxy instead of\n // hitting the per-project Better Auth server directly. The proxy handles\n // the OAuth handshake and redirects back to <app>/auth/callback#code=<singleUse>.\n // AuthCallback.tsx picks up the fragment and completes the sign-in.\n if (env.APP_AUTH_PROXY && env.EZCODER_API_URL && env.EZC_PROJECT_ID) {\n const proxyStartUrl =\n `${env.EZCODER_API_URL.replace(/\\/$/, '')}/api/app-auth/start` +\n `?provider=${encodeURIComponent(provider)}` +\n `&projectId=${encodeURIComponent(env.EZC_PROJECT_ID)}` +\n `&returnUrl=${encodeURIComponent(origin + '/auth/callback')}`;\n\n if (framed && typeof window !== 'undefined') {\n // Open the proxy start URL in a popup so the framed editor preview\n // doesn't try to navigate inside the iframe.\n window.open(proxyStartUrl, 'ezc-auth', 'popup,width=500,height=680');\n return { data: null, error: null };\n }\n\n // Standalone (deployed app / own tab): full-page redirect to the proxy.\n if (typeof window !== 'undefined') {\n window.location.href = proxyStartUrl;\n }\n return { data: null, error: null };\n }\n\n // ── Direct Better Auth path (proxy disabled) ──────────────────────────\n if (framed && typeof window !== 'undefined') {\n // Provider login pages refuse to render inside an iframe (X-Frame-Options /\n // frame-ancestors). Ask Better Auth for the OAuth URL WITHOUT redirecting\n // (disableRedirect) and open it in a popup. The popup completes on the\n // app origin (callbackURL) and the session cookie is set; Better Auth's\n // useSession picks it up here on the next focus/poll. A small focus poke\n // nudges the hook to refetch promptly.\n const result = await authClient.signIn.social({\n provider: social,\n callbackURL,\n disableRedirect: true,\n });\n const error = (result as { error?: unknown })?.error;\n if (error) return { data: null, error: toError(error, 'OAuth sign in failed') };\n const data = (result as { data?: { url?: string } })?.data ?? null;\n const url = data?.url;\n if (url) window.open(url, 'ezc-auth', 'popup,width=500,height=680');\n return { data, error: null };\n }\n\n // Standalone (deployed app / own tab): let Better Auth do the full-page\n // redirect to the provider.\n const result = await authClient.signIn.social({ provider: social, callbackURL });\n const error = (result as { error?: unknown })?.error;\n if (error) return { data: null, error: toError(error, 'OAuth sign in failed') };\n const data = (result as { data?: unknown })?.data ?? null;\n return { data, error: null };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('OAuth sign in failed') };\n }\n }, [authClient]);\n\n const signOut = useCallback(async (): Promise<{ error: Error | null }> => {\n if (!authClient) return { error: notConfiguredError() };\n const userId = user?.id;\n try {\n const result = await authClient.signOut();\n const error = (result as { error?: unknown })?.error;\n if (error) return { error: toError(error, 'Sign out failed') };\n if (userId) ezcoder.users.trackLogout(userId);\n return { error: null };\n } catch (err: unknown) {\n return { error: err instanceof Error ? err : new Error('Sign out failed') };\n }\n }, [authClient, user]);\n\n const resetPassword = useCallback(async (email: string): Promise<AuthResult> => {\n if (!authClient) return { data: null, error: notConfiguredError() };\n // Better Auth renamed `forgetPassword` → `requestPasswordReset`. Support both\n // so the SDK works regardless of the server's Better Auth version.\n const client = authClient as unknown as {\n requestPasswordReset?: (args: { email: string; redirectTo?: string }) => Promise<unknown>;\n forgetPassword?: (args: { email: string; redirectTo?: string }) => Promise<unknown>;\n };\n const redirectTo = `${typeof window !== 'undefined' ? window.location.origin : ''}/auth/reset-password`;\n const fn = client.requestPasswordReset || client.forgetPassword;\n if (!fn) {\n return { data: null, error: NEON_NOT_SUPPORTED('Password reset') };\n }\n try {\n const result = await fn({ email, redirectTo });\n const error = (result as { error?: unknown })?.error;\n if (error) return { data: null, error: toError(error, 'Password reset failed') };\n const data = (result as { data?: unknown })?.data ?? result;\n return { data, error: null };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Password reset failed') };\n }\n }, [authClient]);\n\n const updatePassword = useCallback(async (newPassword: string): Promise<AuthResult> => {\n if (!authClient) return { data: null, error: notConfiguredError() };\n // Two distinct Better Auth operations land here:\n // - `resetPassword({ newPassword, token })` after a reset-email link (token in URL)\n // - `changePassword({ newPassword, currentPassword })` for a logged-in user\n // We only have the new password, so we use the token-based reset when a\n // reset token is present in the URL; otherwise there is no safe call to make\n // (changePassword requires the current password we don't have).\n const token = typeof window !== 'undefined'\n ? new URLSearchParams(window.location.search).get('token') ||\n new URLSearchParams(window.location.search).get('reset_token')\n : null;\n const client = authClient as unknown as {\n resetPassword?: (args: { newPassword: string; token: string }) => Promise<unknown>;\n };\n if (token && client.resetPassword) {\n try {\n const result = await client.resetPassword({ newPassword, token });\n const error = (result as { error?: unknown })?.error;\n if (error) return { data: null, error: toError(error, 'Password update failed') };\n const data = (result as { data?: unknown })?.data ?? result;\n return { data, error: null };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Password update failed') };\n }\n }\n // TODO(neon-auth): wire changePassword once the UI can collect the current\n // password (Better Auth changePassword requires { newPassword, currentPassword }).\n return { data: null, error: NEON_NOT_SUPPORTED('Updating the password without a reset token') };\n }, [authClient]);\n\n // TODO(neon-auth): the user profile lives in the project's Neon\n // `public.user_profiles` table. Reading it requires the platform DB path\n // (useDatabase / DatabaseClient), which is provider-scoped and not available\n // here without threading a client in. We intentionally do NOT call Supabase on\n // the Neon path. Profile reads/writes no-op gracefully for now.\n const fetchProfile = useCallback(async (_userId: string): Promise<UserProfile | null> => {\n return null;\n }, []);\n\n const updateProfile = useCallback(async (_updates: Partial<UserProfile>): Promise<AuthResult> => {\n if (!user) return { data: null, error: new Error('Not authenticated') };\n return { data: null, error: NEON_NOT_SUPPORTED('Updating the profile') };\n }, [user]);\n\n const value: AuthContextType = {\n user,\n profile,\n session,\n loading,\n isConfigured: Boolean(authClient),\n signUp,\n signIn,\n signInWithProvider,\n signOut,\n resetPassword,\n updatePassword,\n updateProfile,\n refetchProfile: fetchProfile,\n };\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nfunction toError(error: unknown, fallback: string): Error {\n if (error instanceof Error) return error;\n if (error && typeof error === 'object') {\n const msg = (error as { message?: string; statusText?: string }).message\n || (error as { statusText?: string }).statusText;\n if (msg) return new Error(msg);\n }\n if (typeof error === 'string') return new Error(error);\n return new Error(fallback);\n}\n\n// ─── Supabase path (UNCHANGED behaviour) ─────────────────────────────────────\n\nfunction SupabaseAuthProvider({ children }: { children: React.ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [profile, setProfile] = useState<UserProfile | null>(null);\n const [session, setSession] = useState<Session | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const previousUserIdRef = useRef<string | null>(null);\n\n const fetchProfile = useCallback(async (userId: string): Promise<UserProfile | null> => {\n if (!userId) return null;\n\n try {\n let query = supabase\n .from('user_profiles')\n .select('*')\n .eq('id', userId);\n\n if (env.EZC_PROJECT_ID) {\n query = query.eq('project_id', env.EZC_PROJECT_ID);\n }\n\n const result = await query.single();\n\n const { data, error } = result || { data: null, error: null };\n\n if (error) {\n return null;\n }\n\n setProfile(data as UserProfile);\n return data as UserProfile;\n } catch {\n return null;\n }\n }, []);\n\n // SEC-1: bind the end-user to THIS project server-side (authoritative; app_metadata\n // is service-role-only). OAuth users have no signup metadata so the migration-226\n // trigger can't bind them — this is what stops migration 227 from locking them out.\n // No-ops if already bound. Non-blocking.\n const bindProjectIfNeeded = useCallback(async (currentUser: User | null): Promise<void> => {\n if (!currentUser || !env.EZC_PROJECT_ID || !env.EZCODER_API_URL) return;\n const appMeta = currentUser.app_metadata as Record<string, unknown> | undefined;\n if (appMeta?.bound_project_id) return;\n try {\n const { data } = await supabase.auth.getSession();\n const token = data?.session?.access_token;\n if (!token) return;\n const res = await fetch(`${env.EZCODER_API_URL.replace(/\\/$/, '')}/api/managed-auth/bind`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(env.EZC_PROJECT_TOKEN_PUBLIC ? { Authorization: `Bearer ${env.EZC_PROJECT_TOKEN_PUBLIC}` } : {}),\n 'X-EZC-User-Token': token,\n },\n body: JSON.stringify({ projectId: env.EZC_PROJECT_ID }),\n });\n const j = await res.json().catch(() => ({}));\n if (j?.changed) {\n // The new bound_project_id claim only appears after a token refresh.\n await supabase.auth.refreshSession();\n }\n } catch {\n // non-blocking — login still works; binding reconciles on next load / via backfill\n }\n }, []);\n\n useEffect(() => {\n supabase.auth.getSession().then(async ({ data: { session: initialSession } }) => {\n setSession(initialSession);\n setUser(initialSession?.user ?? null);\n\n if (initialSession?.user) {\n await fetchProfile(initialSession.user.id);\n bindProjectIfNeeded(initialSession.user);\n }\n\n setLoading(false);\n });\n\n const {\n data: { subscription },\n } = supabase.auth.onAuthStateChange(async (event, currentSession) => {\n setSession(currentSession);\n setUser(currentSession?.user ?? null);\n\n if (event === 'SIGNED_IN' && currentSession?.user) {\n await fetchProfile(currentSession.user.id);\n bindProjectIfNeeded(currentSession.user);\n ezcoderAuthIntegration.onLogin(currentSession.user);\n previousUserIdRef.current = currentSession.user.id;\n } else if (event === 'SIGNED_OUT') {\n setProfile(null);\n if (previousUserIdRef.current) {\n ezcoderAuthIntegration.onLogout(previousUserIdRef.current);\n previousUserIdRef.current = null;\n }\n } else if (event === 'USER_UPDATED' && currentSession?.user) {\n ezcoder.analytics.identify(currentSession.user.id, {\n email: currentSession.user.email,\n name: currentSession.user.user_metadata?.full_name,\n });\n }\n });\n\n // In-editor popup sign-in: the /auth/callback popup postMessages on completion;\n // the storage event is a same-origin fallback for the popup's localStorage write.\n const refreshFromExternal = () => {\n supabase.auth.getSession().then(({ data }) => {\n const s = data?.session ?? null;\n setSession(s);\n setUser(s?.user ?? null);\n if (s?.user) { fetchProfile(s.user.id); bindProjectIfNeeded(s.user); }\n });\n };\n const onMsg = (e: MessageEvent) => { if (e?.data?.type === 'ezc-auth-complete') refreshFromExternal(); };\n const onStorage = (e: StorageEvent) => { if (e.key && /auth-token/.test(e.key)) refreshFromExternal(); };\n if (typeof window !== 'undefined') {\n window.addEventListener('message', onMsg);\n window.addEventListener('storage', onStorage);\n }\n\n return () => {\n subscription.unsubscribe();\n if (typeof window !== 'undefined') {\n window.removeEventListener('message', onMsg);\n window.removeEventListener('storage', onStorage);\n }\n };\n }, [fetchProfile, bindProjectIfNeeded]);\n\n const signUp = useCallback(async (email: string, password: string, options: SignUpOptions = {}): Promise<AuthResult> => {\n if (!isSupabaseConfigured) {\n return { data: null, error: notConfiguredError() };\n }\n const { metadata = {} } = options;\n\n try {\n const signUpMetadata = { ...metadata };\n if (env.EZC_PROJECT_ID) {\n signUpMetadata.project_id = env.EZC_PROJECT_ID;\n signUpMetadata.bound_project_id = env.EZC_PROJECT_ID;\n }\n\n const result = await supabase.auth.signUp({\n email,\n password,\n options: { data: signUpMetadata },\n });\n\n const { data, error } = result || { data: null, error: new Error('Sign up failed') };\n\n if (error) {\n return { data: null, error };\n }\n\n if (data?.user) {\n const profileData: Record<string, unknown> = {\n id: data.user.id,\n email,\n };\n if (metadata.display_name) {\n profileData.display_name = metadata.display_name;\n }\n if (env.EZC_PROJECT_ID) {\n profileData.project_id = env.EZC_PROJECT_ID;\n }\n if (metadata.display_name || env.EZC_PROJECT_ID) {\n await supabase.from('user_profiles').upsert(profileData);\n }\n try {\n await supabase.rpc('assign_default_role', { user_uuid: data.user.id });\n } catch {\n // Non-blocking — role tables may not exist in all projects\n }\n ezcoderAuthIntegration.onSignup(data.user);\n }\n\n return { data, error: null };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Sign up failed') };\n }\n }, []);\n\n const signIn = useCallback(async (email: string, password: string): Promise<AuthResult> => {\n if (!isSupabaseConfigured) {\n return { data: null, error: notConfiguredError() };\n }\n try {\n const result = await supabase.auth.signInWithPassword({ email, password });\n const { data, error } = result || { data: null, error: new Error('Sign in failed') };\n return { data, error };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Sign in failed') };\n }\n }, []);\n\n const signInWithProvider = useCallback(async (provider: string, options: SignInWithProviderOptions = {}): Promise<AuthResult> => {\n if (!isSupabaseConfigured) {\n return { data: null, error: notConfiguredError() };\n }\n try {\n const provider2 = provider as 'google' | 'github' | 'facebook' | 'apple' | 'twitter';\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n const framed = typeof window !== 'undefined' && window.self !== window.top;\n\n if (framed && typeof window !== 'undefined') {\n // Provider login pages refuse to render inside an iframe (X-Frame-Options /\n // frame-ancestors), so we cannot do a full-page redirect in the editor preview.\n // Open the flow in a popup; the /auth/callback page completes PKCE and\n // postMessages back (storage event is the fallback). Land on the callback route.\n const redirectTo = options.redirectTo || (origin ? `${origin}/auth/callback` : '');\n const result = await supabase.auth.signInWithOAuth({\n provider: provider2,\n options: { redirectTo, skipBrowserRedirect: true, ...options },\n });\n if (result?.error) return { data: null, error: result.error };\n const url = (result?.data as { url?: string } | null)?.url;\n if (url) window.open(url, 'ezc-auth', 'popup,width=500,height=680');\n return { data: result?.data ?? null, error: null };\n }\n\n // Standalone (deployed app / own tab): full-page redirect. Default to the app\n // origin (root) so apps without a scaffolded callback route still complete via\n // detectSessionInUrl; new apps pass /auth/callback explicitly.\n const result = await supabase.auth.signInWithOAuth({\n provider: provider2,\n options: {\n redirectTo: options.redirectTo || origin,\n ...options,\n },\n });\n const { data, error } = result || { data: null, error: new Error('OAuth sign in failed') };\n return { data, error };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('OAuth sign in failed') };\n }\n }, []);\n\n const signOut = useCallback(async (): Promise<{ error: Error | null }> => {\n const userId = user?.id;\n try {\n const result = await supabase.auth.signOut();\n const { error } = result || { error: null };\n if (!error && userId) {\n ezcoder.users.trackLogout(userId);\n }\n return { error };\n } catch (err: unknown) {\n return { error: err instanceof Error ? err : new Error('Sign out failed') };\n }\n }, [user]);\n\n const resetPassword = useCallback(async (email: string): Promise<AuthResult> => {\n try {\n const result = await supabase.auth.resetPasswordForEmail(email, {\n redirectTo: `${typeof window !== 'undefined' ? window.location.origin : ''}/auth/reset-password`,\n });\n const { data, error } = result || { data: null, error: new Error('Password reset failed') };\n return { data, error };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Password reset failed') };\n }\n }, []);\n\n // Set a new password. Used on the /auth/reset-password landing page, where the\n // recovery link has already established a (recovery) session via detectSessionInUrl.\n const updatePassword = useCallback(async (newPassword: string): Promise<AuthResult> => {\n if (!isSupabaseConfigured) {\n return { data: null, error: notConfiguredError() };\n }\n try {\n const result = await supabase.auth.updateUser({ password: newPassword });\n const { data, error } = result || { data: null, error: new Error('Password update failed') };\n return { data, error };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Password update failed') };\n }\n }, []);\n\n const updateProfile = useCallback(\n async (updates: Partial<UserProfile>): Promise<AuthResult> => {\n if (!user) {\n return { data: null, error: new Error('Not authenticated') };\n }\n try {\n let query = supabase\n .from('user_profiles')\n .update(updates)\n .eq('id', user.id);\n\n if (env.EZC_PROJECT_ID) {\n query = query.eq('project_id', env.EZC_PROJECT_ID);\n }\n\n const result = await query.select().single();\n const { data, error } = result || { data: null, error: null };\n return { data, error };\n } catch (err: unknown) {\n return { data: null, error: err instanceof Error ? err : new Error('Update failed') };\n }\n },\n [user]\n );\n\n const value: AuthContextType = {\n user,\n profile,\n session,\n loading,\n isConfigured: isSupabaseConfigured,\n signUp,\n signIn,\n signInWithProvider,\n signOut,\n resetPassword,\n updatePassword,\n updateProfile,\n refetchProfile: fetchProfile,\n };\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextType {\n const context = useContext(AuthContext);\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n}\n\nexport type { AuthResult, SignUpOptions, SignInWithProviderOptions };\n"],"mappings":"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","names":["result","error","data"]}
|