recipes/web/server.ts

68 lines
1.8 KiB
TypeScript

import { StrRenderer } from "ren/str.ts";
import { Layout } from "./comp/layout.ts";
import { Context } from "./context.ts";
import { E404Page } from "./views/e404.ts";
import * as log from "./log.ts";
import { HomePage } from "./views/home.ts";
import { RecipesPage } from "./views/recipes.ts";
import { IngredientsPage } from "./views/ingredients.ts";
if (import.meta.main) {
await main();
}
async function main() {
await startServer({ port: 33334 });
}
async function startServer(cfg: ServerConfig) {
const srv = Deno.listen({ hostname: "localhost", port: cfg.port });
log.info(`Server listening at http://localhost:${cfg.port}`);
for await (const conn of srv) {
serveHttp(conn);
}
}
interface ServerConfig {
port: number;
}
async function serveHttp(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const reqEvt of httpConn) {
const res = handleRequest(reqEvt.request);
reqEvt.respondWith(res);
}
}
function handleRequest(req: Request): Response {
log.debug({ url: req.url });
const ren = new StrRenderer({ wrapNode: Layout });
const ctx = createContextFromRequest(req);
if (ctx.locPath === "/") {
return createHtmlResponse(ren.render(HomePage(ctx)));
} else if (ctx.locPath === "/recipes") {
return createHtmlResponse(ren.render(RecipesPage(ctx)));
} else if (ctx.locPath === "/ingredients") {
return createHtmlResponse(ren.render(IngredientsPage(ctx)));
} else {
return createHtmlResponse(ren.render(E404Page(ctx)), 404);
}
}
function createContextFromRequest(req: Request): Context {
return {
locPath: new URL(req.url).pathname,
};
}
function createHtmlResponse(body: string, status = 200): Response {
return new Response(body, {
status,
headers: { "content-type": "text/html" },
});
}