// packages/api-client/src/client.ts // Supabase 클라이언트 팩토리. 각 앱이 자신의 env에서 URL/KEY를 주입하여 생성. import { createClient, type SupabaseClient } from '@supabase/supabase-js' import type { Database } from './types' export type D3roSupabaseClient = SupabaseClient export interface CreateClientOptions { url: string | undefined anonKey: string | undefined /** * SSR 환경에서 세션 영속화를 쿠키 기반으로 하려면 별도 storage adapter를 주입. * 지정하지 않으면 기본(localStorage in browser, 메모리 in SSR). */ auth?: { persistSession?: boolean autoRefreshToken?: boolean storageKey?: string } } export class SupabaseConfigurationError extends Error { readonly code = 'SUPABASE_CONFIGURATION_MISSING' constructor() { super('Supabase public URL and anonymous key are required.') this.name = 'SupabaseConfigurationError' } } export function requireSupabasePublicConfig(options: CreateClientOptions): { url: string anonKey: string } { const url = options.url?.trim() const anonKey = options.anonKey?.trim() if (!url || !anonKey) { throw new SupabaseConfigurationError() } return { url, anonKey } } /** * Supabase 클라이언트 생성. * 필수 공개 설정이 없으면 가짜 백엔드로 진행하지 않고 즉시 실패한다. */ export function createD3roSupabaseClient(options: CreateClientOptions): D3roSupabaseClient { const { auth } = options const { url, anonKey } = requireSupabasePublicConfig(options) return createClient(url, anonKey, { auth: { persistSession: auth?.persistSession ?? true, autoRefreshToken: auth?.autoRefreshToken ?? true, storageKey: auth?.storageKey } }) } /** * Env가 실제로 세팅되었는지 확인. UI에서 "Supabase 미설정" 경고 표시용. */ export function isClientConfigured(options: CreateClientOptions): boolean { return Boolean(options.url?.trim() && options.anonKey?.trim()) }