Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

index.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

index.tsBlame74 lines · 1 contributor
6f3ce18Claude1/**
2 * Drizzle DB connection — dual-driver, auto-detected from DATABASE_URL.
3 *
4 * - Neon serverless (HTTPS over fetch) — for *.neon.tech hosts
5 * - postgres.js (TCP) — for localhost / self-hosted Postgres
6 *
7 * Lets the same codebase run on Neon's hosted DB AND on a local Postgres
8 * sitting next to the bun process on a single VPS. Picks the right driver
9 * by inspecting the URL host once, at first access.
10 */
11
fc1817aClaude12import { neon } from "@neondatabase/serverless";
6f3ce18Claude13import { drizzle as drizzleNeon, type NeonHttpDatabase } from "drizzle-orm/neon-http";
14import { drizzle as drizzlePg, type PostgresJsDatabase } from "drizzle-orm/postgres-js";
15import postgres from "postgres";
fc1817aClaude16import * as schema from "./schema";
17import { config } from "../lib/config";
18
6f3ce18Claude19type AnyDb = NeonHttpDatabase<typeof schema> | PostgresJsDatabase<typeof schema>;
20
21let _db: AnyDb | null = null;
22
23/**
24 * Returns true when the URL points at Neon's serverless HTTPS endpoint.
25 * Anything else (localhost, RDS, Supabase TCP, plain Postgres) goes through
26 * the postgres.js driver.
27 */
28export function isNeonUrl(url: string): boolean {
29 try {
30 const u = new URL(url);
31 return /(^|\.)neon\.tech$/i.test(u.hostname);
32 } catch {
33 return false;
fc1817aClaude34 }
6f3ce18Claude35}
36
37export function getDb(): AnyDb {
38 if (_db) return _db;
39
40 if (!config.databaseUrl) {
41 throw new Error(
42 "DATABASE_URL is not set. Set it in your environment or .env file."
43 );
44 }
45
46 const url = config.databaseUrl;
47
48 if (isNeonUrl(url)) {
49 const sql = neon(url);
50 _db = drizzleNeon(sql, { schema });
51 } else {
52 // postgres.js — TCP driver for self-hosted / non-Neon Postgres.
53 // max=10 keeps the connection pool modest on small VPS deployments.
54 const client = postgres(url, { max: 10, prepare: false });
55 _db = drizzlePg(client, { schema });
56 }
57
fc1817aClaude58 return _db;
59}
60
6f3ce18Claude61// Re-export as `db` for convenience — proxies to the chosen driver lazily.
62// Will throw on first access if DATABASE_URL is unset.
2316901Claude63//
64// We type the proxy as `NeonHttpDatabase<typeof schema>` for ergonomics: the
65// two driver wrappers expose identical query-builder APIs at runtime (both are
66// `PgDatabase` underneath), but the union type narrows TypeScript's overload
67// resolution and makes `.returning({...})` etc. show as "0 args expected".
68// Casting to the Neon variant exposes the full drizzle PG query-builder
69// surface to call sites without changing runtime behaviour.
6f3ce18Claude70export const db = new Proxy({} as AnyDb, {
fc1817aClaude71 get(_target, prop, receiver) {
6f3ce18Claude72 return Reflect.get(getDb(), prop, receiver) as unknown;
fc1817aClaude73 },
2316901Claude74}) as NeonHttpDatabase<typeof schema>;