-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlocal-preview.mjs
More file actions
62 lines (56 loc) · 2.54 KB
/
Copy pathlocal-preview.mjs
File metadata and controls
62 lines (56 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { createServer } from "node:http";
import { readFile, stat } from "node:fs/promises";
import { extname, join, normalize } from "node:path";
import { DEMO_STORIES } from "./src/config.js";
import { answerQuestion } from "./src/chat.js";
const port = Number(process.env.PORT || 8787);
const publicDir = join(process.cwd(), "public");
createServer(async (request, response) => {
const url = new URL(request.url, `http://${request.headers.host}`);
if (url.pathname === "/api/news") return sendJson(response, {
stories: DEMO_STORIES.filter((story) => !url.searchParams.get("category") || url.searchParams.get("category") === "all" || story.category === url.searchParams.get("category")),
updated_at: new Date().toISOString(),
demo: true
});
if (url.pathname === "/api/refresh" && request.method === "POST") return sendJson(response, {
new_count: 0,
message: "All caught up. No new finance stories found.",
updated_at: new Date().toISOString()
});
if (url.pathname === "/api/preferences" && request.method === "POST") return sendJson(response, { ok: true });
if (url.pathname === "/api/chat" && request.method === "POST") {
const body = await readBody(request);
return sendJson(response, await answerQuestion({}, String(body.question || ""), DEMO_STORIES));
}
const relative = url.pathname === "/" ? "index.html" : url.pathname.slice(1);
const path = normalize(join(publicDir, relative));
if (!path.startsWith(publicDir)) return send(response, 403, "Forbidden");
try {
if (!(await stat(path)).isFile()) throw new Error("Not found");
return send(response, 200, await readFile(path), contentType(path));
} catch {
return send(response, 404, "Not found");
}
}).listen(port, "0.0.0.0", () => console.log(`Morning Ledger preview: http://0.0.0.0:${port}`));
async function readBody(request) {
let body = "";
for await (const chunk of request) body += chunk;
return JSON.parse(body || "{}");
}
function sendJson(response, value) {
return send(response, 200, JSON.stringify(value), "application/json; charset=utf-8");
}
function send(response, status, body, type = "text/plain; charset=utf-8") {
response.writeHead(status, { "content-type": type });
response.end(body);
}
function contentType(path) {
return {
".html": "text/html; charset=utf-8",
".css": "text/css; charset=utf-8",
".js": "text/javascript; charset=utf-8",
".json": "application/json; charset=utf-8",
".webmanifest": "application/manifest+json",
".svg": "image/svg+xml"
}[extname(path)] || "application/octet-stream";
}