hanchu/server/server.ts
2024-10-22 15:45:52 +07:00

112 lines
3.4 KiB
TypeScript

import { Database } from "bun:sqlite";
import {
addUser,
fetchCard,
fetchLesson,
fetchLessons,
fetchResource,
} from "./db";
const db = new Database("../db/data.db", { strict: true });
db.exec("PRAGMA journal_mode = WAL;");
Bun.serve({
fetch(req) {
const url = new URL(req.url);
console.log(url.pathname, "url");
const user = parseUser(req);
if (req.method === "POST" && url.pathname === "/api")
return handlePost(req, user, url);
if (req.method === "GET" && url.pathname.startsWith("/api"))
return handleGet(req, user, url);
return serveStatic(url);
},
});
function parseUser(req: Request): number {
// console.log(req, 'request');
return 0;
}
async function serveStatic(url: URL) {
const filename = url.pathname === "/" ? "/index.html" : url.pathname;
const headers = { "Content-type": "text/html" };
const opts = { headers };
try {
const file = await Bun.file(`../ui/${filename}`).bytes();
return new Response(file, opts);
} catch (_) {
return new Response("404!");
}
}
async function handleGet(_req: Request, user: number, url: URL) {
if (url.pathname === "/api/resource") return handleGetExpresion(user, url);
if (url.pathname === "/api/card") return handleGetCard(user, url);
if (url.pathname === "/api/lesson") return handleGetLesson(user, url);
if (url.pathname === "/api/lessons") return handleGetLessons(user, url);
else return new Response("huh");
}
function handleGetExpresion(user: number, url: URL) {
const params = new URLSearchParams(url.search);
const expression = params.get("exp");
const data = fetchResource(db, expression!);
return Response.json({ ok: data });
}
type LessonsType = Record<
number,
{
id: number;
text: string;
cards: Array<{ text: string; note: string | null; id: number }>;
}
>;
type LessonsDBType = {
id: number;
ltext: string;
ctext: string;
cnote: string | null;
cid: number;
};
function handleGetLesson(user: number, url: URL) {
const params = new URLSearchParams(url.search);
const lesson = params.get("lesson");
const data = fetchLesson(db, Number(lesson!));
return Response.json({ ok: data });
}
function handleGetCard(user: number, url: URL) {
const params = new URLSearchParams(url.search);
const card = params.get("card");
const data = fetchCard(db, Number(card), user);
return Response.json({ ok: data });
}
function handleGetLessons(user: number, url: URL) {
const params = new URLSearchParams(url.search);
const page = params.get("page") || "0";
const data: LessonsDBType[] = fetchLessons(db, 20, Number(page)) as any;
console.log(data, "fetchlessons");
const lessons = data.reduce((acc: LessonsType, item: LessonsDBType) => {
let cur = acc[item.id] || { id: item.id, text: item.ltext, cards: [] };
const cards = [
...cur.cards,
{ text: item.ctext, note: item.cnote, id: item.cid },
];
const def = { ...cur, cards };
return { ...acc, [item.id]: def };
}, {} as LessonsType);
console.log(lessons, "lesons");
return Response.json({ ok: lessons });
}
async function handlePost(req: Request, user: number, url: URL) {
const data = await req.json();
if (url.pathname === "/api/user") return handlePostUser(data);
else return new Response("huh");
}
// https://bun.sh/guides/http/server
type PostUser = { name: string; creds: string };
function handlePostUser(user: PostUser) {
addUser(db, user.name, user.creds);
return new Response("ok");
}