hanchu/server/server.ts

111 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-10-20 12:51:30 +00:00
import { Database } from 'bun:sqlite';
2024-10-22 04:35:21 +00:00
import {
addUser,
fetchCard,
fetchLesson,
fetchLessons,
fetchResource,
} from './db';
2024-10-20 12:51:30 +00:00
2024-10-22 04:35:21 +00:00
const db = new Database('../db/data.db', { strict: true });
2024-10-20 12:51:30 +00:00
db.exec('PRAGMA journal_mode = WAL;');
Bun.serve({
fetch(req) {
const url = new URL(req.url);
2024-10-22 04:35:21 +00:00
console.log(url.pathname, 'url');
const user = parseUser(req);
2024-10-20 12:51:30 +00:00
if (req.method === 'POST' && url.pathname === '/api')
2024-10-22 04:35:21 +00:00
return handlePost(req, user, url);
2024-10-20 12:51:30 +00:00
if (req.method === 'GET' && url.pathname.startsWith('/api'))
2024-10-22 04:35:21 +00:00
return handleGet(req, user, url);
return serveStatic(url);
2024-10-20 12:51:30 +00:00
},
});
2024-10-22 04:35:21 +00:00
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);
2024-10-20 12:51:30 +00:00
else return new Response('huh');
}
2024-10-22 04:35:21 +00:00
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) {
2024-10-20 12:51:30 +00:00
const params = new URLSearchParams(url.search);
2024-10-22 04:35:21 +00:00
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;
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 });
2024-10-20 12:51:30 +00:00
}
2024-10-22 04:35:21 +00:00
async function handlePost(req: Request, user: number, url: URL) {
2024-10-20 12:51:30 +00:00
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) {
2024-10-22 04:35:21 +00:00
addUser(db, user.name, user.creds);
2024-10-20 12:51:30 +00:00
return new Response('ok');
}