62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
import "server-only";
|
|
|
|
const DEBUG = process.env.NODE_ENV !== "production";
|
|
const MAX_ARRAY_ITEMS = 3;
|
|
|
|
const RESET = "\x1b[0m";
|
|
const CYAN = "\x1b[36m";
|
|
const GREEN = "\x1b[32m";
|
|
const YELLOW = "\x1b[33m";
|
|
const RED = "\x1b[31m";
|
|
const BOLD = "\x1b[1m";
|
|
const DIM = "\x1b[2m";
|
|
|
|
function statusColor(status: number): string {
|
|
if (status >= 500) return RED;
|
|
if (status >= 400) return YELLOW;
|
|
return GREEN;
|
|
}
|
|
|
|
/**
|
|
* Keeps big paginated lists (e.g. a 19-store `results` array) from flooding the
|
|
* terminal — shows the first few items of any array plus a count, recursively.
|
|
*/
|
|
function truncateForLog(value: unknown): unknown {
|
|
if (Array.isArray(value)) {
|
|
const shown = value.slice(0, MAX_ARRAY_ITEMS).map(truncateForLog);
|
|
if (value.length > MAX_ARRAY_ITEMS) shown.push(`… ${value.length - MAX_ARRAY_ITEMS} more item(s)`);
|
|
return shown;
|
|
}
|
|
if (value && typeof value === "object") {
|
|
return Object.fromEntries(Object.entries(value).map(([key, v]) => [key, truncateForLog(v)]));
|
|
}
|
|
return value;
|
|
}
|
|
|
|
function prettyJson(value: unknown): string {
|
|
return JSON.stringify(truncateForLog(value), null, 2);
|
|
}
|
|
|
|
function indent(text: string): string {
|
|
return text
|
|
.split("\n")
|
|
.map((line) => ` ${line}`)
|
|
.join("\n");
|
|
}
|
|
|
|
/**
|
|
* Dev-only request/response logging — the terminal-equivalent of Chrome's Network
|
|
* tab for server-side calls, since they run on the Next.js server and the browser
|
|
* never sees them (no CORS on the Winofy API). Never runs in production.
|
|
*/
|
|
export function logWinofyRequest(method: string, url: string, body: unknown) {
|
|
if (!DEBUG) return;
|
|
console.log(`\n${CYAN}→ [winofy]${RESET} ${BOLD}${method}${RESET} ${url}`);
|
|
if (body !== undefined) console.log(`${DIM} body:${RESET}\n${indent(prettyJson(body))}`);
|
|
}
|
|
|
|
export function logWinofyResponse(method: string, url: string, status: number, data: unknown) {
|
|
if (!DEBUG) return;
|
|
console.log(`${statusColor(status)}← [winofy] ${status}${RESET} ${BOLD}${method}${RESET} ${url}`);
|
|
if (data !== null && data !== undefined) console.log(`${DIM} data:${RESET}\n${indent(prettyJson(data))}`);
|
|
}
|