The self-hosted client was typed as a full Supabase client, so an old scoring poll called .single() on a plain promise and failed. The new DataClient only lists methods the adapter implements. Co-Authored-By: Grok (agent loop)
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { createClient } from "@supabase/supabase-js";
|
|
import type { DataClient } from "@/lib/db/data-client";
|
|
import { createLocalPostgresDataClient } from "@/lib/db/local-postgres-client-core";
|
|
import {
|
|
getSupabaseUrl,
|
|
SupabaseConfigurationError,
|
|
} from "./config";
|
|
|
|
export function createAdminSupabaseClient(): DataClient {
|
|
if (process.env.AUTH_PROVIDER?.trim() === "self-hosted") {
|
|
const connectionString = process.env.SERVICE_DATABASE_URL?.trim();
|
|
if (!connectionString) {
|
|
throw new SupabaseConfigurationError(["SERVICE_DATABASE_URL"]);
|
|
}
|
|
if (!connectionString.startsWith("postgresql://")) {
|
|
throw new Error("SERVICE_DATABASE_URL must be a PostgreSQL URL");
|
|
}
|
|
return createLocalPostgresDataClient(
|
|
connectionString,
|
|
null,
|
|
"service_role",
|
|
) as DataClient;
|
|
}
|
|
const url = getSupabaseUrl();
|
|
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
if (!serviceRoleKey) {
|
|
throw new SupabaseConfigurationError(["SUPABASE_SERVICE_ROLE_KEY"]);
|
|
}
|
|
|
|
// 回滚分支,运行时形状是超集
|
|
return createClient(url, serviceRoleKey, {
|
|
auth: { autoRefreshToken: false, persistSession: false },
|
|
}) as unknown as DataClient;
|
|
}
|
|
|
|
export function isAdminEmail(email: string | null | undefined) {
|
|
const configured = process.env.ADMIN_EMAILS;
|
|
if (!configured?.trim() || !email) return false;
|
|
|
|
const normalized = email.trim().toLowerCase();
|
|
return configured
|
|
.split(",")
|
|
.some((candidate) => candidate.trim().toLowerCase() === normalized);
|
|
}
|