103 lines · 2.6 KB · TypeScript
RawDownload
import util from "node:util"; type LogLevel = "info" | "warn" | "error" | "event"; type LogContext = Record<string, unknown>; const ANSI = {  reset: "\u001b[0m",  dim: "\u001b[2m",  cyan: "\u001b[36m",  yellow: "\u001b[33m",  red: "\u001b[31m",  magenta: "\u001b[35m",} as const; const LEVEL_LABEL: Record<LogLevel, string> = {  info: "INFO",  warn: "WARN",  error: "ERROR",  event: "EVENT",}; const LEVEL_COLOR: Record<LogLevel, string> = {  info: ANSI.cyan,  warn: ANSI.yellow,  error: ANSI.red,  event: ANSI.magenta,}; function useColors() {  return Boolean(process.stdout.isTTY) && process.env.NO_COLOR === undefined;} function colorize(value: string, color: string, enabled: boolean) {  return enabled ? `${color}${value}${ANSI.reset}` : value;} function timeStamp() {  return new Date().toISOString().slice(11, 23);} function formatValue(value: unknown) {  if (typeof value === "string") {    return JSON.stringify(value);  }  if (    typeof value === "number" ||    typeof value === "boolean" ||    value === null ||    value === undefined  ) {    return String(value);  }  return util.inspect(value, {    depth: 4,    breakLength: Infinity,    compact: true,    maxArrayLength: 25,    maxStringLength: 320,  });} function formatContext(context: LogContext | undefined) {  if (!context) return "";  const entries = Object.entries(context).filter(([, value]) => value !== undefined);  if (entries.length === 0) return "";  return entries.map(([key, value]) => `${key}=${formatValue(value)}`).join(" ");} function write(level: LogLevel, scope: string, message: string, context?: LogContext) {  const colorEnabled = useColors();  const ts = colorize(timeStamp(), ANSI.dim, colorEnabled);  const levelLabel = colorize(LEVEL_LABEL[level], LEVEL_COLOR[level], colorEnabled);  const contextText = formatContext(context);  const line = `${ts} ${levelLabel} [${scope}] ${message}${contextText ? ` ${contextText}` : ""}`;   if (level === "warn") {    console.warn(line);    return;  }  if (level === "error") {    console.error(line);    return;  }  console.log(line);} export function createLogger(scope: string) {  return {    info(message: string, context?: LogContext) {      write("info", scope, message, context);    },    warn(message: string, context?: LogContext) {      write("warn", scope, message, context);    },    error(message: string, context?: LogContext) {      write("error", scope, message, context);    },    event(message: string, context?: LogContext) {      write("event", scope, message, context);    },  };}