xref: /expo/tools/src/Logger.ts (revision eeffdb10)
1import chalk, { Chalk } from 'chalk';
2import readline from 'readline';
3
4type LogLevel = 'log' | 'debug' | 'info' | 'warn' | 'error';
5
6type LoggerResolver = (level: LogLevel, color: Chalk | null, args: string[]) => void;
7
8const CONSOLE_RESOLVER: LoggerResolver = (level: LogLevel, color: Chalk | null, args: string[]) => {
9  return console[level](...(color ? args.map((arg) => color(arg)) : args));
10};
11
12/**
13 * Basic logger just for simple console logging with colored output.
14 */
15export class Logger {
16  constructor(readonly resolver: LoggerResolver = CONSOLE_RESOLVER) {}
17
18  verbose(...args: any[]): void {
19    this.resolver('debug', chalk.dim, args);
20  }
21
22  debug(...args: any[]): void {
23    this.resolver('debug', chalk.gray, args);
24  }
25
26  log(...args: any[]): void {
27    this.resolver('log', null, args);
28  }
29
30  success(...args: any[]): void {
31    this.resolver('log', chalk.green, args);
32  }
33
34  info(...args: any[]): void {
35    this.resolver('info', chalk.cyan, args);
36  }
37
38  warn(...args: any[]): void {
39    this.resolver('warn', chalk.yellow.bold, args);
40  }
41
42  error(...args: any[]): void {
43    this.resolver('error', chalk.red.bold, args);
44  }
45
46  batch(): LoggerBatch {
47    return new LoggerBatch(this.resolver);
48  }
49
50  clearLine() {
51    readline.moveCursor(process.stdout, 0, -1);
52    readline.clearLine(process.stdout, 0);
53  }
54}
55
56/**
57 * Batched logger, it batches all logs until they're flushed.
58 * Useful for asynchronous simultaneous operations to preserve logs order.
59 */
60export class LoggerBatch extends Logger {
61  readonly batchedLogs: [LogLevel, Chalk | null, any[]][] = [];
62
63  constructor(readonly parentResolver: LoggerResolver = CONSOLE_RESOLVER) {
64    super((level, color, args) => {
65      this.batchedLogs.push([level, color, args]);
66    });
67    this.batchedLogs = [];
68  }
69
70  flush() {
71    this.batchedLogs.forEach(([level, color, args]) => this.parentResolver(level, color, args));
72    this.batchedLogs.length = 0;
73  }
74}
75
76export default new Logger();
77