File size: 2,576 Bytes
5a7302b
 
 
 
 
123c60b
b00f0f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123c60b
 
 
 
 
 
 
 
 
9853b20
 
b00f0f1
 
 
 
 
 
 
 
9853b20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a7302b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
    }
  })
}