import { Database } from "bun:sqlite"; import { mkdirSync, readFileSync } from "node:fs"; import path from "node:path"; import * as argon2 from "argon2"; import config from "../config.ts"; import { ADMIN_USERNAME, paths } from "../constants.ts"; // Ensure data directories exist mkdirSync(config.DATA_DIR, { recursive: true }); mkdirSync(paths.REPOS_DIR, { recursive: true }); mkdirSync(paths.AVATARS_DIR, { recursive: true }); const db = new Database(paths.DB_PATH); db.run("PRAGMA journal_mode=WAL"); db.run("PRAGMA foreign_keys=ON"); // Run schema const schema = readFileSync(path.join(import.meta.dir, "schema.sql"), "utf-8"); db.run(schema); // Seed admin account if not present const existing = db .query("SELECT id FROM users WHERE username = ?") .get(ADMIN_USERNAME); if (!existing) { const password = process.env.ADMIN_PASSWORD ?? "changeme"; const hash = await argon2.hash(password); const now = new Date().toISOString(); db.run( "INSERT INTO users (username, password_hash, created_at) VALUES (?, ?, ?)", [ADMIN_USERNAME, hash, now], ); console.log( `Created admin account (username: ${ADMIN_USERNAME}, password: ${password})`, ); if (password === "changeme") { console.warn( "WARNING: Using default admin password. Set ADMIN_PASSWORD env var before running db:init.", ); } } else { console.log("Admin account already exists."); } console.log("Database initialized at", paths.DB_PATH); db.close();