-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
browser.ts
151 lines (133 loc) · 3.57 KB
/
browser.ts
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// this cannot be located at source/brower.ts as otherwise it would become the browser entry
// Imports
import { Transform } from '../transform.js'
/** Mapping of ANSI color codes into a CSS style */
export interface Styles {
[key: string]: {
/** The ANSI color code used to start the style */
start: string
/** The ANSI color code used to end the style */
end: string
/** The CSS style value */
value: string
}
}
/** Configuration optons for the Caterpillar Browser Transform */
export interface BrowserOptions {
/** Use to override the default value of {@link Filter.color} */
color?: boolean
/** Use to override the default value of {@link Filter.console} */
output?: boolean
/** Use to override the default value of {@link Filter.styles} */
styles?: Styles
}
/**
* Convert human readable Caterpillar entries into browser compatible entries.
* @example
* ``` javascript
* import { Logger, Human, Browser } from 'caterpillar'
* const logger = new Logger()
* logger.pipe(new Human()).pipe(new Browser())
* logger.log('info', 'some', {data: 'oh yeah'}, 42)
* ```
*/
export class Browser extends Transform {
/** Whether or not we should use color. */
public color: boolean = true
/** Whether or not we should write to the browser console. */
public output: boolean = true
/** The objects that tell our browser transform how to convert terminal colours into console colours. */
public styles: Styles = {
red: {
start: '31',
end: '39',
value: 'color:red',
},
yellow: {
start: '33',
end: '39',
value: 'color:orange',
},
green: {
start: '32',
end: '39',
value: 'color:green',
},
bright: {
start: '1',
end: '22',
value: 'font-weight:bold',
},
dim: {
start: '2',
end: '22',
value: 'color:lightGray',
},
italic: {
start: '3',
end: '23',
value: 'font-style:italic',
},
underline: {
start: '4',
end: '24',
value: 'text-decoration:underline',
},
}
/** Create our instance and apply our configuraiton options. */
constructor(opts?: BrowserOptions) {
super()
// options
if (opts?.color != null) this.color = opts.color
if (opts?.output != null) this.output = opts.output
if (opts?.styles != null) this.styles = opts.styles
}
/**
* Convert a human readable Caterpillar entry into a format that browser consoles can understand.
* And if the `write` config property is `true` (it is by default), write the result to the browser console.
*/
format(message: string): string[] {
// Prepare
const { color, styles, output } = this
// Replace caterpillar-human formatted entry
/* eslint no-control-regex:0 */
const args: string[] = []
const result = message.replace(
/\u001b\[([0-9]+)m(.+?)\u001b\[([0-9]+)m/g,
function (match, start, content, end) {
// Check
if (color === false) return content
// Prepare
let matchedStyle, style
// Find the matcing style for this combination
for (const key in styles) {
if (styles.hasOwnProperty(key)) {
style = styles[key]
if (
String(style.start) === String(start) &&
String(style.end) === String(end)
) {
matchedStyle = style
break
}
}
}
// Check
if (!matchedStyle) return content
// Push the style
args.push(matchedStyle.value)
args.push(content)
args.push('color:default; font:default; text-decoration:default')
return '%c%s%c'
}
)
// Final format
const parts = [result.trim()].concat(args)
// Write
/* eslint no-console:0 */
if (output) console.log(...parts)
// Return
return parts
}
}
export default Browser