53 lines
1.9 KiB
TypeScript
53 lines
1.9 KiB
TypeScript
/**
|
|
* Supabase client for Server Components and Route Handlers.
|
|
* Uses the cookies() API to read+write the user's session.
|
|
*
|
|
* If NEXT_PUBLIC_SUPABASE_URL is not set (e.g., local dev without Supabase),
|
|
* returns a stub that throws — callers should check `isSupabaseConfigured()`.
|
|
*/
|
|
import { createServerClient, type CookieOptions } from "@supabase/ssr";
|
|
import { cookies } from "next/headers";
|
|
|
|
export function isSupabaseConfigured(): boolean {
|
|
return Boolean(process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY);
|
|
}
|
|
|
|
export async function createClient() {
|
|
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
|
|
if (!url || !key) {
|
|
throw new Error("Supabase env vars not set");
|
|
}
|
|
const cookieStore = await cookies();
|
|
return createServerClient(url, key, {
|
|
cookies: {
|
|
getAll() {
|
|
return cookieStore.getAll();
|
|
},
|
|
setAll(toSet: Array<{ name: string; value: string; options?: CookieOptions }>) {
|
|
try {
|
|
toSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options));
|
|
} catch {
|
|
// setAll fails in Server Components (no setter); ignore — middleware handles refresh.
|
|
}
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Admin client using service_role key. Bypasses RLS. USE ONLY in trusted server
|
|
* code (never expose to clients). Required for inserting usage_events under
|
|
* service_role, deleting users, etc.
|
|
*/
|
|
export function createServiceClient() {
|
|
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
const key = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
if (!url || !key) throw new Error("Supabase service env vars not set");
|
|
// Lazy import to avoid bundling on client
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const { createClient } = require("@supabase/supabase-js");
|
|
return createClient(url, key, {
|
|
auth: { autoRefreshToken: false, persistSession: false },
|
|
});
|
|
}
|