Spaces:
Paused
Paused
| import { createClient, SupabaseClient } from "@supabase/supabase-js"; | |
| import { logger } from "../lib/logger"; | |
| import { configDotenv } from "dotenv"; | |
| configDotenv(); | |
| // SupabaseService class initializes the Supabase client conditionally based on environment variables. | |
| class SupabaseService { | |
| private client: SupabaseClient | null = null; | |
| private rrClient: SupabaseClient | null = null; | |
| constructor() { | |
| const supabaseUrl = process.env.SUPABASE_URL; | |
| const supabaseReplicaUrl = process.env.SUPABASE_REPLICA_URL; | |
| const supabaseServiceToken = process.env.SUPABASE_SERVICE_TOKEN; | |
| const useDbAuthentication = process.env.USE_DB_AUTHENTICATION === "true"; | |
| // Only initialize the Supabase client if both URL and Service Token are provided. | |
| if (!useDbAuthentication) { | |
| // Warn the user that Authentication is disabled by setting the client to null | |
| logger.warn( | |
| "Authentication is disabled. Supabase client will not be initialized.", | |
| ); | |
| this.client = null; | |
| } else if (!supabaseUrl || !supabaseServiceToken || !supabaseReplicaUrl) { | |
| logger.error( | |
| "Supabase environment variables aren't configured correctly. Supabase client will not be initialized. Fix ENV configuration or disable DB authentication with USE_DB_AUTHENTICATION env variable", | |
| ); | |
| } else { | |
| this.client = createClient(supabaseUrl, supabaseServiceToken, { | |
| global: { | |
| headers: { | |
| "sb-lb-routing-mode": "alpha-all-services", | |
| }, | |
| }, | |
| }); | |
| this.rrClient = createClient(supabaseReplicaUrl, supabaseServiceToken); | |
| } | |
| } | |
| // Provides access to the initialized Supabase client, if available. | |
| getClient(): SupabaseClient | null { | |
| return this.client; | |
| } | |
| getRRClient(): SupabaseClient | null { | |
| return this.rrClient; | |
| } | |
| } | |
| const serv = new SupabaseService(); | |
| // Using a Proxy to handle dynamic access to the Supabase client or service methods. | |
| // This approach ensures that if Supabase is not configured, any attempt to use it will result in a clear error. | |
| export const supabase_service: SupabaseClient = new Proxy( | |
| serv, | |
| { | |
| get: function (target, prop, receiver) { | |
| const client = target.getClient(); | |
| // If the Supabase client is not initialized, intercept property access to provide meaningful error feedback. | |
| if (client === null) { | |
| return () => { | |
| throw new Error("Supabase client is not configured."); | |
| }; | |
| } | |
| // Direct access to SupabaseService properties takes precedence. | |
| if (prop in target) { | |
| return Reflect.get(target, prop, receiver); | |
| } | |
| // Otherwise, delegate access to the Supabase client. | |
| return Reflect.get(client, prop, receiver); | |
| }, | |
| }, | |
| ) as unknown as SupabaseClient; | |
| export const supabase_rr_service: SupabaseClient = new Proxy( | |
| serv, | |
| { | |
| get: function (target, prop, receiver) { | |
| const client = target.getRRClient(); | |
| // If the Supabase client is not initialized, intercept property access to provide meaningful error feedback. | |
| if (client === null) { | |
| return () => { | |
| throw new Error("Supabase RR client is not configured."); | |
| }; | |
| } | |
| // Direct access to SupabaseService properties takes precedence. | |
| if (prop in target) { | |
| return Reflect.get(target, prop, receiver); | |
| } | |
| // Otherwise, delegate access to the Supabase client. | |
| return Reflect.get(client, prop, receiver); | |
| }, | |
| }, | |
| ) as unknown as SupabaseClient; | |