annotate react_games/backend/routes/todo.ts @ 96:70401cf61e97

[Seobeo] Added logging.
author June Park <parkjune1995@gmail.com>
date Fri, 02 Jan 2026 19:16:17 -0800
parents fb9bcd3145cb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 import { Router } from 'express';
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2 import * as fs from 'node:fs/promises';
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 import path from 'node:path';
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 import crypto from 'node:crypto';
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 type Todo = { id: string; value: string; status: number };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 /** Idk aynthing about encryption but this seemed fine to me so just going to use this... **/
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 const ALGO = 'aes-256-gcm';
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 const KEYLEN = 32;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11 const IVLEN = 12;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 const SALTLEN = 16;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 const PEPPER = process.env.TODO_PEPPER ?? ''; // optional server-side secret
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15 type EncryptedPayload = {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 v: 1;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 kdf: 'scrypt';
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 salt: string; // base64
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 iv: string; // base64
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 tag: string; // base64
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 ciphertext: string;// base64
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 // ---- crypto helpers --------------------------------------------------------
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 function kdf(passphrase: string, salt: Buffer): Buffer {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 // scryptSync is fine for small payloads; use async/promisified if you prefer.
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 return crypto.scryptSync(passphrase, salt, KEYLEN);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 function encryptJSON(data: unknown, keyword: string): EncryptedPayload {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 const salt = crypto.randomBytes(SALTLEN);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 const key = kdf(keyword + PEPPER, salt);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 const iv = crypto.randomBytes(IVLEN);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 const cipher = crypto.createCipheriv(ALGO, key, iv);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 const plaintext = Buffer.from(JSON.stringify(data), 'utf8');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 const tag = cipher.getAuthTag();
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 return {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 v: 1,
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43 kdf: 'scrypt',
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 salt: salt.toString('base64'),
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 iv: iv.toString('base64'),
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 tag: tag.toString('base64'),
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 ciphertext: ciphertext.toString('base64'),
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 function decryptJSON(payload: EncryptedPayload, keyword: string): any {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 const salt = Buffer.from(payload.salt, 'base64');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 const iv = Buffer.from(payload.iv, 'base64');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 const tag = Buffer.from(payload.tag, 'base64');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 const ciphertext = Buffer.from(payload.ciphertext, 'base64');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 const key = kdf(keyword + PEPPER, salt);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 const decipher = crypto.createDecipheriv(ALGO, key, iv);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 decipher.setAuthTag(tag);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 return JSON.parse(plaintext.toString('utf8'));
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 // ---- path helper: derive a file path from keyword --------------------------
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67 function pathForKeyword(baseDir: string, keyword: string): string {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 // Hash the keyword so you don’t leak it in the filename and to avoid FS-unsafe chars.
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 const h = crypto.createHash('sha256').update(keyword, 'utf8').digest('hex');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 // Optional sharding to keep directories small:
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 return path.join(baseDir, h.slice(0, 2), `${h}.json`);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 // ---- router ----------------------------------------------------------------
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 const getInitialTodos = () => [
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 id: crypto.randomUUID(),
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 value: "Hello from TODO",
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79 status: 0,
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 ]
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82 export function createTodoRouter(dataFileOrDir: string) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 const router = Router();
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 // Support both a file path (old) or a directory (new). We’ll store under that directory.
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 const baseDir = path.extname(dataFileOrDir)
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 ? path.dirname(dataFileOrDir)
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 : dataFileOrDir;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 const requireKeyword = (req: any): string => {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 const key = (typeof req.query.key === 'string' && req.query.key) || req.header('x-keyword');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 if (typeof key !== 'string' || !key.trim()) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 throw Object.assign(new Error('Missing ?key= query or x-keyword header'), { status: 400 });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 return key.trim();
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 const readTodos = async (userKeyword: string): Promise<Todo[]> => {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 const filePath = pathForKeyword(baseDir, userKeyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 try {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 const raw = await fs.readFile(filePath, 'utf8');
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 const parsed = JSON.parse(raw);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 // If this looks like an encrypted payload, decrypt; else treat as plaintext array for backward compat.
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 if (parsed && parsed.ciphertext && parsed.iv && parsed.tag && parsed.salt) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 return decryptJSON(parsed as EncryptedPayload, userKeyword) as Todo[];
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 // fallback (legacy plaintext)
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 return parsed as Todo[];
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 } catch (e: any) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 if (e?.code === 'ENOENT') {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 const initial = getInitialTodos();
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 await writeTodos(initial, userKeyword); // create the file immediately
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 return initial;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 throw e;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 const writeTodos = async (todos: Todo[], userKeyword: string) => {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 const filePath = pathForKeyword(baseDir, userKeyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122 await fs.mkdir(path.dirname(filePath), { recursive: true });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 const payload = encryptJSON(todos, userKeyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 await fs.writeFile(filePath, JSON.stringify(payload, null, 2), { encoding: 'utf8', mode: 0o600 });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 router.get('/', async (req, res) => {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 try {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 const keyword = requireKeyword(req);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 const todos = await readTodos(keyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 res.json({ todos });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 } catch (err: any) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 res.status(err?.status || 500).json({ error: err?.message || 'Internal error' });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 router.post('/', async (req, res) => {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 try {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 const keyword = requireKeyword(req);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141 const body = req.body?.newTodo;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142 if (!body || typeof body.value !== 'string' || typeof body.status !== 'number') {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143 return res.status(400).json({ newTodo: null });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 const todos = await readTodos(keyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 const todo: Todo = {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 id: body.id ?? crypto.randomUUID(),
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 value: body.value,
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 status: body.status,
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 };
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 todos.push(todo);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 // Optional chaos test:
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155 // await new Promise(r => setTimeout(r, 1000));
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 // if (Math.random() > 0.5) return res.status(400).json({ newTodo: null });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 await writeTodos(todos, keyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 res.status(200).json({ newTodo: todo, todos }); // keep your shape if you prefer
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 } catch (err: any) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 res.status(err?.status || 500).json({ error: err?.message || 'Internal error' });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 router.patch('/', async (req, res) => {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 try {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 const keyword = requireKeyword(req);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 const body = req.body;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170 if (!body || typeof body.todoId !== 'string' || typeof body.status !== 'number') {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 return res.status(400).json({ newTodo: null });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 const todos = (await readTodos(keyword)).map(
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 (todo) => todo.id === body.todoId ? {...todo, status: body.status } : todo);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 await writeTodos(todos, keyword);
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 res.status(200).json({ todos });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179 } catch (err: any) {
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 res.status(err?.status || 500).json({ error: err?.message || 'Internal error' });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 }
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 });
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 return router;
fb9bcd3145cb [ReactGames] Few games I made using react just to practice few things.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 }