68 lines
2 KiB
TypeScript
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())
|
|
}
|