d3ro-voice/packages/api-client/src/supabase-server.ts
2026-08-29 18:33:45 +09:00

47 lines
1.6 KiB
TypeScript

// packages/api-client/src/supabase-server.ts
// RSC/route handler용 Supabase 서버 클라이언트 팩토리.
// next/headers에 직접 의존하지 않고, 호출부에서 cookieStore를 주입.
// Database 제네릭 주입 (@supabase/ssr 0.10 + supabase-js 2.103 정합).
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import type { Database } from './types'
import { requireSupabasePublicConfig } from './client'
/** next/headers cookies()가 반환하는 객체의 최소 인터페이스 */
export interface CookieStore {
getAll(): Array<{ name: string; value: string }>
set(name: string, value: string, options: CookieOptions): void
}
export function createSupabaseServerClient(
cookieStore: CookieStore,
): ReturnType<typeof createServerClient<Database>> {
const { url, anonKey } = requireSupabasePublicConfig({
url: process.env.NEXT_PUBLIC_SUPABASE_URL,
anonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
})
return createServerClient<Database>(url, anonKey, {
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet: Array<{ name: string; value: string; options: CookieOptions }>) {
try {
cookiesToSet.forEach(({ name, value, options }) => {
cookieStore.set(name, value, options)
})
} catch {
// RSC에서 set은 실패하지만 route handler에서는 성공
}
},
},
})
}
export function isSupabaseConfiguredServer(): boolean {
return Boolean(
process.env.NEXT_PUBLIC_SUPABASE_URL?.trim()
&& process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY?.trim(),
)
}