logger.ts
1import chalk from 'chalk'
2
3type LogLevel = 'info' | 'warn' | 'error' | 'debug' | 'verbose'
4
5export default class Logger {
6 private static readonly colors: Record<LogLevel, (text: string) => string> = {
7 info: chalk.blue,
8 warn: chalk.yellow,
9 error: chalk.red,
10 debug: chalk.green,
11 verbose: chalk.gray,
12 }
13
14 private static readonly isDebugMode = process.argv.includes('/debug')
15
16 private static getCallerInfo(): string {
17 const error = new Error()
18 const stack = error.stack?.split('\n')[3]
19 if (!stack) return 'unknown'
20
21 const match = stack.match(/at (?:(.+?)\s+\()?(?:(.+?):(\d+):(\d+))/)
22 if (!match) return 'unknown'
23
24 const [, fnName, filePath] = match
25 const fileName = filePath?.split(/[/\\]/).pop() || 'unknown'
26 return fnName ?
27 `${fileName.replace('.ts', '').replace('.js', '')}::${fnName}`
28 : fileName.replace('.ts', '').replace('.js', '')
29 }
30
31 public static log(level: LogLevel, message: string, context?: string): void {
32 if (level === 'debug' && !this.isDebugMode) return
33
34 const color = Logger.colors[level]
35 const caller = context || this.getCallerInfo()
36 console.log(`[${color(level.toUpperCase())}] [${caller}]: ${message}`)
37 }
38}
39