this repo has no description
1import http from 'node:http';
2import { URL } from 'node:url';
3
4import {
5 buildGraphSvg,
6 clampRange,
7 fetchActivityByDay,
8 normalizeAccount,
9} from './tangledGraph';
10
11const PORT = Number(process.env.PORT ?? 3000);
12
13const server = http.createServer(async (req, res) => {
14 if (!req.url) {
15 res.statusCode = 400;
16 res.end('Bad Request');
17 return;
18 }
19
20 const url = new URL(req.url, `http://localhost:${PORT}`);
21
22 if (url.pathname !== '/api/graph') {
23 res.statusCode = 404;
24 res.setHeader('Content-Type', 'text/plain; charset=utf-8');
25 res.end('Not Found');
26 return;
27 }
28
29 const account = normalizeAccount(url.searchParams.get('account') ?? undefined);
30 const range = clampRange(url.searchParams.get('range') ?? undefined);
31
32 res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8');
33 res.setHeader('Cache-Control', 'no-store');
34
35 if (!account) {
36 res.statusCode = 400;
37 res.end(
38 buildGraphSvg({
39 account: 'unknown',
40 range,
41 days: [],
42 error: 'Missing or invalid account parameter',
43 }),
44 );
45 return;
46 }
47
48 try {
49 const days = await fetchActivityByDay(account, range);
50 res.statusCode = 200;
51 res.end(buildGraphSvg({ account, range, days }));
52 } catch (error) {
53 const message = error instanceof Error ? error.message : 'Failed to load feed';
54 res.statusCode = 502;
55 res.end(
56 buildGraphSvg({
57 account,
58 range,
59 days: [],
60 error: message,
61 }),
62 );
63 }
64});
65
66server.listen(PORT, () => {
67 process.stdout.write(`Local server running at http://localhost:${PORT}\n`);
68});