import { startReminders } from "./reminders/worker"; import { backupConfig, startBackups } from "./ops/backups"; import { databasePath } from "./db/config"; import { db, sqlite } from "./db"; import { createApi } from "./api"; import { readAuthConfig } from "./auth/config"; import { readDiscordSharingConfig } from "./sharing/config"; import index from "./index.html"; import { migrate } from "drizzle-orm/bun-sqlite/migrator"; // Hot reloads skip the package script's migration step. Apply pending changes // before the reloaded development server accepts requests. if (process.env.NODE_ENV !== "production") { migrate(db, { migrationsFolder: "./drizzle" }); } const backups = process.env.NODE_ENV === "production" ? startBackups(sqlite, backupConfig(databasePath)) : undefined; await backups?.ready; if (import.meta.hot) import.meta.hot.dispose(() => backups?.stop()); const reminders = process.env.NODE_ENV === "production" ? startReminders(db, { token: readDiscordSharingConfig().token, origin: readAuthConfig().origin, commandsAvailable: /^[a-f\d]{64}$/i.test(process.env.DISCORD_PUBLIC_KEY ?? "") && Boolean(readAuthConfig().clientId) }) : undefined; if (import.meta.hot) import.meta.hot.dispose(() => reminders?.stop()); const app = createApi(db, readAuthConfig(), undefined, undefined, undefined, readDiscordSharingConfig(), { discord: { publicKey: process.env.DISCORD_PUBLIC_KEY ?? "", applicationId: readAuthConfig().clientId, origin: readAuthConfig().origin }, healthy: () => !backups?.state.enabled || (!backups.state.failed && backups.state.lastSuccess > 0) }); if (import.meta.hot) import.meta.hot.dispose(() => app.stopLiveSharing()); const server = Bun.serve({ hostname: process.env.HOST ?? "127.0.0.1", port: Number(process.env.PORT ?? 3000), routes: { "/api": req => app.fetch(req), "/api/*": req => app.fetch(req), "/*": index, }, development: process.env.NODE_ENV !== "production" && { hmr: true, console: true, }, }); console.log(`Server running at ${server.url}`);