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

68 lines
2 KiB
TypeScript

// 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<Database>
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<Database>(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())
}