/**
* Copyright (C) 2026 SofĂa Aritz and contributors
*
* This file is part of Everest.
*
* Everest is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* Everest is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Everest. If not, see .
*/
import { Kysely, PostgresDialect } from "kysely";
import { Pool } from "pg";
let db: Kysely | null = null;
export function getDb() {
if (!db) {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) throw new Error("Environment variable DATABASE_URL is required");
const connectionUrl = new URL(databaseUrl);
if (connectionUrl.protocol !== "postgresql:") throw new Error("DATABASE_URL's protocol must be 'postgresql'");
const pool = new Pool({
host: connectionUrl.hostname,
port: connectionUrl.port ? Number(connectionUrl.port) : 5434,
user: connectionUrl.username,
password: connectionUrl.password,
database: connectionUrl.pathname.substring(1),
});
db = new Kysely({
dialect: new PostgresDialect({ pool }),
});
}
return db;
}
export interface DatabaseSchema {
atproto_auth_state: AtProtoAuthStateTable;
atproto_auth_session: AtProtoAuthSessionTable;
account: AccountTable;
entry: EntryTable;
follow: FollowTable;
}
export interface AtProtoAuthStateTable {
key: string;
value: string;
}
export interface AtProtoAuthSessionTable {
key: string;
value: string;
}
export interface AccountTable {
did: string;
email?: string;
handle: string;
avatar?: string;
active: boolean;
}
export interface EntryTable {
uri: string;
authorDid: string;
website: string;
note?: string;
tags: string[];
createdAt: Date;
indexedAt: Date;
}
export interface FollowTable {
uri: string;
follower: string;
following: string;
createdAt: Date;
indexedAt: Date;
}