-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
js-tokens.ts
91 lines (77 loc) · 2.28 KB
/
js-tokens.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
import type { Token as JSToken } from 'js-tokens'
import jsTokens from 'js-tokens'
import type { StripLiteralOptions } from './types'
export function stripLiteralJsTokens(code: string, options?: StripLiteralOptions) {
const FILL = options?.fillChar ?? ' '
const FILL_COMMENT = ' '
let result = ''
const filter = options?.filter ?? (() => true)
const tokens: JSToken[] = []
// jsx: false is more correct when parsing html
for (const token of jsTokens(code, { jsx: false })) {
tokens.push(token)
if (token.type === 'SingleLineComment') {
result += FILL_COMMENT.repeat(token.value.length)
continue
}
if (token.type === 'MultiLineComment') {
result += token.value.replace(/[^\n]/g, FILL_COMMENT)
continue
}
if (token.type === 'StringLiteral') {
// js-token sees exotic vue prop value as an unclosed string literal
if (!token.closed) {
result += token.value
continue
}
const body = token.value.slice(1, -1)
if (filter(body)) {
result += token.value[0] + FILL.repeat(body.length) + token.value[token.value.length - 1]
continue
}
}
if (token.type === 'NoSubstitutionTemplate') {
const body = token.value.slice(1, -1)
if (filter(body)) {
result += `\`${body.replace(/[^\n]/g, FILL)}\``
continue
}
}
if (token.type === 'RegularExpressionLiteral') {
const body = token.value
if (filter(body)) {
result += body.replace(/\/(.*)\/(\w?)$/g, (_, $1, $2) => `/${FILL.repeat($1.length)}/${$2}`)
continue
}
}
// `start${
if (token.type === 'TemplateHead') {
const body = token.value.slice(1, -2)
if (filter(body)) {
result += `\`${body.replace(/[^\n]/g, FILL)}\${`
continue
}
}
// }end`
if (token.type === 'TemplateTail') {
const body = token.value.slice(0, -2)
if (filter(body)) {
result += `}${body.replace(/[^\n]/g, FILL)}\``
continue
}
}
// }middle${
if (token.type === 'TemplateMiddle') {
const body = token.value.slice(1, -2)
if (filter(body)) {
result += `}${body.replace(/[^\n]/g, FILL)}\${`
continue
}
}
result += token.value
}
return {
result,
tokens,
}
}