about summary refs log tree commit diff
path: root/src/logger/transports/console.ts
blob: 1f760630a44f4c5345024362ef90dcd31ff65fc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import format from 'date-fns/format'

import {LogLevel, type Transport} from '#/logger/types'
import {prepareMetadata} from '#/logger/util'
import {isWeb} from '#/platform/detection'

/**
 * Used in dev mode to nicely log to the console
 */
export const consoleTransport: Transport = (
  level,
  context,
  message,
  metadata,
  timestamp,
) => {
  const hasMetadata = Object.keys(metadata).length
  const colorize = withColor(
    {
      [LogLevel.Debug]: colors.magenta,
      [LogLevel.Info]: colors.blue,
      [LogLevel.Log]: colors.green,
      [LogLevel.Warn]: colors.yellow,
      [LogLevel.Error]: colors.red,
    }[level],
  )

  let msg = `${colorize(format(timestamp, 'HH:mm:ss'))}`
  if (context) {
    msg += ` ${colorize(`(${context})`)}`
  }
  if (message) {
    msg += ` ${message.toString()}`
  }

  if (isWeb) {
    if (hasMetadata) {
      console.groupCollapsed(msg)
      console.log(metadata)
      console.groupEnd()
    } else {
      console.log(msg)
    }
    if (message instanceof Error) {
      // for stacktrace
      console.error(message)
    }
  } else {
    if (hasMetadata) {
      msg += ` ${JSON.stringify(prepareMetadata(metadata), null, 2)}`
    }
    console.log(msg)
    if (message instanceof Error) {
      // for stacktrace
      console.error(message)
    }
  }
}

/**
 * Color handling copied from Kleur
 *
 * @see https://github.com/lukeed/kleur/blob/fa3454483899ddab550d08c18c028e6db1aab0e5/colors.mjs#L13
 */
const colors: {
  [key: string]: [number, number]
} = {
  default: [0, 0],
  blue: [36, 39],
  green: [32, 39],
  magenta: [35, 39],
  red: [31, 39],
  yellow: [33, 39],
}

function withColor([x, y]: [number, number]) {
  const rgx = new RegExp(`\\x1b\\[${y}m`, 'g')
  const open = `\x1b[${x}m`,
    close = `\x1b[${y}m`

  return function (txt: string) {
    if (txt == null) return txt

    return (
      open +
      (~('' + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) +
      close
    )
  }
}