Letschat / src /lib /supabase /server.ts
HonzaH's picture
Upload 182 files
b00f0f1 verified
Raw
History Blame Contribute Delete
2.58 kB
import { createClient as createSupabaseClient } from '@supabase/supabase-js'
import type { Database } from 'types/database'
import { isSupabaseConfigured as isSupabaseConfiguredEnv, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_URL } from './env'
export const isSupabaseConfigured = isSupabaseConfiguredEnv
import type { SupabaseClient } from '@supabase/supabase-js'
export const createServerClient = async (opts?: { service?: boolean }): Promise<SupabaseClient<Database>> => {
// If caller explicitly requests a service client and service role key exists,
// return a service-role supabase client (for admin tasks).
if (opts?.service && SUPABASE_URL && SUPABASE_SERVICE_ROLE_KEY) {
return createSupabaseClient<Database>(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, {
auth: { persistSession: false }
})
}
// For regular server route handlers, construct a Supabase client using
// the anon/public key. We don't persist Supabase sessions; app-level
// session is handled by our own cookie (`letschat_session`).
if (!SUPABASE_URL || !SUPABASE_ANON_KEY) {
// Return a proxy object that will throw only when its methods are invoked.
// This prevents Next.js from crashing at startup while still surfacing
// a clear error when code actually attempts to use Supabase.
// @ts-ignore - create a lightweight proxy matching SupabaseClient shape at runtime
const missingClient = new Proxy({}, {
get() {
return () => {
throw new Error('Supabase not configured: missing NEXT_PUBLIC_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_ANON_KEY')
}
}
}) as SupabaseClient<Database>
return missingClient
}
return createSupabaseClient<Database>(SUPABASE_URL, SUPABASE_ANON_KEY, {
auth: { persistSession: false }
})
}
// Helper to explicitly create a service-role client when needed.
export const createServiceClient = () => {
if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE_KEY) {
throw new Error('Service role key not configured')
}
// Provide a no-op async storage adapter for service clients on server.
const noopAsyncStorage = {
async getItem(_key: string) {
return null
},
async setItem(_key: string, _value: any) {
return
},
async removeItem(_key: string) {
return
}
}
return createSupabaseClient<Database>(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, {
auth: {
persistSession: false,
// @ts-ignore - adapter shape is accepted at runtime
storage: noopAsyncStorage
}
})
}