import { Database as BunDatabase } from "bun:sqlite"; import { type Generated, Kysely, type Selectable } from "kysely"; import { BunSqliteDialect } from "kysely-bun-sqlite"; import { DB_PATH } from "../constants.ts"; interface UserTable { id: Generated; username: string; password_hash: string | null; created_at: string; avatar_version: Generated; } interface PasskeyTable { id: Generated; user_id: number; credential_id: string; public_key: string; counter: number; created_at: string; } interface SessionTable { id: string; user_id: number; expires_at: string; created_at: string; } interface RepositoryTable { id: Generated; name: string; description: string | null; is_private: number; default_branch: string; created_at: string; issue_seq: Generated; patch_seq: Generated; issue_template: string | null; patch_template: string | null; } interface IssueTable { id: Generated; repo_id: number; author_id: number | null; number: number; title: string; body: string; status: string; created_at: string; updated_at: string; edited_at: string | null; } interface IssueCommentTable { id: Generated; issue_id: number; author_id: number | null; body: string; created_at: string; edited_at: string | null; } interface IssueReactionTable { id: Generated; issue_id: number; comment_id: number | null; user_id: number; emoji: string; } interface PatchTable { id: Generated; repo_id: number; author_id: number | null; number: number; title: string; description: string; patch_content: string; status: string; author_name: string; author_email: string; created_at: string; updated_at: string; edited_at: string | null; } interface PatchCommentTable { id: Generated; patch_id: number; author_id: number | null; body: string; created_at: string; edited_at: string | null; } interface PatchReactionTable { id: Generated; patch_id: number; comment_id: number | null; user_id: number; emoji: string; } interface SshKeyTable { id: Generated; user_id: number; name: string; public_key: string; fingerprint: string; created_at: string; } interface ReleaseTable { id: Generated; repo_id: number; tag_name: string | null; name: string; notes: string | null; include_source_code: number; created_at: string; } interface ReleaseAssetTable { id: Generated; release_id: number; filename: string; size: number; content_type: string; created_at: string; } export interface Database { users: UserTable; passkeys: PasskeyTable; sessions: SessionTable; repositories: RepositoryTable; issues: IssueTable; issue_comments: IssueCommentTable; issue_reactions: IssueReactionTable; patches: PatchTable; patch_comments: PatchCommentTable; patch_reactions: PatchReactionTable; ssh_keys: SshKeyTable; releases: ReleaseTable; release_assets: ReleaseAssetTable; } // Selectable row types (id is plain number, as returned by queries) export type UserRow = Selectable; export type PasskeyRow = Selectable; export type SessionRow = Selectable; export type RepositoryRow = Selectable; export type IssueRow = Selectable; export type IssueCommentRow = Selectable; export type IssueReactionRow = Selectable; export type PatchRow = Selectable; export type PatchCommentRow = Selectable; export type PatchReactionRow = Selectable; export type SshKeyRow = Selectable; export type ReleaseRow = Selectable; export type ReleaseAssetRow = Selectable; const sqlite = new BunDatabase(DB_PATH); sqlite.run("PRAGMA journal_mode=WAL"); sqlite.run("PRAGMA foreign_keys=ON"); export const db = new Kysely({ dialect: new BunSqliteDialect({ database: sqlite }), }); export async function getRepo(name: string, isAdmin: boolean) { const repo = await db .selectFrom("repositories") .selectAll() .where("name", "=", name) .executeTakeFirst(); if (!repo) return null; if (repo.is_private && !isAdmin) return null; return repo; }