mirror of
https://github.com/tiennm99/llmapikey.git
synced 2026-06-17 12:48:54 +00:00
02fa52ccf9
- Next.js 15 App Router (JS+JSDoc): landing, auth-gated dashboard, docs - GitHub OAuth via Supabase; identity anchored on numeric provider_id - key provisioning: reserve-then-mint-persist-compensate, one key per account - api_keys in unexposed llmapikey schema via direct Postgres; RLS deny-all - live minting gated behind PROVISIONING_ENABLED; Vercel auto-deploy disabled - unit tests (mask, request-body), RLS deny-all test, reconcile script
42 lines
1.3 KiB
JavaScript
42 lines
1.3 KiB
JavaScript
import "server-only";
|
|
|
|
import postgres from "postgres";
|
|
|
|
/**
|
|
* Direct Postgres client for the unexposed `llmapikey` schema.
|
|
*
|
|
* Why direct PG (not supabase-js): the `llmapikey` schema is intentionally NOT
|
|
* added to PostgREST's exposed schemas, so the REST API (and therefore the anon
|
|
* role) cannot reach `api_keys` at all. supabase-js cannot query an unexposed
|
|
* schema. A direct Postgres connection sidesteps PostgREST entirely.
|
|
*
|
|
* This module is `server-only`; DATABASE_URL must never reach the client bundle.
|
|
*
|
|
* Connection: use Supabase's pooler connection string. In transaction-pooling
|
|
* mode (port 6543) prepared statements are unsupported, so `prepare: false`.
|
|
*
|
|
* @type {import('postgres').Sql}
|
|
*/
|
|
let sql;
|
|
|
|
/**
|
|
* Lazily create the singleton sql client. Lazy so importing this module never
|
|
* throws at build time when DATABASE_URL is absent (e.g. CI without secrets).
|
|
*
|
|
* @returns {import('postgres').Sql}
|
|
*/
|
|
export function getSql() {
|
|
if (sql) return sql;
|
|
const connectionString = process.env.DATABASE_URL;
|
|
if (!connectionString) {
|
|
throw new Error("Missing required environment variable: DATABASE_URL");
|
|
}
|
|
sql = postgres(connectionString, {
|
|
prepare: false,
|
|
max: 5,
|
|
idle_timeout: 20,
|
|
connect_timeout: 10,
|
|
});
|
|
return sql;
|
|
}
|