@@ -3,6 +3,44 @@ const npmlog = require('npmlog')
3
3
const log = require('./log-shim.js')
4
4
const { explain } = require('./explain-eresolve.js')
5
5
6
+
const originalCustomInspect = Symbol('npm.display.original.util.inspect.custom')
7
+
8
+
// These are most assuredly not a mistake
9
+
// https://eslint.org/docs/latest/rules/no-control-regex
10
+
/* eslint-disable no-control-regex */
11
+
// \x00 through \x1f, \x7f through \x9f, not including \x09 \x0a \x0b \x0d
12
+
const hasC01 = /[\x00-\x08\x0c\x0e-\x1f\x7f-\x9f]/
13
+
// Allows everything up to '[38;5;255m' in 8 bit notation
14
+
const allowedSGR = /^\[[0-9;]{0,8}m/
15
+
// '[38;5;255m'.length
16
+
const sgrMaxLen = 10
17
+
18
+
// Strips all ANSI C0 and C1 control characters (except for SGR up to 8 bit)
19
+
function stripC01 (str) {
20
+
if (!hasC01.test(str)) {
21
+
return str
22
+
}
23
+
let result = ''
24
+
for (let i = 0; i < str.length; i++) {
25
+
const char = str[i]
26
+
const code = char.charCodeAt(0)
27
+
if (!hasC01.test(char)) {
28
+
// Most characters are in this set so continue early if we can
29
+
result = `${result}${char}`
30
+
} else if (code === 27 && allowedSGR.test(str.slice(i + 1, i + sgrMaxLen + 1))) {
31
+
// \x1b with allowed SGR
32
+
result = `${result}\x1b`
33
+
} else if (code <= 31) {
34
+
// escape all other C0 control characters besides \x7f
35
+
result = `${result}^${String.fromCharCode(code + 64)}`
36
+
} else {
37
+
// hasC01 ensures this is now a C1 control character or \x7f
38
+
result = `${result}^${String.fromCharCode(code - 64)}`
39
+
}
40
+
}
41
+
return result
42
+
}
43
+
6
44
class Display {
7
45
#chalk = null
8
46
@@ -12,6 +50,57 @@ class Display {
12
50
log.pause()
13
51
}
14
52
53
+
static clean (output) {
54
+
if (typeof output === 'string') {
55
+
// Strings are cleaned inline
56
+
return stripC01(output)
57
+
}
58
+
if (!output || typeof output !== 'object') {
59
+
// Numbers, booleans, null all end up here and don't need cleaning
60
+
return output
61
+
}
62
+
// output && typeof output === 'object'
63
+
// We can't use hasOwn et al for detecting the original but we can use it
64
+
// for detecting the properties we set via defineProperty
65
+
if (
66
+
output[inspect.custom] &&
67
+
(!Object.hasOwn(output, originalCustomInspect))
68
+
) {
69
+
// Save the old one if we didn't already do it.
70
+
Object.defineProperty(output, originalCustomInspect, {
71
+
value: output[inspect.custom],
72
+
writable: true,
73
+
})
74
+
}
75
+
if (!Object.hasOwn(output, originalCustomInspect)) {
76
+
// Put a dummy one in for when we run multiple times on the same object
77
+
Object.defineProperty(output, originalCustomInspect, {
78
+
value: function () {
79
+
return this
80
+
},
81
+
writable: true,
82
+
})
83
+
}
84
+
// Set the custom inspect to our own function
85
+
Object.defineProperty(output, inspect.custom, {
86
+
value: function () {
87
+
const toClean = this[originalCustomInspect]()
88
+
// Custom inspect can return things other than objects, check type again
89
+
if (typeof toClean === 'string') {
90
+
// Strings are cleaned inline
91
+
return stripC01(toClean)
92
+
}
93
+
if (!toClean || typeof toClean !== 'object') {
94
+
// Numbers, booleans, null all end up here and don't need cleaning
95
+
return toClean
96
+
}
97
+
return stripC01(inspect(toClean, { customInspect: false }))
98
+
},
99
+
writable: true,
100
+
})
101
+
return output
102
+
}
103
+
15
104
on () {
16
105
process.on('log', this.#logHandler)
17
106
}
@@ -103,7 +192,7 @@ class Display {
103
192
// Explicitly call these on npmlog and not log shim
104
193
// This is the final place we should call npmlog before removing it.
105
194
#npmlog (level, ...args) {
106
-
npmlog[level](...args)
195
+
npmlog[level](...args.map(Display.clean))
107
196
}
108
197
109
198
// Also (and this is a really inexcusable kludge), we patch the
@@ -112,8 +201,8 @@ class Display {
112
201
// highly abbreviated explanation of what's being overridden.
113
202
#eresolveWarn (level, heading, message, expl) {
114
203
if (level === 'warn' &&
115
-
heading === 'ERESOLVE' &&
116
-
expl && typeof expl === 'object'
204
+
heading === 'ERESOLVE' &&
205
+
expl && typeof expl === 'object'
117
206
) {
118
207
this.#npmlog(level, heading, message)
119
208
this.#npmlog(level, '', explain(expl, this.#chalk, 2))
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4