My personal website!
at trunk 62 lines 1.8 kB view raw
1import fs from "node:fs/promises"; 2import path from "node:path"; 3import express from "express"; 4import type { z } from "zod"; 5import { banner } from "./components/banner"; 6import { footer } from "./components/footer"; 7import { head } from "./components/head"; 8import type { Post } from "./utils/structs"; 9 10const app = express(); 11const port = process.env.PORT || 8080; 12 13app.use("/public", express.static(path.join(path.resolve(), "src/public"))); 14app.get("/", async (_req, res) => { 15 const content: z.infer<typeof Post>[] = JSON.parse( 16 await fs.readFile(path.join(path.resolve(), "data", "db.json"), "utf-8"), 17 ); 18 19 res.send(` 20 <!DOCTYPE html> 21 <html lang="en-US"> 22 ${head()} 23 <body> 24 <main> 25 <h1>From, <i class="me">Koehn</i></h1> 26 ${( 27 await Promise.all( 28 content 29 .filter((p) => !p.flags?.includes("private")) 30 .sort((a, b) => +b.published - +a.published) 31 .map(async (post) => { 32 let decoration: string = ""; 33 34 if (!post.flags.includes("source:local")) { 35 const flag = post.flags.find((f) => 36 f.startsWith("source:"), 37 ); 38 decoration = ` <span class="banner">[ ${flag?.split(":")[1]} ]</span>`; 39 } 40 41 return `<p role="article"><time class="mute" datetime="${post.published}">${ 42 new Date(post.published).toISOString().split("T")[0] 43 }</time>${decoration} <a href="${post.slug}">${post.title}</a></p>`; 44 }), 45 ) 46 ).join(" ")} 47 </main> 48 ${banner( 49 [ 50 { title: "about", link: "infer" }, 51 { title: "time machine", link: "infer" }, 52 ], 53 { home: false }, 54 )} 55 ${await footer()} 56 </html> 57 `); 58}); 59 60app.listen(port, () => { 61 console.log(`[INFO] Started listening on: ${port}`); 62});