45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import { Hono } from "hono";
|
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
import { readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { LIMITS } from "../shared/types";
|
|
import { createCatalogRepo } from "./catalog-repo";
|
|
import { openDatabase } from "./db";
|
|
import type { Env } from "./env";
|
|
import { HttpError } from "./errors";
|
|
import { createRateLimiter } from "./rate-limit";
|
|
import { catalogRoutes } from "./routes/catalogs";
|
|
|
|
export async function createApp(env: Env, options?: { now?: () => number }) {
|
|
const db = await openDatabase(env.databasePath);
|
|
const repo = createCatalogRepo(db);
|
|
const limiter = createRateLimiter(
|
|
LIMITS.maxCreatesPerHour,
|
|
LIMITS.rateWindowMs,
|
|
options?.now,
|
|
);
|
|
|
|
const app = new Hono();
|
|
|
|
app.onError((err, c) => {
|
|
if (err instanceof HttpError) {
|
|
return c.json({ error: err.message }, err.status as 400);
|
|
}
|
|
console.error(err);
|
|
return c.json({ error: "خطای داخلی سرور" }, 500);
|
|
});
|
|
|
|
app.route("/api", catalogRoutes({ env, repo, limiter }));
|
|
|
|
if (env.isProduction) {
|
|
const dist = "./dist";
|
|
app.use("/*", serveStatic({ root: dist }));
|
|
app.get("*", async (c) => {
|
|
const html = await readFile(path.join("dist", "index.html"), "utf8");
|
|
return c.html(html);
|
|
});
|
|
}
|
|
|
|
return app;
|
|
}
|