1 |
|
2 |
|
3 |
|
4 | import { Transform } from '../transform.js'
|
5 |
|
6 |
|
7 | export interface Styles {
|
8 | [key: string]: {
|
9 |
|
10 | start: string
|
11 |
|
12 | end: string
|
13 |
|
14 | value: string
|
15 | }
|
16 | }
|
17 |
|
18 |
|
19 | export interface BrowserOptions {
|
20 |
|
21 | color?: boolean
|
22 |
|
23 | output?: boolean
|
24 |
|
25 | styles?: Styles
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | export class Browser extends Transform {
|
39 |
|
40 | public color: boolean = true
|
41 |
|
42 |
|
43 | public output: boolean = true
|
44 |
|
45 |
|
46 | public styles: Styles = {
|
47 | red: {
|
48 | start: '31',
|
49 | end: '39',
|
50 | value: 'color:red',
|
51 | },
|
52 | yellow: {
|
53 | start: '33',
|
54 | end: '39',
|
55 | value: 'color:orange',
|
56 | },
|
57 | green: {
|
58 | start: '32',
|
59 | end: '39',
|
60 | value: 'color:green',
|
61 | },
|
62 | bright: {
|
63 | start: '1',
|
64 | end: '22',
|
65 | value: 'font-weight:bold',
|
66 | },
|
67 | dim: {
|
68 | start: '2',
|
69 | end: '22',
|
70 | value: 'color:lightGray',
|
71 | },
|
72 | italic: {
|
73 | start: '3',
|
74 | end: '23',
|
75 | value: 'font-style:italic',
|
76 | },
|
77 | underline: {
|
78 | start: '4',
|
79 | end: '24',
|
80 | value: 'text-decoration:underline',
|
81 | },
|
82 | }
|
83 |
|
84 |
|
85 | constructor(opts?: BrowserOptions) {
|
86 | super()
|
87 |
|
88 |
|
89 | if (opts?.color != null) this.color = opts.color
|
90 | if (opts?.output != null) this.output = opts.output
|
91 | if (opts?.styles != null) this.styles = opts.styles
|
92 | }
|
93 |
|
94 | |
95 |
|
96 |
|
97 |
|
98 | format(message: string): string[] {
|
99 |
|
100 | const { color, styles, output } = this
|
101 |
|
102 |
|
103 |
|
104 | const args: string[] = []
|
105 | const result = message.replace(
|
106 | /\u001b\[([0-9]+)m(.+?)\u001b\[([0-9]+)m/g,
|
107 | function (match, start, content, end) {
|
108 |
|
109 | if (color === false) return content
|
110 |
|
111 |
|
112 | let matchedStyle, style
|
113 |
|
114 |
|
115 | for (const key in styles) {
|
116 | if (styles.hasOwnProperty(key)) {
|
117 | style = styles[key]
|
118 | if (
|
119 | String(style.start) === String(start) &&
|
120 | String(style.end) === String(end)
|
121 | ) {
|
122 | matchedStyle = style
|
123 | break
|
124 | }
|
125 | }
|
126 | }
|
127 |
|
128 |
|
129 | if (!matchedStyle) return content
|
130 |
|
131 |
|
132 | args.push(matchedStyle.value)
|
133 | args.push(content)
|
134 | args.push('color:default; font:default; text-decoration:default')
|
135 | return '%c%s%c'
|
136 | }
|
137 | )
|
138 |
|
139 |
|
140 | const parts = [result.trim()].concat(args)
|
141 |
|
142 |
|
143 |
|
144 | if (output) console.log(...parts)
|
145 |
|
146 |
|
147 | return parts
|
148 | }
|
149 | }
|
150 |
|
151 | export default Browser
|