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