From 5a1ec40e1b321b1b985ec3ebacdc6be88e0ba069 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Fri, 3 Oct 2025 16:03:53 +0200 Subject: [PATCH] feat: champions leauge server --- C/opening_learner/mistakes.txt | 16 +++ .../server/src/server.ts | 103 ++++++++++++------ 2 files changed, 86 insertions(+), 33 deletions(-) diff --git a/C/opening_learner/mistakes.txt b/C/opening_learner/mistakes.txt index 3512742..e07ec74 100644 --- a/C/opening_learner/mistakes.txt +++ b/C/opening_learner/mistakes.txt @@ -10,3 +10,19 @@ FEN:rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPPKPPP/RNBQ1BNR b kq - 1 2 BEST:d7d5 LINE:e2e3 e7e5 e1e2 . +FEN:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 +BEST: +LINE: +. +FEN:rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq - 1 1 +BEST:e7e5 +LINE:g1h3 +. +FEN:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 +BEST: +LINE: +. +FEN:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 +BEST: +LINE: +. diff --git a/TS/champions_leauge_scores/server/src/server.ts b/TS/champions_leauge_scores/server/src/server.ts index 88362e9..793b02a 100644 --- a/TS/champions_leauge_scores/server/src/server.ts +++ b/TS/champions_leauge_scores/server/src/server.ts @@ -28,54 +28,91 @@ app.use((_req, res, next) => { app.use((req, res, next) => { const start = process.hrtime.bigint(); const id = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`; + const MAX_LOG_BODY = 2000; // chars + const clip = (s: string) => (s && s.length > MAX_LOG_BODY ? `${s.slice(0, MAX_LOG_BODY)}…(+${s.length - MAX_LOG_BODY})` : s); + // Attach id so downstream handlers could use it if needed (res as any).locals = { ...(res as any).locals, requestId: id }; + // Patch res.json and res.send to capture response payload + const originalJson = res.json.bind(res); + const originalSend = res.send.bind(res); + (res as any).json = (body: any) => { + try { (res as any).locals.bodyForLog = body; } catch { /* ignore */ } + return originalJson(body); + }; + (res as any).send = (body: any) => { + try { (res as any).locals.bodyForLog = body; } catch { /* ignore */ } + return originalSend(body as any); + }; + // eslint-disable-next-line no-console - console.log(`[#${id}] -> ${req.method} ${req.originalUrl} ` + - (Object.keys(req.query || {}).length ? `query=${JSON.stringify(req.query)}` : '')); + console.log(`[#${id}] -> ${req.method} ${req.originalUrl}` + (Object.keys(req.query || {}).length ? ` query=${JSON.stringify(req.query)}` : '')); res.on('finish', () => { const durMs = Number(process.hrtime.bigint() - start) / 1_000_000; + let bodyPreview = ''; + try { + const body = (res as any).locals?.bodyForLog; + if (body !== undefined) { + const str = typeof body === 'string' ? body : JSON.stringify(body); + bodyPreview = ` body=${clip(str)}`; + } + } catch { /* ignore */ } // eslint-disable-next-line no-console - console.log(`[#${id}] <- ${req.method} ${req.originalUrl} ${res.statusCode} ${durMs.toFixed(1)}ms`); + console.log(`[#${id}] <- ${req.method} ${req.originalUrl} ${res.statusCode} ${durMs.toFixed(1)}ms${bodyPreview}`); }); next(); }); // Axios interceptors to log outgoing requests and incoming responses -axios.interceptors.request.use((config) => { - (config as any).metadata = { start: Date.now() }; - // eslint-disable-next-line no-console - console.log(`[axios ->] ${String(config.method || 'GET').toUpperCase()} ${config.url}`); - return config; -}, (error) => { - // eslint-disable-next-line no-console - console.warn('[axios req error]', error?.message || error); - return Promise.reject(error); -}); +axios.interceptors.request.use( + (config) => { + (config as any).metadata = { start: Date.now() }; + // eslint-disable-next-line no-console + console.log(`[axios ->] ${String(config.method || 'GET').toUpperCase()} ${config.url}`); + return config; + }, + (error) => { + // eslint-disable-next-line no-console + console.warn('[axios req error]', error?.message || error); + return Promise.reject(error); + } +); -axios.interceptors.response.use((response) => { - const started = (response.config as any).metadata?.start || Date.now(); - const dur = Date.now() - started; - let size = 0; - try { - const d = typeof response.data === 'string' ? response.data : JSON.stringify(response.data); - size = d?.length || 0; - } catch (_e) { /* ignore */ } - // eslint-disable-next-line no-console - console.log(`[axios <-] ${response.status} ${String(response.config.method || 'GET').toUpperCase()} ${response.config.url} ${dur}ms ~${size}B`); - return response; -}, (error) => { - const cfg = error?.config || {}; - const started = (cfg as any).metadata?.start || Date.now(); - const dur = Date.now() - started; - const status = error?.response?.status; - // eslint-disable-next-line no-console - console.warn(`[axios ! ] ${status ?? 'ERR'} ${String(cfg.method || 'GET').toUpperCase()} ${cfg.url} ${dur}ms`, error?.response?.data || error?.message); - return Promise.reject(error); -}); +axios.interceptors.response.use( + (response) => { + const started = (response.config as any).metadata?.start || Date.now(); + const dur = Date.now() - started; + let dataStr = ''; + try { + dataStr = typeof response.data === 'string' ? response.data : JSON.stringify(response.data); + } catch { /* ignore */ } + const size = dataStr?.length || 0; + const MAX_LOG_BODY = 2000; + const clip = (s: string) => (s && s.length > MAX_LOG_BODY ? `${s.slice(0, MAX_LOG_BODY)}…(+${s.length - MAX_LOG_BODY})` : s); + // eslint-disable-next-line no-console + console.log(`[axios <-] ${response.status} ${String(response.config.method || 'GET').toUpperCase()} ${response.config.url} ${dur}ms ~${size}B data=${clip(dataStr)}`); + return response; + }, + (error) => { + const cfg = error?.config || {}; + const started = (cfg as any).metadata?.start || Date.now(); + const dur = Date.now() - started; + const status = error?.response?.status; + let dataStr = ''; + try { + const d = error?.response?.data; + dataStr = typeof d === 'string' ? d : JSON.stringify(d); + } catch { /* ignore */ } + const MAX_LOG_BODY = 2000; + const clip = (s: string) => (s && s.length > MAX_LOG_BODY ? `${s.slice(0, MAX_LOG_BODY)}…(+${s.length - MAX_LOG_BODY})` : s); + // eslint-disable-next-line no-console + console.warn(`[axios ! ] ${status ?? 'ERR'} ${String(cfg.method || 'GET').toUpperCase()} ${cfg.url} ${dur}ms data=${dataStr ? clip(dataStr) : (error?.message || 'error')}`); + return Promise.reject(error); + } +); app.get('/health', (_req: Request, res: Response) => res.json({ ok: true }));