@jsenv/humanize 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -10
- package/dist/browser/jsenv_humanize_browser.js +96 -2
- package/dist/node/jsenv_humanize_node.js +1470 -1531
- package/package.json +3 -3
- package/src/.jsenv/jsenv_tests_output.txt +27 -30
- package/src/_tests/byte/file_size.test.js +2 -2
- package/src/_tests/byte/memory.test.js +11 -0
- package/src/_tests/js_value/array.test.js +14 -14
- package/src/_tests/js_value/biginit.test.js +10 -10
- package/src/_tests/js_value/boolean.test.js +12 -12
- package/src/_tests/js_value/date.test.js +4 -4
- package/src/_tests/js_value/error.test.js +8 -8
- package/src/_tests/js_value/function.test.js +12 -12
- package/src/_tests/js_value/instance.test.js +2 -2
- package/src/_tests/js_value/null.test.js +2 -2
- package/src/_tests/js_value/number.test.js +54 -54
- package/src/_tests/js_value/object.test.js +34 -34
- package/src/_tests/js_value/regexp.test.js +4 -4
- package/src/_tests/js_value/string.test.js +32 -32
- package/src/_tests/js_value/symbol.test.js +6 -6
- package/src/_tests/js_value/undefined.test.js +2 -2
- package/src/_tests/log/logger.test.mjs +14 -14
- package/src/_tests/log/spinner.test.mjs +6 -6
- package/src/_tests/percentage/percentage_distribution.test.mjs +2 -2
- package/src/_tests/time/decimals.test.js +40 -40
- package/src/_tests/time/duration.test.js +2 -2
- package/src/_tests/time/ellapsed.test.js +2 -2
- package/src/ansi/ansi_browser.js +3 -0
- package/src/ansi/ansi_node.js +16 -0
- package/src/ansi/ansi_runtime_agnostic.js +33 -0
- package/src/byte/byte.js +1 -1
- package/src/js_value/humanize.js +1 -1
- package/src/js_value/string.js +1 -1
- package/src/log/dynamic_log.js +6 -4
- package/src/log/spinner.js +1 -1
- package/src/log/task_log.js +1 -1
- package/src/main_browser.js +3 -5
- package/src/main_node.js +9 -13
- package/src/unicode/unicode_browser.js +7 -0
- package/src/unicode/unicode_node.js +8 -0
- package/src/unicode/unicode_runtime_agnostic.js +53 -0
- package/src/_tests/byte/memory_usage.test.js +0 -11
- package/src/log/ansi.js +0 -37
- package/src/log/unicode.js +0 -52
|
@@ -1,727 +1,997 @@
|
|
|
1
|
-
import stringWidth from "string-width";
|
|
2
1
|
import process$1 from "node:process";
|
|
3
2
|
import os from "node:os";
|
|
4
3
|
import tty from "node:tty";
|
|
4
|
+
import stringWidth from "string-width";
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const LOG_LEVEL_DEBUG = "debug";
|
|
9
|
-
|
|
10
|
-
const LOG_LEVEL_INFO = "info";
|
|
11
|
-
|
|
12
|
-
const LOG_LEVEL_WARN = "warn";
|
|
6
|
+
const createDetailedMessage = (message, details = {}) => {
|
|
7
|
+
let string = `${message}`;
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
Object.keys(details).forEach((key) => {
|
|
10
|
+
const value = details[key];
|
|
11
|
+
string += `
|
|
12
|
+
--- ${key} ---
|
|
13
|
+
${
|
|
14
|
+
Array.isArray(value)
|
|
15
|
+
? value.join(`
|
|
16
|
+
`)
|
|
17
|
+
: value
|
|
18
|
+
}`;
|
|
19
|
+
});
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
if (logLevel === LOG_LEVEL_DEBUG) {
|
|
18
|
-
return {
|
|
19
|
-
level: "debug",
|
|
20
|
-
levels: { debug: true, info: true, warn: true, error: true },
|
|
21
|
-
debug,
|
|
22
|
-
info,
|
|
23
|
-
warn,
|
|
24
|
-
error,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
if (logLevel === LOG_LEVEL_INFO) {
|
|
28
|
-
return {
|
|
29
|
-
level: "info",
|
|
30
|
-
levels: { debug: false, info: true, warn: true, error: true },
|
|
31
|
-
debug: debugDisabled,
|
|
32
|
-
info,
|
|
33
|
-
warn,
|
|
34
|
-
error,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
if (logLevel === LOG_LEVEL_WARN) {
|
|
38
|
-
return {
|
|
39
|
-
level: "warn",
|
|
40
|
-
levels: { debug: false, info: false, warn: true, error: true },
|
|
41
|
-
debug: debugDisabled,
|
|
42
|
-
info: infoDisabled,
|
|
43
|
-
warn,
|
|
44
|
-
error,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
if (logLevel === LOG_LEVEL_ERROR) {
|
|
48
|
-
return {
|
|
49
|
-
level: "error",
|
|
50
|
-
levels: { debug: false, info: false, warn: false, error: true },
|
|
51
|
-
debug: debugDisabled,
|
|
52
|
-
info: infoDisabled,
|
|
53
|
-
warn: warnDisabled,
|
|
54
|
-
error,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
if (logLevel === LOG_LEVEL_OFF) {
|
|
58
|
-
return {
|
|
59
|
-
level: "off",
|
|
60
|
-
levels: { debug: false, info: false, warn: false, error: false },
|
|
61
|
-
debug: debugDisabled,
|
|
62
|
-
info: infoDisabled,
|
|
63
|
-
warn: warnDisabled,
|
|
64
|
-
error: errorDisabled,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
throw new Error(`unexpected logLevel.
|
|
68
|
-
--- logLevel ---
|
|
69
|
-
${logLevel}
|
|
70
|
-
--- allowed log levels ---
|
|
71
|
-
${LOG_LEVEL_OFF}
|
|
72
|
-
${LOG_LEVEL_ERROR}
|
|
73
|
-
${LOG_LEVEL_WARN}
|
|
74
|
-
${LOG_LEVEL_INFO}
|
|
75
|
-
${LOG_LEVEL_DEBUG}`);
|
|
21
|
+
return string;
|
|
76
22
|
};
|
|
77
23
|
|
|
78
|
-
|
|
24
|
+
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
|
|
25
|
+
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
|
|
26
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
|
|
27
|
+
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
28
|
+
const position = argv.indexOf(prefix + flag);
|
|
29
|
+
const terminatorPosition = argv.indexOf('--');
|
|
30
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
31
|
+
}
|
|
79
32
|
|
|
80
|
-
const
|
|
33
|
+
const {env} = process$1;
|
|
81
34
|
|
|
82
|
-
|
|
35
|
+
let flagForceColor;
|
|
36
|
+
if (
|
|
37
|
+
hasFlag('no-color')
|
|
38
|
+
|| hasFlag('no-colors')
|
|
39
|
+
|| hasFlag('color=false')
|
|
40
|
+
|| hasFlag('color=never')
|
|
41
|
+
) {
|
|
42
|
+
flagForceColor = 0;
|
|
43
|
+
} else if (
|
|
44
|
+
hasFlag('color')
|
|
45
|
+
|| hasFlag('colors')
|
|
46
|
+
|| hasFlag('color=true')
|
|
47
|
+
|| hasFlag('color=always')
|
|
48
|
+
) {
|
|
49
|
+
flagForceColor = 1;
|
|
50
|
+
}
|
|
83
51
|
|
|
84
|
-
|
|
52
|
+
function envForceColor() {
|
|
53
|
+
if ('FORCE_COLOR' in env) {
|
|
54
|
+
if (env.FORCE_COLOR === 'true') {
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
85
57
|
|
|
86
|
-
|
|
58
|
+
if (env.FORCE_COLOR === 'false') {
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
87
61
|
|
|
88
|
-
|
|
62
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
89
65
|
|
|
90
|
-
|
|
66
|
+
function translateLevel(level) {
|
|
67
|
+
if (level === 0) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
91
70
|
|
|
92
|
-
|
|
71
|
+
return {
|
|
72
|
+
level,
|
|
73
|
+
hasBasic: true,
|
|
74
|
+
has256: level >= 2,
|
|
75
|
+
has16m: level >= 3,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
93
78
|
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
79
|
+
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
|
|
80
|
+
const noFlagForceColor = envForceColor();
|
|
81
|
+
if (noFlagForceColor !== undefined) {
|
|
82
|
+
flagForceColor = noFlagForceColor;
|
|
83
|
+
}
|
|
98
84
|
|
|
99
|
-
|
|
100
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
85
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
101
86
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
106
|
-
} : process$1.cwd;
|
|
87
|
+
if (forceColor === 0) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
107
90
|
|
|
108
|
-
|
|
91
|
+
if (sniffFlags) {
|
|
92
|
+
if (hasFlag('color=16m')
|
|
93
|
+
|| hasFlag('color=full')
|
|
94
|
+
|| hasFlag('color=truecolor')) {
|
|
95
|
+
return 3;
|
|
96
|
+
}
|
|
109
97
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
98
|
+
if (hasFlag('color=256')) {
|
|
99
|
+
return 2;
|
|
100
|
+
}
|
|
113
101
|
}
|
|
114
102
|
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
// Check for Azure DevOps pipelines.
|
|
104
|
+
// Has to be above the `!streamIsTTY` check.
|
|
105
|
+
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
|
106
|
+
return 1;
|
|
117
107
|
}
|
|
118
108
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
ansiEscapes.cursorMove = (x, y) => {
|
|
123
|
-
if (typeof x !== 'number') {
|
|
124
|
-
throw new TypeError('The `x` argument is required');
|
|
109
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
110
|
+
return 0;
|
|
125
111
|
}
|
|
126
112
|
|
|
127
|
-
|
|
113
|
+
const min = forceColor || 0;
|
|
128
114
|
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
} else if (x > 0) {
|
|
132
|
-
returnValue += ESC + x + 'C';
|
|
115
|
+
if (env.TERM === 'dumb') {
|
|
116
|
+
return min;
|
|
133
117
|
}
|
|
134
118
|
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
119
|
+
if (process$1.platform === 'win32') {
|
|
120
|
+
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
121
|
+
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
122
|
+
const osRelease = os.release().split('.');
|
|
123
|
+
if (
|
|
124
|
+
Number(osRelease[0]) >= 10
|
|
125
|
+
&& Number(osRelease[2]) >= 10_586
|
|
126
|
+
) {
|
|
127
|
+
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return 1;
|
|
139
131
|
}
|
|
140
132
|
|
|
141
|
-
|
|
142
|
-
|
|
133
|
+
if ('CI' in env) {
|
|
134
|
+
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
|
|
135
|
+
return 3;
|
|
136
|
+
}
|
|
143
137
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
|
|
148
|
-
|
|
149
|
-
ansiEscapes.cursorLeft = ESC + 'G';
|
|
150
|
-
ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
|
|
151
|
-
ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
|
|
152
|
-
ansiEscapes.cursorGetPosition = ESC + '6n';
|
|
153
|
-
ansiEscapes.cursorNextLine = ESC + 'E';
|
|
154
|
-
ansiEscapes.cursorPrevLine = ESC + 'F';
|
|
155
|
-
ansiEscapes.cursorHide = ESC + '?25l';
|
|
156
|
-
ansiEscapes.cursorShow = ESC + '?25h';
|
|
157
|
-
|
|
158
|
-
ansiEscapes.eraseLines = count => {
|
|
159
|
-
let clear = '';
|
|
138
|
+
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
160
141
|
|
|
161
|
-
|
|
162
|
-
clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : '');
|
|
142
|
+
return min;
|
|
163
143
|
}
|
|
164
144
|
|
|
165
|
-
if (
|
|
166
|
-
|
|
145
|
+
if ('TEAMCITY_VERSION' in env) {
|
|
146
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
167
147
|
}
|
|
168
148
|
|
|
169
|
-
|
|
170
|
-
|
|
149
|
+
if (env.COLORTERM === 'truecolor') {
|
|
150
|
+
return 3;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (env.TERM === 'xterm-kitty') {
|
|
154
|
+
return 3;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if ('TERM_PROGRAM' in env) {
|
|
158
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
171
159
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
ansiEscapes.eraseUp = ESC + '1J';
|
|
177
|
-
ansiEscapes.eraseScreen = ESC + '2J';
|
|
178
|
-
ansiEscapes.scrollUp = ESC + 'S';
|
|
179
|
-
ansiEscapes.scrollDown = ESC + 'T';
|
|
160
|
+
switch (env.TERM_PROGRAM) {
|
|
161
|
+
case 'iTerm.app': {
|
|
162
|
+
return version >= 3 ? 3 : 2;
|
|
163
|
+
}
|
|
180
164
|
|
|
181
|
-
|
|
165
|
+
case 'Apple_Terminal': {
|
|
166
|
+
return 2;
|
|
167
|
+
}
|
|
168
|
+
// No default
|
|
169
|
+
}
|
|
170
|
+
}
|
|
182
171
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
186
|
-
// 2. Erases the whole screen including scrollback buffer
|
|
187
|
-
// 3. Moves cursor to the top-left position
|
|
188
|
-
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
189
|
-
: `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
|
|
190
|
-
|
|
191
|
-
ansiEscapes.enterAlternativeScreen = ESC + '?1049h';
|
|
192
|
-
ansiEscapes.exitAlternativeScreen = ESC + '?1049l';
|
|
193
|
-
|
|
194
|
-
ansiEscapes.beep = BEL;
|
|
195
|
-
|
|
196
|
-
ansiEscapes.link = (text, url) => [
|
|
197
|
-
OSC,
|
|
198
|
-
'8',
|
|
199
|
-
SEP,
|
|
200
|
-
SEP,
|
|
201
|
-
url,
|
|
202
|
-
BEL,
|
|
203
|
-
text,
|
|
204
|
-
OSC,
|
|
205
|
-
'8',
|
|
206
|
-
SEP,
|
|
207
|
-
SEP,
|
|
208
|
-
BEL,
|
|
209
|
-
].join('');
|
|
210
|
-
|
|
211
|
-
ansiEscapes.image = (buffer, options = {}) => {
|
|
212
|
-
let returnValue = `${OSC}1337;File=inline=1`;
|
|
213
|
-
|
|
214
|
-
if (options.width) {
|
|
215
|
-
returnValue += `;width=${options.width}`;
|
|
172
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
173
|
+
return 2;
|
|
216
174
|
}
|
|
217
175
|
|
|
218
|
-
if (
|
|
219
|
-
|
|
176
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
177
|
+
return 1;
|
|
220
178
|
}
|
|
221
179
|
|
|
222
|
-
if (
|
|
223
|
-
|
|
180
|
+
if ('COLORTERM' in env) {
|
|
181
|
+
return 1;
|
|
224
182
|
}
|
|
225
183
|
|
|
226
|
-
return
|
|
227
|
-
}
|
|
184
|
+
return min;
|
|
185
|
+
}
|
|
228
186
|
|
|
229
|
-
|
|
230
|
-
|
|
187
|
+
function createSupportsColor(stream, options = {}) {
|
|
188
|
+
const level = _supportsColor(stream, {
|
|
189
|
+
streamIsTTY: stream && stream.isTTY,
|
|
190
|
+
...options,
|
|
191
|
+
});
|
|
231
192
|
|
|
232
|
-
|
|
233
|
-
|
|
193
|
+
return translateLevel(level);
|
|
194
|
+
}
|
|
234
195
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
196
|
+
({
|
|
197
|
+
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
|
198
|
+
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
|
199
|
+
});
|
|
240
200
|
|
|
241
|
-
|
|
201
|
+
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
202
|
+
// https://stackoverflow.com/a/75985833/2634179
|
|
203
|
+
const RESET = "\x1b[0m";
|
|
242
204
|
|
|
243
|
-
|
|
205
|
+
const createAnsi = ({ supported }) => {
|
|
206
|
+
const ANSI = {
|
|
207
|
+
supported,
|
|
208
|
+
|
|
209
|
+
RED: "\x1b[31m",
|
|
210
|
+
GREEN: "\x1b[32m",
|
|
211
|
+
YELLOW: "\x1b[33m",
|
|
212
|
+
BLUE: "\x1b[34m",
|
|
213
|
+
MAGENTA: "\x1b[35m",
|
|
214
|
+
CYAN: "\x1b[36m",
|
|
215
|
+
GREY: "\x1b[90m",
|
|
216
|
+
color: (text, ANSI_COLOR) => {
|
|
217
|
+
return ANSI.supported && ANSI_COLOR
|
|
218
|
+
? `${ANSI_COLOR}${text}${RESET}`
|
|
219
|
+
: text;
|
|
220
|
+
},
|
|
244
221
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
222
|
+
BOLD: "\x1b[1m",
|
|
223
|
+
UNDERLINE: "\x1b[4m",
|
|
224
|
+
STRIKE: "\x1b[9m",
|
|
225
|
+
effect: (text, ANSI_EFFECT) => {
|
|
226
|
+
return ANSI.supported && ANSI_EFFECT
|
|
227
|
+
? `${ANSI_EFFECT}${text}${RESET}`
|
|
228
|
+
: text;
|
|
229
|
+
},
|
|
230
|
+
};
|
|
254
231
|
|
|
255
|
-
|
|
256
|
-
},
|
|
232
|
+
return ANSI;
|
|
257
233
|
};
|
|
258
234
|
|
|
259
|
-
|
|
260
|
-
* see also https://github.com/vadimdemedes/ink
|
|
261
|
-
*/
|
|
235
|
+
const processSupportsBasicColor = createSupportsColor(process.stdout).hasBasic;
|
|
262
236
|
|
|
237
|
+
const ANSI = createAnsi({
|
|
238
|
+
supported:
|
|
239
|
+
processSupportsBasicColor ||
|
|
240
|
+
// GitHub workflow does support ANSI but "supports-color" returns false
|
|
241
|
+
// because stream.isTTY returns false, see https://github.com/actions/runner/issues/241
|
|
242
|
+
(process.env.GITHUB_WORKFLOW &&
|
|
243
|
+
// Check on FORCE_COLOR is to ensure it is prio over GitHub workflow check
|
|
244
|
+
// in unit test we use process.env.FORCE_COLOR = 'false' to fake
|
|
245
|
+
// that colors are not supported. Let it have priority
|
|
246
|
+
process.env.FORCE_COLOR !== "false"),
|
|
247
|
+
});
|
|
263
248
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
onWriteFromOutside = () => {},
|
|
269
|
-
} = {}) => {
|
|
270
|
-
const { columns = 80, rows = 24 } = stream;
|
|
271
|
-
const dynamicLog = {
|
|
272
|
-
destroyed: false,
|
|
273
|
-
onVerticalOverflow,
|
|
274
|
-
onWriteFromOutside,
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
let lastOutput = "";
|
|
278
|
-
let lastOutputFromOutside = "";
|
|
279
|
-
let clearAttemptResult;
|
|
280
|
-
let writing = false;
|
|
281
|
-
|
|
282
|
-
const getErasePreviousOutput = () => {
|
|
283
|
-
// nothing to clear
|
|
284
|
-
if (!lastOutput) {
|
|
285
|
-
return "";
|
|
286
|
-
}
|
|
287
|
-
if (clearAttemptResult !== undefined) {
|
|
288
|
-
return "";
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const logLines = lastOutput.split(/\r\n|\r|\n/);
|
|
292
|
-
let visualLineCount = 0;
|
|
293
|
-
for (const logLine of logLines) {
|
|
294
|
-
const width = stringWidth(logLine);
|
|
295
|
-
if (width === 0) {
|
|
296
|
-
visualLineCount++;
|
|
297
|
-
} else {
|
|
298
|
-
visualLineCount += Math.ceil(width / columns);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
249
|
+
function isUnicodeSupported() {
|
|
250
|
+
if (process$1.platform !== 'win32') {
|
|
251
|
+
return process$1.env.TERM !== 'linux'; // Linux console (kernel)
|
|
252
|
+
}
|
|
301
253
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
// better keep the log untouched
|
|
312
|
-
clearAttemptResult = false;
|
|
313
|
-
dynamicLog.onVerticalOverflow();
|
|
314
|
-
return "";
|
|
315
|
-
}
|
|
254
|
+
return Boolean(process$1.env.WT_SESSION) // Windows Terminal
|
|
255
|
+
|| Boolean(process$1.env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
|
|
256
|
+
|| process$1.env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
|
|
257
|
+
|| process$1.env.TERM_PROGRAM === 'Terminus-Sublime'
|
|
258
|
+
|| process$1.env.TERM_PROGRAM === 'vscode'
|
|
259
|
+
|| process$1.env.TERM === 'xterm-256color'
|
|
260
|
+
|| process$1.env.TERM === 'alacritty'
|
|
261
|
+
|| process$1.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
|
|
262
|
+
}
|
|
316
263
|
|
|
317
|
-
|
|
318
|
-
return ansiEscapes.eraseLines(visualLineCount);
|
|
319
|
-
};
|
|
264
|
+
// see also https://github.com/sindresorhus/figures
|
|
320
265
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
266
|
+
const createUnicode = ({ supported, ANSI }) => {
|
|
267
|
+
const UNICODE = {
|
|
268
|
+
supported,
|
|
269
|
+
get COMMAND_RAW() {
|
|
270
|
+
return UNICODE.supported ? `❯` : `>`;
|
|
271
|
+
},
|
|
272
|
+
get OK_RAW() {
|
|
273
|
+
return UNICODE.supported ? `✔` : `√`;
|
|
274
|
+
},
|
|
275
|
+
get FAILURE_RAW() {
|
|
276
|
+
return UNICODE.supported ? `✖` : `×`;
|
|
277
|
+
},
|
|
278
|
+
get DEBUG_RAW() {
|
|
279
|
+
return UNICODE.supported ? `◆` : `♦`;
|
|
280
|
+
},
|
|
281
|
+
get INFO_RAW() {
|
|
282
|
+
return UNICODE.supported ? `ℹ` : `i`;
|
|
283
|
+
},
|
|
284
|
+
get WARNING_RAW() {
|
|
285
|
+
return UNICODE.supported ? `⚠` : `‼`;
|
|
286
|
+
},
|
|
287
|
+
get CIRCLE_CROSS_RAW() {
|
|
288
|
+
return UNICODE.supported ? `ⓧ` : `(×)`;
|
|
289
|
+
},
|
|
290
|
+
get COMMAND() {
|
|
291
|
+
return ANSI.color(UNICODE.COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
|
|
292
|
+
},
|
|
293
|
+
get OK() {
|
|
294
|
+
return ANSI.color(UNICODE.OK_RAW, ANSI.GREEN);
|
|
295
|
+
},
|
|
296
|
+
get FAILURE() {
|
|
297
|
+
return ANSI.color(UNICODE.FAILURE_RAW, ANSI.RED);
|
|
298
|
+
},
|
|
299
|
+
get DEBUG() {
|
|
300
|
+
return ANSI.color(UNICODE.DEBUG_RAW, ANSI.GREY);
|
|
301
|
+
},
|
|
302
|
+
get INFO() {
|
|
303
|
+
return ANSI.color(UNICODE.INFO_RAW, ANSI.BLUE);
|
|
304
|
+
},
|
|
305
|
+
get WARNING() {
|
|
306
|
+
return ANSI.color(UNICODE.WARNING_RAW, ANSI.YELLOW);
|
|
307
|
+
},
|
|
308
|
+
get CIRCLE_CROSS() {
|
|
309
|
+
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
310
|
+
},
|
|
311
|
+
get ELLIPSIS() {
|
|
312
|
+
return UNICODE.supported ? `…` : `...`;
|
|
313
|
+
},
|
|
345
314
|
};
|
|
315
|
+
return UNICODE;
|
|
316
|
+
};
|
|
346
317
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
// During step 2. we expect a "write from outside" so we uninstall
|
|
352
|
-
// the stream spy during function call
|
|
353
|
-
const currentOutput = lastOutput;
|
|
354
|
-
update("");
|
|
318
|
+
const UNICODE = createUnicode({
|
|
319
|
+
supported: isUnicodeSupported(),
|
|
320
|
+
ANSI,
|
|
321
|
+
});
|
|
355
322
|
|
|
356
|
-
|
|
357
|
-
callback();
|
|
358
|
-
writing = false;
|
|
323
|
+
const inspectBoolean = (value) => value.toString();
|
|
359
324
|
|
|
360
|
-
|
|
361
|
-
};
|
|
325
|
+
const inspectNull = () => "null";
|
|
362
326
|
|
|
363
|
-
|
|
364
|
-
if (!lastOutput) {
|
|
365
|
-
// we don't care if the log never wrote anything
|
|
366
|
-
// or if last update() wrote an empty string
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
if (writing) {
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
lastOutputFromOutside = value;
|
|
373
|
-
dynamicLog.onWriteFromOutside(value);
|
|
374
|
-
};
|
|
327
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/rules/numeric-separators-style.js
|
|
375
328
|
|
|
376
|
-
|
|
377
|
-
if (
|
|
378
|
-
|
|
379
|
-
process.stdout,
|
|
380
|
-
writeFromOutsideEffect,
|
|
381
|
-
);
|
|
382
|
-
const removeStderrSpy = spyStreamOutput(
|
|
383
|
-
process.stderr,
|
|
384
|
-
writeFromOutsideEffect,
|
|
385
|
-
);
|
|
386
|
-
removeStreamSpy = () => {
|
|
387
|
-
removeStdoutSpy();
|
|
388
|
-
removeStderrSpy();
|
|
389
|
-
};
|
|
390
|
-
} else {
|
|
391
|
-
removeStreamSpy = spyStreamOutput(stream, writeFromOutsideEffect);
|
|
329
|
+
const inspectNumber = (value, { numericSeparator }) => {
|
|
330
|
+
if (isNegativeZero(value)) {
|
|
331
|
+
return "-0";
|
|
392
332
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
333
|
+
// isNaN
|
|
334
|
+
// eslint-disable-next-line no-self-compare
|
|
335
|
+
if (value !== value) {
|
|
336
|
+
return "NaN";
|
|
337
|
+
}
|
|
338
|
+
if (value === Infinity) {
|
|
339
|
+
return "Infinity";
|
|
340
|
+
}
|
|
341
|
+
if (value === -Infinity) {
|
|
342
|
+
return "-Infinity";
|
|
343
|
+
}
|
|
344
|
+
const numberString = String(value);
|
|
345
|
+
if (!numericSeparator) {
|
|
346
|
+
return numberString;
|
|
347
|
+
}
|
|
348
|
+
const {
|
|
349
|
+
number,
|
|
350
|
+
mark = "",
|
|
351
|
+
sign = "",
|
|
352
|
+
power = "",
|
|
353
|
+
} = numberString.match(
|
|
354
|
+
/^(?<number>.*?)(?:(?<mark>e)(?<sign>[+-])?(?<power>\d+))?$/i,
|
|
355
|
+
).groups;
|
|
356
|
+
const numberWithSeparators = formatNumber(number);
|
|
357
|
+
const powerWithSeparators = addSeparator(power, {
|
|
358
|
+
minimumDigits: 5,
|
|
359
|
+
groupLength: 3,
|
|
409
360
|
});
|
|
410
|
-
return
|
|
361
|
+
return `${numberWithSeparators}${mark}${sign}${powerWithSeparators}`;
|
|
411
362
|
};
|
|
412
363
|
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
364
|
+
// Use this and instead of Object.is(value, -0)
|
|
365
|
+
// because in some corner cases firefox returns false
|
|
366
|
+
// for Object.is(-0, -0)
|
|
367
|
+
const isNegativeZero = (value) => {
|
|
368
|
+
return value === 0 && 1 / value === -Infinity;
|
|
369
|
+
};
|
|
419
370
|
|
|
420
|
-
|
|
421
|
-
|
|
371
|
+
const formatNumber = (numberString) => {
|
|
372
|
+
const parts = numberString.split(".");
|
|
373
|
+
const [integer, fractional] = parts;
|
|
422
374
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
375
|
+
if (parts.length === 2) {
|
|
376
|
+
const integerWithSeparators = addSeparator(integer, {
|
|
377
|
+
minimumDigits: 5,
|
|
378
|
+
groupLength: 3,
|
|
379
|
+
});
|
|
380
|
+
return `${integerWithSeparators}.${fractional}`;
|
|
381
|
+
}
|
|
428
382
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
installed = false;
|
|
435
|
-
};
|
|
383
|
+
return addSeparator(integer, {
|
|
384
|
+
minimumDigits: 5,
|
|
385
|
+
groupLength: 3,
|
|
386
|
+
});
|
|
387
|
+
};
|
|
436
388
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
return
|
|
440
|
-
|
|
389
|
+
const addSeparator = (numberString, { minimumDigits, groupLength }) => {
|
|
390
|
+
if (numberString[0] === "-") {
|
|
391
|
+
return `-${groupDigits(numberString.slice(1), {
|
|
392
|
+
minimumDigits,
|
|
393
|
+
groupLength,
|
|
394
|
+
})}`;
|
|
395
|
+
}
|
|
396
|
+
return groupDigits(numberString, { minimumDigits, groupLength });
|
|
441
397
|
};
|
|
442
398
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const terminatorPosition = argv.indexOf('--');
|
|
449
|
-
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const {env} = process$1;
|
|
399
|
+
const groupDigits = (digits, { minimumDigits, groupLength }) => {
|
|
400
|
+
const digitCount = digits.length;
|
|
401
|
+
if (digitCount < minimumDigits) {
|
|
402
|
+
return digits;
|
|
403
|
+
}
|
|
453
404
|
|
|
454
|
-
let
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
hasFlag('color')
|
|
464
|
-
|| hasFlag('colors')
|
|
465
|
-
|| hasFlag('color=true')
|
|
466
|
-
|| hasFlag('color=always')
|
|
467
|
-
) {
|
|
468
|
-
flagForceColor = 1;
|
|
469
|
-
}
|
|
405
|
+
let digitsWithSeparator = digits.slice(-groupLength);
|
|
406
|
+
let remainingDigits = digits.slice(0, -groupLength);
|
|
407
|
+
while (remainingDigits.length) {
|
|
408
|
+
const group = remainingDigits.slice(-groupLength);
|
|
409
|
+
remainingDigits = remainingDigits.slice(0, -groupLength);
|
|
410
|
+
digitsWithSeparator = `${group}_${digitsWithSeparator}`;
|
|
411
|
+
}
|
|
412
|
+
return digitsWithSeparator;
|
|
413
|
+
};
|
|
470
414
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
415
|
+
// const addSeparatorFromLeft = (value, { minimumDigits, groupLength }) => {
|
|
416
|
+
// const { length } = value;
|
|
417
|
+
// if (length < minimumDigits) {
|
|
418
|
+
// return value;
|
|
419
|
+
// }
|
|
476
420
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
421
|
+
// const parts = [];
|
|
422
|
+
// for (let start = 0; start < length; start += groupLength) {
|
|
423
|
+
// const end = Math.min(start + groupLength, length);
|
|
424
|
+
// parts.push(value.slice(start, end));
|
|
425
|
+
// }
|
|
426
|
+
// return parts.join("_");
|
|
427
|
+
// };
|
|
480
428
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
429
|
+
const DOUBLE_QUOTE = `"`;
|
|
430
|
+
const SINGLE_QUOTE = `'`;
|
|
431
|
+
const BACKTICK = "`";
|
|
484
432
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
433
|
+
const inspectString = (
|
|
434
|
+
value,
|
|
435
|
+
{
|
|
436
|
+
quote = "auto",
|
|
437
|
+
canUseTemplateString = false,
|
|
438
|
+
preserveLineBreaks = false,
|
|
439
|
+
quoteDefault = DOUBLE_QUOTE,
|
|
440
|
+
} = {},
|
|
441
|
+
) => {
|
|
442
|
+
quote =
|
|
443
|
+
quote === "auto"
|
|
444
|
+
? determineQuote(value, { canUseTemplateString, quoteDefault })
|
|
445
|
+
: quote;
|
|
446
|
+
if (quote === BACKTICK) {
|
|
447
|
+
return `\`${escapeTemplateStringSpecialCharacters(value)}\``;
|
|
448
|
+
}
|
|
449
|
+
return surroundStringWith(value, { quote, preserveLineBreaks });
|
|
450
|
+
};
|
|
489
451
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
452
|
+
// https://github.com/mgenware/string-to-template-literal/blob/main/src/main.ts#L1
|
|
453
|
+
const escapeTemplateStringSpecialCharacters = (string) => {
|
|
454
|
+
string = String(string);
|
|
455
|
+
let i = 0;
|
|
456
|
+
let escapedString = "";
|
|
457
|
+
while (i < string.length) {
|
|
458
|
+
const char = string[i];
|
|
459
|
+
i++;
|
|
460
|
+
escapedString += isTemplateStringSpecialChar(char) ? `\\${char}` : char;
|
|
461
|
+
}
|
|
462
|
+
return escapedString;
|
|
463
|
+
};
|
|
497
464
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
flagForceColor = noFlagForceColor;
|
|
502
|
-
}
|
|
465
|
+
const isTemplateStringSpecialChar = (char) =>
|
|
466
|
+
templateStringSpecialChars.indexOf(char) > -1;
|
|
467
|
+
const templateStringSpecialChars = ["\\", "`", "$"];
|
|
503
468
|
|
|
504
|
-
|
|
469
|
+
const determineQuote = (
|
|
470
|
+
string,
|
|
471
|
+
{ canUseTemplateString, quoteDefault = DOUBLE_QUOTE } = {},
|
|
472
|
+
) => {
|
|
473
|
+
const containsDoubleQuote = string.includes(DOUBLE_QUOTE);
|
|
474
|
+
if (!containsDoubleQuote) {
|
|
475
|
+
return DOUBLE_QUOTE;
|
|
476
|
+
}
|
|
477
|
+
const containsSimpleQuote = string.includes(SINGLE_QUOTE);
|
|
478
|
+
if (!containsSimpleQuote) {
|
|
479
|
+
return SINGLE_QUOTE;
|
|
480
|
+
}
|
|
481
|
+
if (canUseTemplateString) {
|
|
482
|
+
const containsBackTick = string.includes(BACKTICK);
|
|
483
|
+
if (!containsBackTick) {
|
|
484
|
+
return BACKTICK;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const doubleQuoteCount = string.split(DOUBLE_QUOTE).length - 1;
|
|
488
|
+
const singleQuoteCount = string.split(SINGLE_QUOTE).length - 1;
|
|
489
|
+
if (singleQuoteCount > doubleQuoteCount) {
|
|
490
|
+
return DOUBLE_QUOTE;
|
|
491
|
+
}
|
|
492
|
+
if (doubleQuoteCount > singleQuoteCount) {
|
|
493
|
+
return SINGLE_QUOTE;
|
|
494
|
+
}
|
|
495
|
+
return quoteDefault;
|
|
496
|
+
};
|
|
505
497
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
498
|
+
const inspectChar = (char, { quote, preserveLineBreaks }) => {
|
|
499
|
+
const point = char.charCodeAt(0);
|
|
500
|
+
if (preserveLineBreaks && (char === "\n" || char === "\r")) {
|
|
501
|
+
return char;
|
|
502
|
+
}
|
|
503
|
+
if (
|
|
504
|
+
char === quote ||
|
|
505
|
+
point === 92 ||
|
|
506
|
+
point < 32 ||
|
|
507
|
+
(point > 126 && point < 160) ||
|
|
508
|
+
// line separators
|
|
509
|
+
point === 8232 ||
|
|
510
|
+
point === 8233
|
|
511
|
+
) {
|
|
512
|
+
const replacement =
|
|
513
|
+
char === quote
|
|
514
|
+
? `\\${quote}`
|
|
515
|
+
: point === 8232
|
|
516
|
+
? "\\u2028"
|
|
517
|
+
: point === 8233
|
|
518
|
+
? "\\u2029"
|
|
519
|
+
: meta[point];
|
|
520
|
+
return replacement;
|
|
521
|
+
}
|
|
522
|
+
return char;
|
|
523
|
+
};
|
|
509
524
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
525
|
+
// https://github.com/jsenv/jsenv-uneval/blob/6c97ef9d8f2e9425a66f2c88347e0a118d427f3a/src/internal/escapeString.js#L3
|
|
526
|
+
// https://github.com/jsenv/jsenv-inspect/blob/bb11de3adf262b68f71ed82b0a37d4528dd42229/src/internal/string.js#L3
|
|
527
|
+
// https://github.com/joliss/js-string-escape/blob/master/index.js
|
|
528
|
+
// http://javascript.crockford.com/remedial.html
|
|
529
|
+
const surroundStringWith = (string, { quote, preserveLineBreaks }) => {
|
|
530
|
+
let result = "";
|
|
531
|
+
let last = 0;
|
|
532
|
+
const lastIndex = string.length;
|
|
533
|
+
let i = 0;
|
|
534
|
+
while (i < lastIndex) {
|
|
535
|
+
const char = string[i];
|
|
536
|
+
const replacement = inspectChar(char, { quote, preserveLineBreaks });
|
|
537
|
+
if (char !== replacement) {
|
|
538
|
+
if (last === i) {
|
|
539
|
+
result += replacement;
|
|
540
|
+
} else {
|
|
541
|
+
result += `${string.slice(last, i)}${replacement}`;
|
|
542
|
+
}
|
|
543
|
+
last = i + 1;
|
|
544
|
+
}
|
|
545
|
+
i++;
|
|
546
|
+
}
|
|
547
|
+
if (last !== lastIndex) {
|
|
548
|
+
result += string.slice(last);
|
|
549
|
+
}
|
|
550
|
+
return `${quote}${result}${quote}`;
|
|
551
|
+
};
|
|
516
552
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
553
|
+
// prettier-ignore
|
|
554
|
+
const meta = [
|
|
555
|
+
'\\x00', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\x07', // x07
|
|
556
|
+
'\\b', '\\t', '\\n', '\\x0B', '\\f', '\\r', '\\x0E', '\\x0F', // x0F
|
|
557
|
+
'\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', // x17
|
|
558
|
+
'\\x18', '\\x19', '\\x1A', '\\x1B', '\\x1C', '\\x1D', '\\x1E', '\\x1F', // x1F
|
|
559
|
+
'', '', '', '', '', '', '', "\\'", '', '', '', '', '', '', '', '', // x2F
|
|
560
|
+
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', // x3F
|
|
561
|
+
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', // x4F
|
|
562
|
+
'', '', '', '', '', '', '', '', '', '', '', '', '\\\\', '', '', '', // x5F
|
|
563
|
+
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', // x6F
|
|
564
|
+
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\\x7F', // x7F
|
|
565
|
+
'\\x80', '\\x81', '\\x82', '\\x83', '\\x84', '\\x85', '\\x86', '\\x87', // x87
|
|
566
|
+
'\\x88', '\\x89', '\\x8A', '\\x8B', '\\x8C', '\\x8D', '\\x8E', '\\x8F', // x8F
|
|
567
|
+
'\\x90', '\\x91', '\\x92', '\\x93', '\\x94', '\\x95', '\\x96', '\\x97', // x97
|
|
568
|
+
'\\x98', '\\x99', '\\x9A', '\\x9B', '\\x9C', '\\x9D', '\\x9E', '\\x9F', // x9F
|
|
569
|
+
];
|
|
521
570
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
571
|
+
const inspectSymbol = (value, { nestedHumanize, parenthesis }) => {
|
|
572
|
+
const symbolDescription = symbolToDescription(value);
|
|
573
|
+
const symbolDescriptionSource = symbolDescription
|
|
574
|
+
? nestedHumanize(symbolDescription)
|
|
575
|
+
: "";
|
|
576
|
+
const symbolSource = `Symbol(${symbolDescriptionSource})`;
|
|
527
577
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
578
|
+
if (parenthesis) return `${symbolSource}`;
|
|
579
|
+
return symbolSource;
|
|
580
|
+
};
|
|
531
581
|
|
|
532
|
-
|
|
582
|
+
const symbolToDescription =
|
|
583
|
+
"description" in Symbol.prototype
|
|
584
|
+
? (symbol) => symbol.description
|
|
585
|
+
: (symbol) => {
|
|
586
|
+
const toStringResult = symbol.toString();
|
|
587
|
+
const openingParenthesisIndex = toStringResult.indexOf("(");
|
|
588
|
+
const closingParenthesisIndex = toStringResult.indexOf(")");
|
|
589
|
+
const symbolDescription = toStringResult.slice(
|
|
590
|
+
openingParenthesisIndex + 1,
|
|
591
|
+
closingParenthesisIndex,
|
|
592
|
+
);
|
|
593
|
+
return symbolDescription;
|
|
594
|
+
};
|
|
533
595
|
|
|
534
|
-
|
|
535
|
-
return min;
|
|
536
|
-
}
|
|
596
|
+
const inspectUndefined = () => "undefined";
|
|
537
597
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const osRelease = os.release().split('.');
|
|
542
|
-
if (
|
|
543
|
-
Number(osRelease[0]) >= 10
|
|
544
|
-
&& Number(osRelease[2]) >= 10_586
|
|
545
|
-
) {
|
|
546
|
-
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
return 1;
|
|
550
|
-
}
|
|
598
|
+
const inspectBigInt = (value) => {
|
|
599
|
+
return `${value}n`;
|
|
600
|
+
};
|
|
551
601
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
602
|
+
const preNewLineAndIndentation = (
|
|
603
|
+
value,
|
|
604
|
+
{ depth, indentUsingTab, indentSize },
|
|
605
|
+
) => {
|
|
606
|
+
return `${newLineAndIndent({
|
|
607
|
+
count: depth + 1,
|
|
608
|
+
useTabs: indentUsingTab,
|
|
609
|
+
size: indentSize,
|
|
610
|
+
})}${value}`;
|
|
611
|
+
};
|
|
556
612
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
613
|
+
const postNewLineAndIndentation = ({ depth, indentUsingTab, indentSize }) => {
|
|
614
|
+
return newLineAndIndent({
|
|
615
|
+
count: depth,
|
|
616
|
+
useTabs: indentUsingTab,
|
|
617
|
+
size: indentSize,
|
|
618
|
+
});
|
|
619
|
+
};
|
|
560
620
|
|
|
561
|
-
|
|
562
|
-
|
|
621
|
+
const newLineAndIndent = ({ count, useTabs, size }) => {
|
|
622
|
+
if (useTabs) {
|
|
623
|
+
// eslint-disable-next-line prefer-template
|
|
624
|
+
return "\n" + "\t".repeat(count);
|
|
625
|
+
}
|
|
626
|
+
// eslint-disable-next-line prefer-template
|
|
627
|
+
return "\n" + " ".repeat(count * size);
|
|
628
|
+
};
|
|
563
629
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
630
|
+
const wrapNewLineAndIndentation = (
|
|
631
|
+
value,
|
|
632
|
+
{ depth, indentUsingTab, indentSize },
|
|
633
|
+
) => {
|
|
634
|
+
return `${preNewLineAndIndentation(value, {
|
|
635
|
+
depth,
|
|
636
|
+
indentUsingTab,
|
|
637
|
+
indentSize,
|
|
638
|
+
})}${postNewLineAndIndentation({ depth, indentUsingTab, indentSize })}`;
|
|
639
|
+
};
|
|
567
640
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
641
|
+
const inspectConstructor = (value, { parenthesis, useNew }) => {
|
|
642
|
+
let formattedString = value;
|
|
643
|
+
if (parenthesis) {
|
|
644
|
+
formattedString = `(${value})`;
|
|
645
|
+
}
|
|
646
|
+
if (useNew) {
|
|
647
|
+
formattedString = `new ${formattedString}`;
|
|
648
|
+
}
|
|
649
|
+
return formattedString;
|
|
650
|
+
};
|
|
571
651
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
652
|
+
const inspectArray = (
|
|
653
|
+
value,
|
|
654
|
+
{
|
|
655
|
+
seen = [],
|
|
656
|
+
nestedHumanize,
|
|
657
|
+
depth,
|
|
658
|
+
indentUsingTab,
|
|
659
|
+
indentSize,
|
|
660
|
+
parenthesis,
|
|
661
|
+
useNew,
|
|
662
|
+
},
|
|
663
|
+
) => {
|
|
664
|
+
if (seen.indexOf(value) > -1) {
|
|
665
|
+
return "Symbol.for('circular')";
|
|
666
|
+
}
|
|
667
|
+
seen.push(value);
|
|
575
668
|
|
|
576
|
-
|
|
577
|
-
|
|
669
|
+
let valuesSource = "";
|
|
670
|
+
let i = 0;
|
|
671
|
+
const j = value.length;
|
|
578
672
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
673
|
+
while (i < j) {
|
|
674
|
+
const valueSource = value.hasOwnProperty(i)
|
|
675
|
+
? nestedHumanize(value[i], { seen })
|
|
676
|
+
: "";
|
|
677
|
+
if (i === 0) {
|
|
678
|
+
valuesSource += valueSource;
|
|
679
|
+
} else {
|
|
680
|
+
valuesSource += `,${preNewLineAndIndentation(valueSource, {
|
|
681
|
+
depth,
|
|
682
|
+
indentUsingTab,
|
|
683
|
+
indentSize,
|
|
684
|
+
})}`;
|
|
685
|
+
}
|
|
686
|
+
i++;
|
|
687
|
+
}
|
|
583
688
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
689
|
+
let arraySource;
|
|
690
|
+
if (valuesSource.length) {
|
|
691
|
+
arraySource = wrapNewLineAndIndentation(valuesSource, {
|
|
692
|
+
depth,
|
|
693
|
+
indentUsingTab,
|
|
694
|
+
indentSize,
|
|
695
|
+
});
|
|
696
|
+
} else {
|
|
697
|
+
arraySource = "";
|
|
698
|
+
}
|
|
590
699
|
|
|
591
|
-
|
|
592
|
-
return 2;
|
|
593
|
-
}
|
|
700
|
+
arraySource = `[${arraySource}]`;
|
|
594
701
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
702
|
+
return inspectConstructor(arraySource, { parenthesis, useNew });
|
|
703
|
+
};
|
|
598
704
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
705
|
+
const inspectBigIntObject = (value, { nestedHumanize }) => {
|
|
706
|
+
const bigIntSource = nestedHumanize(value.valueOf());
|
|
602
707
|
|
|
603
|
-
|
|
604
|
-
}
|
|
708
|
+
return `BigInt(${bigIntSource})`;
|
|
709
|
+
};
|
|
605
710
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
711
|
+
const inspectBooleanObject = (
|
|
712
|
+
value,
|
|
713
|
+
{ nestedHumanize, useNew, parenthesis },
|
|
714
|
+
) => {
|
|
715
|
+
const booleanSource = nestedHumanize(value.valueOf());
|
|
716
|
+
return inspectConstructor(`Boolean(${booleanSource})`, {
|
|
717
|
+
useNew,
|
|
718
|
+
parenthesis,
|
|
719
|
+
});
|
|
720
|
+
};
|
|
611
721
|
|
|
612
|
-
|
|
613
|
-
|
|
722
|
+
const inspectError = (
|
|
723
|
+
error,
|
|
724
|
+
{ nestedHumanize, useNew, parenthesis },
|
|
725
|
+
) => {
|
|
726
|
+
const messageSource = nestedHumanize(error.message);
|
|
614
727
|
|
|
615
|
-
(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
728
|
+
const errorSource = inspectConstructor(
|
|
729
|
+
`${errorToConstructorName(error)}(${messageSource})`,
|
|
730
|
+
{
|
|
731
|
+
useNew,
|
|
732
|
+
parenthesis,
|
|
733
|
+
},
|
|
734
|
+
);
|
|
735
|
+
return errorSource;
|
|
736
|
+
};
|
|
619
737
|
|
|
620
|
-
const
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
738
|
+
const errorToConstructorName = ({ name }) => {
|
|
739
|
+
if (derivedErrorNameArray.includes(name)) {
|
|
740
|
+
return name;
|
|
741
|
+
}
|
|
742
|
+
return "Error";
|
|
743
|
+
};
|
|
624
744
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
color: (text, ANSI_COLOR) => {
|
|
635
|
-
return ANSI.supported ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
636
|
-
},
|
|
745
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types
|
|
746
|
+
const derivedErrorNameArray = [
|
|
747
|
+
"EvalError",
|
|
748
|
+
"RangeError",
|
|
749
|
+
"ReferenceError",
|
|
750
|
+
"SyntaxError",
|
|
751
|
+
"TypeError",
|
|
752
|
+
"URIError",
|
|
753
|
+
];
|
|
637
754
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
755
|
+
const inspectDate = (value, { nestedHumanize, useNew, parenthesis }) => {
|
|
756
|
+
const dateSource = nestedHumanize(value.valueOf(), {
|
|
757
|
+
numericSeparator: false,
|
|
758
|
+
});
|
|
759
|
+
return inspectConstructor(`Date(${dateSource})`, { useNew, parenthesis });
|
|
642
760
|
};
|
|
643
761
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
|
659
|
-
fps = 20,
|
|
660
|
-
keepProcessAlive = false,
|
|
661
|
-
stopOnWriteFromOutside = true,
|
|
662
|
-
stopOnVerticalOverflow = true,
|
|
663
|
-
render = () => "",
|
|
664
|
-
effect = () => {},
|
|
665
|
-
animated = dynamicLog.stream.isTTY,
|
|
666
|
-
}) => {
|
|
667
|
-
let frameIndex = 0;
|
|
668
|
-
let interval;
|
|
669
|
-
let running = true;
|
|
762
|
+
const inspectFunction = (
|
|
763
|
+
value,
|
|
764
|
+
{ showFunctionBody, parenthesis, depth },
|
|
765
|
+
) => {
|
|
766
|
+
let functionSource;
|
|
767
|
+
if (showFunctionBody) {
|
|
768
|
+
functionSource = value.toString();
|
|
769
|
+
} else {
|
|
770
|
+
const isArrowFunction = value.prototype === undefined;
|
|
771
|
+
const head = isArrowFunction
|
|
772
|
+
? "() =>"
|
|
773
|
+
: `function ${depth === 0 ? value.name : ""}()`;
|
|
774
|
+
functionSource = `${head} {/* hidden */}`;
|
|
775
|
+
}
|
|
670
776
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
777
|
+
if (parenthesis) {
|
|
778
|
+
return `(${functionSource})`;
|
|
779
|
+
}
|
|
780
|
+
return functionSource;
|
|
781
|
+
};
|
|
674
782
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
};
|
|
681
|
-
|
|
783
|
+
const inspectNumberObject = (
|
|
784
|
+
value,
|
|
785
|
+
{ nestedHumanize, useNew, parenthesis },
|
|
786
|
+
) => {
|
|
787
|
+
const numberSource = nestedHumanize(value.valueOf());
|
|
788
|
+
return inspectConstructor(`Number(${numberSource})`, { useNew, parenthesis });
|
|
789
|
+
};
|
|
682
790
|
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
791
|
+
const inspectObject = (
|
|
792
|
+
value,
|
|
793
|
+
{
|
|
794
|
+
nestedHumanize,
|
|
795
|
+
seen = [],
|
|
796
|
+
depth,
|
|
797
|
+
indentUsingTab,
|
|
798
|
+
indentSize,
|
|
799
|
+
objectConstructor,
|
|
800
|
+
parenthesis,
|
|
801
|
+
useNew,
|
|
802
|
+
},
|
|
803
|
+
) => {
|
|
804
|
+
if (seen.indexOf(value) > -1) return "Symbol.for('circular')";
|
|
688
805
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
806
|
+
seen.push(value);
|
|
807
|
+
|
|
808
|
+
const propertySourceArray = [];
|
|
809
|
+
Object.getOwnPropertyNames(value).forEach((propertyName) => {
|
|
810
|
+
const propertyNameAsNumber = parseInt(propertyName, 10);
|
|
811
|
+
const propertyNameSource = nestedHumanize(
|
|
812
|
+
Number.isInteger(propertyNameAsNumber)
|
|
813
|
+
? propertyNameAsNumber
|
|
814
|
+
: propertyName,
|
|
815
|
+
);
|
|
816
|
+
propertySourceArray.push({
|
|
817
|
+
nameOrSymbolSource: propertyNameSource,
|
|
818
|
+
valueSource: nestedHumanize(value[propertyName], { seen }),
|
|
819
|
+
});
|
|
820
|
+
});
|
|
821
|
+
Object.getOwnPropertySymbols(value).forEach((symbol) => {
|
|
822
|
+
propertySourceArray.push({
|
|
823
|
+
nameOrSymbolSource: `[${nestedHumanize(symbol)}]`,
|
|
824
|
+
valueSource: nestedHumanize(value[symbol], { seen }),
|
|
825
|
+
});
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
let propertiesSource = "";
|
|
829
|
+
propertySourceArray.forEach(({ nameOrSymbolSource, valueSource }, index) => {
|
|
830
|
+
if (index === 0) {
|
|
831
|
+
propertiesSource += `${nameOrSymbolSource}: ${valueSource}`;
|
|
832
|
+
} else {
|
|
833
|
+
propertiesSource += `,${preNewLineAndIndentation(
|
|
834
|
+
`${nameOrSymbolSource}: ${valueSource}`,
|
|
835
|
+
{
|
|
836
|
+
depth,
|
|
837
|
+
indentUsingTab,
|
|
838
|
+
indentSize,
|
|
839
|
+
},
|
|
840
|
+
)}`;
|
|
695
841
|
}
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
let objectSource;
|
|
845
|
+
if (propertiesSource.length) {
|
|
846
|
+
objectSource = `${wrapNewLineAndIndentation(propertiesSource, {
|
|
847
|
+
depth,
|
|
848
|
+
indentUsingTab,
|
|
849
|
+
indentSize,
|
|
850
|
+
})}`;
|
|
696
851
|
} else {
|
|
697
|
-
|
|
852
|
+
objectSource = "";
|
|
698
853
|
}
|
|
699
854
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
855
|
+
if (objectConstructor) {
|
|
856
|
+
objectSource = `Object({${objectSource}})`;
|
|
857
|
+
} else {
|
|
858
|
+
objectSource = `{${objectSource}}`;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
return inspectConstructor(objectSource, { parenthesis, useNew });
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
const inspectRegExp = (value) => value.toString();
|
|
865
|
+
|
|
866
|
+
const inspectStringObject = (
|
|
867
|
+
value,
|
|
868
|
+
{ nestedHumanize, useNew, parenthesis },
|
|
869
|
+
) => {
|
|
870
|
+
const stringSource = nestedHumanize(value.valueOf());
|
|
871
|
+
|
|
872
|
+
return inspectConstructor(`String(${stringSource})`, { useNew, parenthesis });
|
|
873
|
+
};
|
|
874
|
+
|
|
875
|
+
// primitives
|
|
876
|
+
|
|
877
|
+
const humanize = (
|
|
878
|
+
value,
|
|
879
|
+
{
|
|
880
|
+
parenthesis = false,
|
|
881
|
+
quote = "auto",
|
|
882
|
+
canUseTemplateString = true,
|
|
883
|
+
useNew = false,
|
|
884
|
+
objectConstructor = false,
|
|
885
|
+
showFunctionBody = false,
|
|
886
|
+
indentUsingTab = false,
|
|
887
|
+
indentSize = 2,
|
|
888
|
+
numericSeparator = true,
|
|
889
|
+
preserveLineBreaks = false,
|
|
890
|
+
} = {},
|
|
891
|
+
) => {
|
|
892
|
+
const scopedHumanize = (scopedValue, scopedOptions) => {
|
|
893
|
+
const options = {
|
|
894
|
+
...scopedOptions,
|
|
895
|
+
nestedHumanize: (nestedValue, nestedOptions = {}) => {
|
|
896
|
+
return scopedHumanize(nestedValue, {
|
|
897
|
+
...scopedOptions,
|
|
898
|
+
depth: scopedOptions.depth + 1,
|
|
899
|
+
...nestedOptions,
|
|
900
|
+
});
|
|
901
|
+
},
|
|
902
|
+
};
|
|
903
|
+
return humanizeValue(scopedValue, options);
|
|
714
904
|
};
|
|
715
|
-
spinner.stop = stop;
|
|
716
905
|
|
|
717
|
-
|
|
718
|
-
|
|
906
|
+
return scopedHumanize(value, {
|
|
907
|
+
parenthesis,
|
|
908
|
+
quote,
|
|
909
|
+
canUseTemplateString,
|
|
910
|
+
useNew,
|
|
911
|
+
objectConstructor,
|
|
912
|
+
showFunctionBody,
|
|
913
|
+
indentUsingTab,
|
|
914
|
+
indentSize,
|
|
915
|
+
numericSeparator,
|
|
916
|
+
preserveLineBreaks,
|
|
917
|
+
depth: 0,
|
|
918
|
+
});
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
const humanizeMethodSymbol = Symbol.for("inspect");
|
|
922
|
+
|
|
923
|
+
const humanizeValue = (value, options) => {
|
|
924
|
+
const customHumanize = value && value[humanizeMethodSymbol];
|
|
925
|
+
if (customHumanize) {
|
|
926
|
+
return customHumanize(options);
|
|
719
927
|
}
|
|
720
|
-
|
|
721
|
-
|
|
928
|
+
const primitiveType = primitiveTypeFromValue(value);
|
|
929
|
+
const primitiveStringifier = primitiveStringifiers[primitiveType];
|
|
930
|
+
if (primitiveStringifier) {
|
|
931
|
+
return primitiveStringifier(value, options);
|
|
722
932
|
}
|
|
933
|
+
const compositeType = compositeTypeFromObject(value);
|
|
934
|
+
const compositeStringifier = compositeStringifiers[compositeType];
|
|
935
|
+
if (compositeStringifier) {
|
|
936
|
+
return compositeStringifier(value, options);
|
|
937
|
+
}
|
|
938
|
+
return inspectConstructor(
|
|
939
|
+
`${compositeType}(${inspectObject(value, options)})`,
|
|
940
|
+
{
|
|
941
|
+
...options,
|
|
942
|
+
parenthesis: false,
|
|
943
|
+
},
|
|
944
|
+
);
|
|
945
|
+
};
|
|
723
946
|
|
|
724
|
-
|
|
947
|
+
const primitiveTypeFromValue = (value) => {
|
|
948
|
+
if (value === null) {
|
|
949
|
+
return "null";
|
|
950
|
+
}
|
|
951
|
+
if (value === undefined) {
|
|
952
|
+
return "undefined";
|
|
953
|
+
}
|
|
954
|
+
return typeof value;
|
|
955
|
+
};
|
|
956
|
+
const primitiveStringifiers = {
|
|
957
|
+
boolean: inspectBoolean,
|
|
958
|
+
function: inspectFunction,
|
|
959
|
+
null: inspectNull,
|
|
960
|
+
number: inspectNumber,
|
|
961
|
+
string: inspectString,
|
|
962
|
+
symbol: inspectSymbol,
|
|
963
|
+
undefined: inspectUndefined,
|
|
964
|
+
bigint: inspectBigInt,
|
|
965
|
+
};
|
|
966
|
+
const compositeTypeFromObject = (object) => {
|
|
967
|
+
if (typeof object === "object" && Object.getPrototypeOf(object) === null) {
|
|
968
|
+
return "Object";
|
|
969
|
+
}
|
|
970
|
+
const toStringResult = toString.call(object);
|
|
971
|
+
// returns format is '[object ${tagName}]';
|
|
972
|
+
// and we want ${tagName}
|
|
973
|
+
const tagName = toStringResult.slice("[object ".length, -1);
|
|
974
|
+
if (tagName === "Object") {
|
|
975
|
+
const objectConstructorName = object.constructor.name;
|
|
976
|
+
if (objectConstructorName !== "Object") {
|
|
977
|
+
return objectConstructorName;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return tagName;
|
|
981
|
+
};
|
|
982
|
+
const { toString } = Object.prototype;
|
|
983
|
+
|
|
984
|
+
const compositeStringifiers = {
|
|
985
|
+
Array: inspectArray,
|
|
986
|
+
BigInt: inspectBigIntObject,
|
|
987
|
+
Boolean: inspectBooleanObject,
|
|
988
|
+
Error: inspectError,
|
|
989
|
+
Date: inspectDate,
|
|
990
|
+
Function: inspectFunction,
|
|
991
|
+
Number: inspectNumberObject,
|
|
992
|
+
Object: inspectObject,
|
|
993
|
+
RegExp: inspectRegExp,
|
|
994
|
+
String: inspectStringObject,
|
|
725
995
|
};
|
|
726
996
|
|
|
727
997
|
const getPrecision = (number) => {
|
|
@@ -948,1056 +1218,725 @@ const parseMs = (ms) => {
|
|
|
948
1218
|
};
|
|
949
1219
|
};
|
|
950
1220
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
1221
|
+
const humanizeFileSize = (numberOfBytes, { decimals, short } = {}) => {
|
|
1222
|
+
return inspectBytes(numberOfBytes, { decimals, short });
|
|
1223
|
+
};
|
|
955
1224
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|| process$1.env.TERM_PROGRAM === 'Terminus-Sublime'
|
|
960
|
-
|| process$1.env.TERM_PROGRAM === 'vscode'
|
|
961
|
-
|| process$1.env.TERM === 'xterm-256color'
|
|
962
|
-
|| process$1.env.TERM === 'alacritty'
|
|
963
|
-
|| process$1.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
|
|
964
|
-
}
|
|
1225
|
+
const humanizeMemory = (metricValue, { decimals, short } = {}) => {
|
|
1226
|
+
return inspectBytes(metricValue, { decimals, fixedDecimals: true, short });
|
|
1227
|
+
};
|
|
965
1228
|
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
const UNICODE = {
|
|
970
|
-
supported: isUnicodeSupported(),
|
|
971
|
-
|
|
972
|
-
get COMMAND_RAW() {
|
|
973
|
-
return UNICODE.supported ? `❯` : `>`;
|
|
974
|
-
},
|
|
975
|
-
get OK_RAW() {
|
|
976
|
-
return UNICODE.supported ? `✔` : `√`;
|
|
977
|
-
},
|
|
978
|
-
get FAILURE_RAW() {
|
|
979
|
-
return UNICODE.supported ? `✖` : `×`;
|
|
980
|
-
},
|
|
981
|
-
get DEBUG_RAW() {
|
|
982
|
-
return UNICODE.supported ? `◆` : `♦`;
|
|
983
|
-
},
|
|
984
|
-
get INFO_RAW() {
|
|
985
|
-
return UNICODE.supported ? `ℹ` : `i`;
|
|
986
|
-
},
|
|
987
|
-
get WARNING_RAW() {
|
|
988
|
-
return UNICODE.supported ? `⚠` : `‼`;
|
|
989
|
-
},
|
|
990
|
-
get CIRCLE_CROSS_RAW() {
|
|
991
|
-
return UNICODE.supported ? `ⓧ` : `(×)`;
|
|
992
|
-
},
|
|
993
|
-
get COMMAND() {
|
|
994
|
-
return ANSI.color(UNICODE.COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
|
|
995
|
-
},
|
|
996
|
-
get OK() {
|
|
997
|
-
return ANSI.color(UNICODE.OK_RAW, ANSI.GREEN);
|
|
998
|
-
},
|
|
999
|
-
get FAILURE() {
|
|
1000
|
-
return ANSI.color(UNICODE.FAILURE_RAW, ANSI.RED);
|
|
1001
|
-
},
|
|
1002
|
-
get DEBUG() {
|
|
1003
|
-
return ANSI.color(UNICODE.DEBUG_RAW, ANSI.GREY);
|
|
1004
|
-
},
|
|
1005
|
-
get INFO() {
|
|
1006
|
-
return ANSI.color(UNICODE.INFO_RAW, ANSI.BLUE);
|
|
1007
|
-
},
|
|
1008
|
-
get WARNING() {
|
|
1009
|
-
return ANSI.color(UNICODE.WARNING_RAW, ANSI.YELLOW);
|
|
1010
|
-
},
|
|
1011
|
-
get CIRCLE_CROSS() {
|
|
1012
|
-
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
1013
|
-
},
|
|
1014
|
-
};
|
|
1015
|
-
|
|
1016
|
-
const createTaskLog = (
|
|
1017
|
-
label,
|
|
1018
|
-
{ disabled = false, animated = true, stopOnWriteFromOutside } = {},
|
|
1229
|
+
const inspectBytes = (
|
|
1230
|
+
number,
|
|
1231
|
+
{ fixedDecimals = false, decimals, short } = {},
|
|
1019
1232
|
) => {
|
|
1020
|
-
if (
|
|
1021
|
-
return
|
|
1022
|
-
setRightText: () => {},
|
|
1023
|
-
done: () => {},
|
|
1024
|
-
happen: () => {},
|
|
1025
|
-
fail: () => {},
|
|
1026
|
-
};
|
|
1233
|
+
if (number === 0) {
|
|
1234
|
+
return `0 B`;
|
|
1027
1235
|
}
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1236
|
+
const exponent = Math.min(
|
|
1237
|
+
Math.floor(Math.log10(number) / 3),
|
|
1238
|
+
BYTE_UNITS.length - 1,
|
|
1239
|
+
);
|
|
1240
|
+
const unitNumber = number / Math.pow(1000, exponent);
|
|
1241
|
+
const unitName = BYTE_UNITS[exponent];
|
|
1242
|
+
if (decimals === undefined) {
|
|
1243
|
+
if (unitNumber < 100) {
|
|
1244
|
+
decimals = 1;
|
|
1245
|
+
} else {
|
|
1246
|
+
decimals = 0;
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
const unitNumberRounded = setRoundedPrecision(unitNumber, {
|
|
1250
|
+
decimals,
|
|
1251
|
+
decimalsWhenSmall: 1,
|
|
1036
1252
|
});
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
`${UNICODE.OK} ${label} (done in ${humanizeDuration(msEllapsed)})`,
|
|
1045
|
-
);
|
|
1046
|
-
},
|
|
1047
|
-
happen: (message) => {
|
|
1048
|
-
taskSpinner.stop(
|
|
1049
|
-
`${UNICODE.INFO} ${message} (at ${new Date().toLocaleTimeString()})`,
|
|
1050
|
-
);
|
|
1051
|
-
},
|
|
1052
|
-
fail: (message = `failed to ${label}`) => {
|
|
1053
|
-
taskSpinner.stop(`${UNICODE.FAILURE} ${message}`);
|
|
1054
|
-
},
|
|
1055
|
-
};
|
|
1253
|
+
const value = fixedDecimals
|
|
1254
|
+
? unitNumberRounded.toFixed(decimals)
|
|
1255
|
+
: unitNumberRounded;
|
|
1256
|
+
if (short) {
|
|
1257
|
+
return `${value}${unitName}`;
|
|
1258
|
+
}
|
|
1259
|
+
return `${value} ${unitName}`;
|
|
1056
1260
|
};
|
|
1057
1261
|
|
|
1058
|
-
const
|
|
1059
|
-
let string = `${message}`;
|
|
1262
|
+
const BYTE_UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
1060
1263
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1264
|
+
const distributePercentages = (
|
|
1265
|
+
namedNumbers,
|
|
1266
|
+
{ maxPrecisionHint = 2 } = {},
|
|
1267
|
+
) => {
|
|
1268
|
+
const numberNames = Object.keys(namedNumbers);
|
|
1269
|
+
if (numberNames.length === 0) {
|
|
1270
|
+
return {};
|
|
1271
|
+
}
|
|
1272
|
+
if (numberNames.length === 1) {
|
|
1273
|
+
const firstNumberName = numberNames[0];
|
|
1274
|
+
return { [firstNumberName]: "100 %" };
|
|
1275
|
+
}
|
|
1276
|
+
const numbers = numberNames.map((name) => namedNumbers[name]);
|
|
1277
|
+
const total = numbers.reduce((sum, value) => sum + value, 0);
|
|
1278
|
+
const ratios = numbers.map((number) => number / total);
|
|
1279
|
+
const percentages = {};
|
|
1280
|
+
ratios.pop();
|
|
1281
|
+
ratios.forEach((ratio, index) => {
|
|
1282
|
+
const percentage = ratio * 100;
|
|
1283
|
+
percentages[numberNames[index]] = percentage;
|
|
1284
|
+
});
|
|
1285
|
+
const lowestPercentage = (1 / Math.pow(10, maxPrecisionHint)) * 100;
|
|
1286
|
+
let precision = 0;
|
|
1287
|
+
Object.keys(percentages).forEach((name) => {
|
|
1288
|
+
const percentage = percentages[name];
|
|
1289
|
+
if (percentage < lowestPercentage) {
|
|
1290
|
+
// check the amout of meaningful decimals
|
|
1291
|
+
// and that what we will use
|
|
1292
|
+
const percentageRounded = setRoundedPrecision(percentage);
|
|
1293
|
+
const percentagePrecision = getPrecision(percentageRounded);
|
|
1294
|
+
if (percentagePrecision > precision) {
|
|
1295
|
+
precision = percentagePrecision;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1071
1298
|
});
|
|
1299
|
+
let remainingPercentage = 100;
|
|
1072
1300
|
|
|
1073
|
-
|
|
1301
|
+
Object.keys(percentages).forEach((name) => {
|
|
1302
|
+
const percentage = percentages[name];
|
|
1303
|
+
const percentageAllocated = setRoundedPrecision(percentage, {
|
|
1304
|
+
decimals: precision,
|
|
1305
|
+
});
|
|
1306
|
+
remainingPercentage -= percentageAllocated;
|
|
1307
|
+
percentages[name] = percentageAllocated;
|
|
1308
|
+
});
|
|
1309
|
+
const lastName = numberNames[numberNames.length - 1];
|
|
1310
|
+
percentages[lastName] = setRoundedPrecision(remainingPercentage, {
|
|
1311
|
+
decimals: precision,
|
|
1312
|
+
});
|
|
1313
|
+
return percentages;
|
|
1074
1314
|
};
|
|
1075
1315
|
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
const inspectNull = () => "null";
|
|
1316
|
+
const formatDefault = (v) => v;
|
|
1079
1317
|
|
|
1080
|
-
|
|
1318
|
+
const generateContentFrame = ({
|
|
1319
|
+
content,
|
|
1320
|
+
line,
|
|
1321
|
+
column,
|
|
1081
1322
|
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1323
|
+
linesAbove = 3,
|
|
1324
|
+
linesBelow = 0,
|
|
1325
|
+
lineMaxWidth = 120,
|
|
1326
|
+
lineNumbersOnTheLeft = true,
|
|
1327
|
+
lineMarker = true,
|
|
1328
|
+
columnMarker = true,
|
|
1329
|
+
format = formatDefault,
|
|
1330
|
+
} = {}) => {
|
|
1331
|
+
const lineStrings = content.split(/\r?\n/);
|
|
1332
|
+
if (line === 0) line = 1;
|
|
1333
|
+
if (column === undefined) {
|
|
1334
|
+
columnMarker = false;
|
|
1335
|
+
column = 1;
|
|
1085
1336
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1337
|
+
if (column === 0) column = 1;
|
|
1338
|
+
|
|
1339
|
+
let lineStartIndex = line - 1 - linesAbove;
|
|
1340
|
+
if (lineStartIndex < 0) {
|
|
1341
|
+
lineStartIndex = 0;
|
|
1090
1342
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1343
|
+
let lineEndIndex = line - 1 + linesBelow;
|
|
1344
|
+
if (lineEndIndex > lineStrings.length - 1) {
|
|
1345
|
+
lineEndIndex = lineStrings.length - 1;
|
|
1093
1346
|
}
|
|
1094
|
-
if (
|
|
1095
|
-
|
|
1347
|
+
if (columnMarker) {
|
|
1348
|
+
// human reader deduce the line when there is a column marker
|
|
1349
|
+
lineMarker = false;
|
|
1096
1350
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
return numberString;
|
|
1351
|
+
if (line - 1 === lineEndIndex) {
|
|
1352
|
+
lineMarker = false; // useless because last line
|
|
1100
1353
|
}
|
|
1101
|
-
|
|
1102
|
-
number,
|
|
1103
|
-
mark = "",
|
|
1104
|
-
sign = "",
|
|
1105
|
-
power = "",
|
|
1106
|
-
} = numberString.match(
|
|
1107
|
-
/^(?<number>.*?)(?:(?<mark>e)(?<sign>[+-])?(?<power>\d+))?$/i,
|
|
1108
|
-
).groups;
|
|
1109
|
-
const numberWithSeparators = formatNumber(number);
|
|
1110
|
-
const powerWithSeparators = addSeparator(power, {
|
|
1111
|
-
minimumDigits: 5,
|
|
1112
|
-
groupLength: 3,
|
|
1113
|
-
});
|
|
1114
|
-
return `${numberWithSeparators}${mark}${sign}${powerWithSeparators}`;
|
|
1115
|
-
};
|
|
1116
|
-
|
|
1117
|
-
// Use this and instead of Object.is(value, -0)
|
|
1118
|
-
// because in some corner cases firefox returns false
|
|
1119
|
-
// for Object.is(-0, -0)
|
|
1120
|
-
const isNegativeZero = (value) => {
|
|
1121
|
-
return value === 0 && 1 / value === -Infinity;
|
|
1122
|
-
};
|
|
1123
|
-
|
|
1124
|
-
const formatNumber = (numberString) => {
|
|
1125
|
-
const parts = numberString.split(".");
|
|
1126
|
-
const [integer, fractional] = parts;
|
|
1354
|
+
let lineIndex = lineStartIndex;
|
|
1127
1355
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1356
|
+
let columnsBefore;
|
|
1357
|
+
let columnsAfter;
|
|
1358
|
+
if (column > lineMaxWidth) {
|
|
1359
|
+
columnsBefore = column - Math.ceil(lineMaxWidth / 2);
|
|
1360
|
+
columnsAfter = column + Math.floor(lineMaxWidth / 2);
|
|
1361
|
+
} else {
|
|
1362
|
+
columnsBefore = 0;
|
|
1363
|
+
columnsAfter = lineMaxWidth;
|
|
1134
1364
|
}
|
|
1365
|
+
let columnMarkerIndex = column - 1 - columnsBefore;
|
|
1135
1366
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1367
|
+
let source = "";
|
|
1368
|
+
while (lineIndex <= lineEndIndex) {
|
|
1369
|
+
const lineString = lineStrings[lineIndex];
|
|
1370
|
+
const lineNumber = lineIndex + 1;
|
|
1371
|
+
const isLastLine = lineIndex === lineEndIndex;
|
|
1372
|
+
const isMainLine = lineNumber === line;
|
|
1373
|
+
lineIndex++;
|
|
1141
1374
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1375
|
+
{
|
|
1376
|
+
if (lineMarker) {
|
|
1377
|
+
if (isMainLine) {
|
|
1378
|
+
source += `${format(">", "marker_line")} `;
|
|
1379
|
+
} else {
|
|
1380
|
+
source += " ";
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
if (lineNumbersOnTheLeft) {
|
|
1384
|
+
// fill with spaces to ensure if line moves from 7,8,9 to 10 the display is still great
|
|
1385
|
+
const asideSource = `${fillLeft(lineNumber, lineEndIndex + 1)} |`;
|
|
1386
|
+
source += `${format(asideSource, "line_number_aside")} `;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
{
|
|
1390
|
+
source += truncateLine(lineString, {
|
|
1391
|
+
start: columnsBefore,
|
|
1392
|
+
end: columnsAfter,
|
|
1393
|
+
prefix: "…",
|
|
1394
|
+
suffix: "…",
|
|
1395
|
+
format,
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
{
|
|
1399
|
+
if (columnMarker && isMainLine) {
|
|
1400
|
+
source += `\n`;
|
|
1401
|
+
if (lineMarker) {
|
|
1402
|
+
source += " ";
|
|
1403
|
+
}
|
|
1404
|
+
if (lineNumbersOnTheLeft) {
|
|
1405
|
+
const asideSpaces = `${fillLeft(lineNumber, lineEndIndex + 1)} | `
|
|
1406
|
+
.length;
|
|
1407
|
+
source += " ".repeat(asideSpaces);
|
|
1408
|
+
}
|
|
1409
|
+
source += " ".repeat(columnMarkerIndex);
|
|
1410
|
+
source += format("^", "marker_column");
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
if (!isLastLine) {
|
|
1414
|
+
source += "\n";
|
|
1415
|
+
}
|
|
1148
1416
|
}
|
|
1149
|
-
return
|
|
1417
|
+
return source;
|
|
1150
1418
|
};
|
|
1151
1419
|
|
|
1152
|
-
const
|
|
1153
|
-
const
|
|
1154
|
-
if (digitCount < minimumDigits) {
|
|
1155
|
-
return digits;
|
|
1156
|
-
}
|
|
1420
|
+
const truncateLine = (line, { start, end, prefix, suffix, format }) => {
|
|
1421
|
+
const lastIndex = line.length;
|
|
1157
1422
|
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
remainingDigits = remainingDigits.slice(0, -groupLength);
|
|
1163
|
-
digitsWithSeparator = `${group}_${digitsWithSeparator}`;
|
|
1423
|
+
if (line.length === 0) {
|
|
1424
|
+
// don't show any ellipsis if the line is empty
|
|
1425
|
+
// because it's not truncated in that case
|
|
1426
|
+
return "";
|
|
1164
1427
|
}
|
|
1165
|
-
return digitsWithSeparator;
|
|
1166
|
-
};
|
|
1167
|
-
|
|
1168
|
-
// const addSeparatorFromLeft = (value, { minimumDigits, groupLength }) => {
|
|
1169
|
-
// const { length } = value;
|
|
1170
|
-
// if (length < minimumDigits) {
|
|
1171
|
-
// return value;
|
|
1172
|
-
// }
|
|
1173
|
-
|
|
1174
|
-
// const parts = [];
|
|
1175
|
-
// for (let start = 0; start < length; start += groupLength) {
|
|
1176
|
-
// const end = Math.min(start + groupLength, length);
|
|
1177
|
-
// parts.push(value.slice(start, end));
|
|
1178
|
-
// }
|
|
1179
|
-
// return parts.join("_");
|
|
1180
|
-
// };
|
|
1181
1428
|
|
|
1182
|
-
const
|
|
1183
|
-
const
|
|
1184
|
-
const BACKTICK = "`";
|
|
1429
|
+
const startTruncated = start > 0;
|
|
1430
|
+
const endTruncated = lastIndex > end;
|
|
1185
1431
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
quote = "auto",
|
|
1190
|
-
canUseTemplateString = false,
|
|
1191
|
-
preserveLineBreaks = false,
|
|
1192
|
-
quoteDefault = DOUBLE_QUOTE,
|
|
1193
|
-
} = {},
|
|
1194
|
-
) => {
|
|
1195
|
-
quote =
|
|
1196
|
-
quote === "auto"
|
|
1197
|
-
? determineQuote(value, { canUseTemplateString, quoteDefault })
|
|
1198
|
-
: quote;
|
|
1199
|
-
if (quote === BACKTICK) {
|
|
1200
|
-
return `\`${escapeTemplateStringSpecialCharacters(value)}\``;
|
|
1201
|
-
}
|
|
1202
|
-
return surroundStringWith(value, { quote, preserveLineBreaks });
|
|
1203
|
-
};
|
|
1432
|
+
let from = startTruncated ? start + prefix.length : start;
|
|
1433
|
+
let to = endTruncated ? end - suffix.length : end;
|
|
1434
|
+
if (to > lastIndex) to = lastIndex;
|
|
1204
1435
|
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
string = String(string);
|
|
1208
|
-
let i = 0;
|
|
1209
|
-
let escapedString = "";
|
|
1210
|
-
while (i < string.length) {
|
|
1211
|
-
const char = string[i];
|
|
1212
|
-
i++;
|
|
1213
|
-
escapedString += isTemplateStringSpecialChar(char) ? `\\${char}` : char;
|
|
1436
|
+
if (start >= lastIndex || from === to) {
|
|
1437
|
+
return "";
|
|
1214
1438
|
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
templateStringSpecialChars.indexOf(char) > -1;
|
|
1220
|
-
const templateStringSpecialChars = ["\\", "`", "$"];
|
|
1221
|
-
|
|
1222
|
-
const determineQuote = (
|
|
1223
|
-
string,
|
|
1224
|
-
{ canUseTemplateString, quoteDefault = DOUBLE_QUOTE } = {},
|
|
1225
|
-
) => {
|
|
1226
|
-
const containsDoubleQuote = string.includes(DOUBLE_QUOTE);
|
|
1227
|
-
if (!containsDoubleQuote) {
|
|
1228
|
-
return DOUBLE_QUOTE;
|
|
1439
|
+
let result = "";
|
|
1440
|
+
while (from < to) {
|
|
1441
|
+
result += format(line[from], "char");
|
|
1442
|
+
from++;
|
|
1229
1443
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
return SINGLE_QUOTE;
|
|
1444
|
+
if (result.length === 0) {
|
|
1445
|
+
return "";
|
|
1233
1446
|
}
|
|
1234
|
-
if (
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
}
|
|
1447
|
+
if (startTruncated && endTruncated) {
|
|
1448
|
+
return `${format(prefix, "marker_overflow_left")}${result}${format(
|
|
1449
|
+
suffix,
|
|
1450
|
+
"marker_overflow_right",
|
|
1451
|
+
)}`;
|
|
1239
1452
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
if (singleQuoteCount > doubleQuoteCount) {
|
|
1243
|
-
return DOUBLE_QUOTE;
|
|
1453
|
+
if (startTruncated) {
|
|
1454
|
+
return `${format(prefix, "marker_overflow_left")}${result}`;
|
|
1244
1455
|
}
|
|
1245
|
-
if (
|
|
1246
|
-
return
|
|
1456
|
+
if (endTruncated) {
|
|
1457
|
+
return `${result}${format(suffix, "marker_overflow_right")}`;
|
|
1247
1458
|
}
|
|
1248
|
-
return
|
|
1459
|
+
return result;
|
|
1249
1460
|
};
|
|
1250
1461
|
|
|
1251
|
-
const
|
|
1252
|
-
const
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
point === 92 ||
|
|
1259
|
-
point < 32 ||
|
|
1260
|
-
(point > 126 && point < 160) ||
|
|
1261
|
-
// line separators
|
|
1262
|
-
point === 8232 ||
|
|
1263
|
-
point === 8233
|
|
1264
|
-
) {
|
|
1265
|
-
const replacement =
|
|
1266
|
-
char === quote
|
|
1267
|
-
? `\\${quote}`
|
|
1268
|
-
: point === 8232
|
|
1269
|
-
? "\\u2028"
|
|
1270
|
-
: point === 8233
|
|
1271
|
-
? "\\u2029"
|
|
1272
|
-
: meta[point];
|
|
1273
|
-
return replacement;
|
|
1462
|
+
const fillLeft = (value, biggestValue, char = " ") => {
|
|
1463
|
+
const width = String(value).length;
|
|
1464
|
+
const biggestWidth = String(biggestValue).length;
|
|
1465
|
+
let missingWidth = biggestWidth - width;
|
|
1466
|
+
let padded = "";
|
|
1467
|
+
while (missingWidth--) {
|
|
1468
|
+
padded += char;
|
|
1274
1469
|
}
|
|
1275
|
-
|
|
1470
|
+
padded += value;
|
|
1471
|
+
return padded;
|
|
1276
1472
|
};
|
|
1277
1473
|
|
|
1278
|
-
|
|
1279
|
-
// https://github.com/jsenv/jsenv-inspect/blob/bb11de3adf262b68f71ed82b0a37d4528dd42229/src/internal/string.js#L3
|
|
1280
|
-
// https://github.com/joliss/js-string-escape/blob/master/index.js
|
|
1281
|
-
// http://javascript.crockford.com/remedial.html
|
|
1282
|
-
const surroundStringWith = (string, { quote, preserveLineBreaks }) => {
|
|
1283
|
-
let result = "";
|
|
1284
|
-
let last = 0;
|
|
1285
|
-
const lastIndex = string.length;
|
|
1286
|
-
let i = 0;
|
|
1287
|
-
while (i < lastIndex) {
|
|
1288
|
-
const char = string[i];
|
|
1289
|
-
const replacement = inspectChar(char, { quote, preserveLineBreaks });
|
|
1290
|
-
if (char !== replacement) {
|
|
1291
|
-
if (last === i) {
|
|
1292
|
-
result += replacement;
|
|
1293
|
-
} else {
|
|
1294
|
-
result += `${string.slice(last, i)}${replacement}`;
|
|
1295
|
-
}
|
|
1296
|
-
last = i + 1;
|
|
1297
|
-
}
|
|
1298
|
-
i++;
|
|
1299
|
-
}
|
|
1300
|
-
if (last !== lastIndex) {
|
|
1301
|
-
result += string.slice(last);
|
|
1302
|
-
}
|
|
1303
|
-
return `${quote}${result}${quote}`;
|
|
1304
|
-
};
|
|
1474
|
+
const LOG_LEVEL_OFF = "off";
|
|
1305
1475
|
|
|
1306
|
-
|
|
1307
|
-
const meta = [
|
|
1308
|
-
'\\x00', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\x07', // x07
|
|
1309
|
-
'\\b', '\\t', '\\n', '\\x0B', '\\f', '\\r', '\\x0E', '\\x0F', // x0F
|
|
1310
|
-
'\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', // x17
|
|
1311
|
-
'\\x18', '\\x19', '\\x1A', '\\x1B', '\\x1C', '\\x1D', '\\x1E', '\\x1F', // x1F
|
|
1312
|
-
'', '', '', '', '', '', '', "\\'", '', '', '', '', '', '', '', '', // x2F
|
|
1313
|
-
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', // x3F
|
|
1314
|
-
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', // x4F
|
|
1315
|
-
'', '', '', '', '', '', '', '', '', '', '', '', '\\\\', '', '', '', // x5F
|
|
1316
|
-
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', // x6F
|
|
1317
|
-
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\\x7F', // x7F
|
|
1318
|
-
'\\x80', '\\x81', '\\x82', '\\x83', '\\x84', '\\x85', '\\x86', '\\x87', // x87
|
|
1319
|
-
'\\x88', '\\x89', '\\x8A', '\\x8B', '\\x8C', '\\x8D', '\\x8E', '\\x8F', // x8F
|
|
1320
|
-
'\\x90', '\\x91', '\\x92', '\\x93', '\\x94', '\\x95', '\\x96', '\\x97', // x97
|
|
1321
|
-
'\\x98', '\\x99', '\\x9A', '\\x9B', '\\x9C', '\\x9D', '\\x9E', '\\x9F', // x9F
|
|
1322
|
-
];
|
|
1476
|
+
const LOG_LEVEL_DEBUG = "debug";
|
|
1323
1477
|
|
|
1324
|
-
const
|
|
1325
|
-
const symbolDescription = symbolToDescription(value);
|
|
1326
|
-
const symbolDescriptionSource = symbolDescription
|
|
1327
|
-
? nestedHumanize(symbolDescription)
|
|
1328
|
-
: "";
|
|
1329
|
-
const symbolSource = `Symbol(${symbolDescriptionSource})`;
|
|
1478
|
+
const LOG_LEVEL_INFO = "info";
|
|
1330
1479
|
|
|
1331
|
-
|
|
1332
|
-
return symbolSource;
|
|
1333
|
-
};
|
|
1480
|
+
const LOG_LEVEL_WARN = "warn";
|
|
1334
1481
|
|
|
1335
|
-
const
|
|
1336
|
-
"description" in Symbol.prototype
|
|
1337
|
-
? (symbol) => symbol.description
|
|
1338
|
-
: (symbol) => {
|
|
1339
|
-
const toStringResult = symbol.toString();
|
|
1340
|
-
const openingParenthesisIndex = toStringResult.indexOf("(");
|
|
1341
|
-
const closingParenthesisIndex = toStringResult.indexOf(")");
|
|
1342
|
-
const symbolDescription = toStringResult.slice(
|
|
1343
|
-
openingParenthesisIndex + 1,
|
|
1344
|
-
closingParenthesisIndex,
|
|
1345
|
-
);
|
|
1346
|
-
return symbolDescription;
|
|
1347
|
-
};
|
|
1348
|
-
|
|
1349
|
-
const inspectUndefined = () => "undefined";
|
|
1482
|
+
const LOG_LEVEL_ERROR = "error";
|
|
1350
1483
|
|
|
1351
|
-
const
|
|
1352
|
-
|
|
1484
|
+
const createLogger = ({ logLevel = LOG_LEVEL_INFO } = {}) => {
|
|
1485
|
+
if (logLevel === LOG_LEVEL_DEBUG) {
|
|
1486
|
+
return {
|
|
1487
|
+
level: "debug",
|
|
1488
|
+
levels: { debug: true, info: true, warn: true, error: true },
|
|
1489
|
+
debug,
|
|
1490
|
+
info,
|
|
1491
|
+
warn,
|
|
1492
|
+
error,
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
if (logLevel === LOG_LEVEL_INFO) {
|
|
1496
|
+
return {
|
|
1497
|
+
level: "info",
|
|
1498
|
+
levels: { debug: false, info: true, warn: true, error: true },
|
|
1499
|
+
debug: debugDisabled,
|
|
1500
|
+
info,
|
|
1501
|
+
warn,
|
|
1502
|
+
error,
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
if (logLevel === LOG_LEVEL_WARN) {
|
|
1506
|
+
return {
|
|
1507
|
+
level: "warn",
|
|
1508
|
+
levels: { debug: false, info: false, warn: true, error: true },
|
|
1509
|
+
debug: debugDisabled,
|
|
1510
|
+
info: infoDisabled,
|
|
1511
|
+
warn,
|
|
1512
|
+
error,
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
if (logLevel === LOG_LEVEL_ERROR) {
|
|
1516
|
+
return {
|
|
1517
|
+
level: "error",
|
|
1518
|
+
levels: { debug: false, info: false, warn: false, error: true },
|
|
1519
|
+
debug: debugDisabled,
|
|
1520
|
+
info: infoDisabled,
|
|
1521
|
+
warn: warnDisabled,
|
|
1522
|
+
error,
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
if (logLevel === LOG_LEVEL_OFF) {
|
|
1526
|
+
return {
|
|
1527
|
+
level: "off",
|
|
1528
|
+
levels: { debug: false, info: false, warn: false, error: false },
|
|
1529
|
+
debug: debugDisabled,
|
|
1530
|
+
info: infoDisabled,
|
|
1531
|
+
warn: warnDisabled,
|
|
1532
|
+
error: errorDisabled,
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
throw new Error(`unexpected logLevel.
|
|
1536
|
+
--- logLevel ---
|
|
1537
|
+
${logLevel}
|
|
1538
|
+
--- allowed log levels ---
|
|
1539
|
+
${LOG_LEVEL_OFF}
|
|
1540
|
+
${LOG_LEVEL_ERROR}
|
|
1541
|
+
${LOG_LEVEL_WARN}
|
|
1542
|
+
${LOG_LEVEL_INFO}
|
|
1543
|
+
${LOG_LEVEL_DEBUG}`);
|
|
1353
1544
|
};
|
|
1354
1545
|
|
|
1355
|
-
const
|
|
1356
|
-
value,
|
|
1357
|
-
{ depth, indentUsingTab, indentSize },
|
|
1358
|
-
) => {
|
|
1359
|
-
return `${newLineAndIndent({
|
|
1360
|
-
count: depth + 1,
|
|
1361
|
-
useTabs: indentUsingTab,
|
|
1362
|
-
size: indentSize,
|
|
1363
|
-
})}${value}`;
|
|
1364
|
-
};
|
|
1546
|
+
const debug = (...args) => console.debug(...args);
|
|
1365
1547
|
|
|
1366
|
-
const
|
|
1367
|
-
return newLineAndIndent({
|
|
1368
|
-
count: depth,
|
|
1369
|
-
useTabs: indentUsingTab,
|
|
1370
|
-
size: indentSize,
|
|
1371
|
-
});
|
|
1372
|
-
};
|
|
1548
|
+
const debugDisabled = () => {};
|
|
1373
1549
|
|
|
1374
|
-
const
|
|
1375
|
-
if (useTabs) {
|
|
1376
|
-
// eslint-disable-next-line prefer-template
|
|
1377
|
-
return "\n" + "\t".repeat(count);
|
|
1378
|
-
}
|
|
1379
|
-
// eslint-disable-next-line prefer-template
|
|
1380
|
-
return "\n" + " ".repeat(count * size);
|
|
1381
|
-
};
|
|
1550
|
+
const info = (...args) => console.info(...args);
|
|
1382
1551
|
|
|
1383
|
-
const
|
|
1384
|
-
value,
|
|
1385
|
-
{ depth, indentUsingTab, indentSize },
|
|
1386
|
-
) => {
|
|
1387
|
-
return `${preNewLineAndIndentation(value, {
|
|
1388
|
-
depth,
|
|
1389
|
-
indentUsingTab,
|
|
1390
|
-
indentSize,
|
|
1391
|
-
})}${postNewLineAndIndentation({ depth, indentUsingTab, indentSize })}`;
|
|
1392
|
-
};
|
|
1552
|
+
const infoDisabled = () => {};
|
|
1393
1553
|
|
|
1394
|
-
const
|
|
1395
|
-
let formattedString = value;
|
|
1396
|
-
if (parenthesis) {
|
|
1397
|
-
formattedString = `(${value})`;
|
|
1398
|
-
}
|
|
1399
|
-
if (useNew) {
|
|
1400
|
-
formattedString = `new ${formattedString}`;
|
|
1401
|
-
}
|
|
1402
|
-
return formattedString;
|
|
1403
|
-
};
|
|
1554
|
+
const warn = (...args) => console.warn(...args);
|
|
1404
1555
|
|
|
1405
|
-
const
|
|
1406
|
-
value,
|
|
1407
|
-
{
|
|
1408
|
-
seen = [],
|
|
1409
|
-
nestedHumanize,
|
|
1410
|
-
depth,
|
|
1411
|
-
indentUsingTab,
|
|
1412
|
-
indentSize,
|
|
1413
|
-
parenthesis,
|
|
1414
|
-
useNew,
|
|
1415
|
-
},
|
|
1416
|
-
) => {
|
|
1417
|
-
if (seen.indexOf(value) > -1) {
|
|
1418
|
-
return "Symbol.for('circular')";
|
|
1419
|
-
}
|
|
1420
|
-
seen.push(value);
|
|
1556
|
+
const warnDisabled = () => {};
|
|
1421
1557
|
|
|
1422
|
-
|
|
1423
|
-
let i = 0;
|
|
1424
|
-
const j = value.length;
|
|
1558
|
+
const error = (...args) => console.error(...args);
|
|
1425
1559
|
|
|
1426
|
-
|
|
1427
|
-
const valueSource = value.hasOwnProperty(i)
|
|
1428
|
-
? nestedHumanize(value[i], { seen })
|
|
1429
|
-
: "";
|
|
1430
|
-
if (i === 0) {
|
|
1431
|
-
valuesSource += valueSource;
|
|
1432
|
-
} else {
|
|
1433
|
-
valuesSource += `,${preNewLineAndIndentation(valueSource, {
|
|
1434
|
-
depth,
|
|
1435
|
-
indentUsingTab,
|
|
1436
|
-
indentSize,
|
|
1437
|
-
})}`;
|
|
1438
|
-
}
|
|
1439
|
-
i++;
|
|
1440
|
-
}
|
|
1560
|
+
const errorDisabled = () => {};
|
|
1441
1561
|
|
|
1442
|
-
|
|
1443
|
-
if (valuesSource.length) {
|
|
1444
|
-
arraySource = wrapNewLineAndIndentation(valuesSource, {
|
|
1445
|
-
depth,
|
|
1446
|
-
indentUsingTab,
|
|
1447
|
-
indentSize,
|
|
1448
|
-
});
|
|
1449
|
-
} else {
|
|
1450
|
-
arraySource = "";
|
|
1451
|
-
}
|
|
1562
|
+
/* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
|
|
1452
1563
|
|
|
1453
|
-
|
|
1564
|
+
const isBrowser = globalThis.window?.document !== undefined;
|
|
1454
1565
|
|
|
1455
|
-
|
|
1456
|
-
};
|
|
1566
|
+
globalThis.process?.versions?.node !== undefined;
|
|
1457
1567
|
|
|
1458
|
-
|
|
1459
|
-
const bigIntSource = nestedHumanize(value.valueOf());
|
|
1568
|
+
globalThis.process?.versions?.bun !== undefined;
|
|
1460
1569
|
|
|
1461
|
-
|
|
1462
|
-
};
|
|
1570
|
+
globalThis.Deno?.version?.deno !== undefined;
|
|
1463
1571
|
|
|
1464
|
-
|
|
1465
|
-
value,
|
|
1466
|
-
{ nestedHumanize, useNew, parenthesis },
|
|
1467
|
-
) => {
|
|
1468
|
-
const booleanSource = nestedHumanize(value.valueOf());
|
|
1469
|
-
return inspectConstructor(`Boolean(${booleanSource})`, {
|
|
1470
|
-
useNew,
|
|
1471
|
-
parenthesis,
|
|
1472
|
-
});
|
|
1473
|
-
};
|
|
1572
|
+
globalThis.process?.versions?.electron !== undefined;
|
|
1474
1573
|
|
|
1475
|
-
|
|
1476
|
-
error,
|
|
1477
|
-
{ nestedHumanize, useNew, parenthesis },
|
|
1478
|
-
) => {
|
|
1479
|
-
const messageSource = nestedHumanize(error.message);
|
|
1574
|
+
globalThis.navigator?.userAgent?.includes('jsdom') === true;
|
|
1480
1575
|
|
|
1481
|
-
|
|
1482
|
-
`${errorToConstructorName(error)}(${messageSource})`,
|
|
1483
|
-
{
|
|
1484
|
-
useNew,
|
|
1485
|
-
parenthesis,
|
|
1486
|
-
},
|
|
1487
|
-
);
|
|
1488
|
-
return errorSource;
|
|
1489
|
-
};
|
|
1576
|
+
typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
|
|
1490
1577
|
|
|
1491
|
-
|
|
1492
|
-
if (derivedErrorNameArray.includes(name)) {
|
|
1493
|
-
return name;
|
|
1494
|
-
}
|
|
1495
|
-
return "Error";
|
|
1496
|
-
};
|
|
1578
|
+
typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
1497
1579
|
|
|
1498
|
-
|
|
1499
|
-
const derivedErrorNameArray = [
|
|
1500
|
-
"EvalError",
|
|
1501
|
-
"RangeError",
|
|
1502
|
-
"ReferenceError",
|
|
1503
|
-
"SyntaxError",
|
|
1504
|
-
"TypeError",
|
|
1505
|
-
"URIError",
|
|
1506
|
-
];
|
|
1580
|
+
typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
|
|
1507
1581
|
|
|
1508
|
-
|
|
1509
|
-
const dateSource = nestedHumanize(value.valueOf(), {
|
|
1510
|
-
numericSeparator: false,
|
|
1511
|
-
});
|
|
1512
|
-
return inspectConstructor(`Date(${dateSource})`, { useNew, parenthesis });
|
|
1513
|
-
};
|
|
1582
|
+
typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
|
|
1514
1583
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
{ showFunctionBody, parenthesis, depth },
|
|
1518
|
-
) => {
|
|
1519
|
-
let functionSource;
|
|
1520
|
-
if (showFunctionBody) {
|
|
1521
|
-
functionSource = value.toString();
|
|
1522
|
-
} else {
|
|
1523
|
-
const isArrowFunction = value.prototype === undefined;
|
|
1524
|
-
const head = isArrowFunction
|
|
1525
|
-
? "() =>"
|
|
1526
|
-
: `function ${depth === 0 ? value.name : ""}()`;
|
|
1527
|
-
functionSource = `${head} {/* hidden */}`;
|
|
1528
|
-
}
|
|
1584
|
+
// Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
|
|
1585
|
+
const platform = globalThis.navigator?.userAgentData?.platform;
|
|
1529
1586
|
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
};
|
|
1587
|
+
platform === 'macOS'
|
|
1588
|
+
|| globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
|
|
1589
|
+
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|
|
1590
|
+
|| globalThis.process?.platform === 'darwin';
|
|
1535
1591
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
) => {
|
|
1540
|
-
const numberSource = nestedHumanize(value.valueOf());
|
|
1541
|
-
return inspectConstructor(`Number(${numberSource})`, { useNew, parenthesis });
|
|
1542
|
-
};
|
|
1592
|
+
platform === 'Windows'
|
|
1593
|
+
|| globalThis.navigator?.platform === 'Win32'
|
|
1594
|
+
|| globalThis.process?.platform === 'win32';
|
|
1543
1595
|
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
seen = [],
|
|
1549
|
-
depth,
|
|
1550
|
-
indentUsingTab,
|
|
1551
|
-
indentSize,
|
|
1552
|
-
objectConstructor,
|
|
1553
|
-
parenthesis,
|
|
1554
|
-
useNew,
|
|
1555
|
-
},
|
|
1556
|
-
) => {
|
|
1557
|
-
if (seen.indexOf(value) > -1) return "Symbol.for('circular')";
|
|
1596
|
+
platform === 'Linux'
|
|
1597
|
+
|| globalThis.navigator?.platform?.startsWith('Linux') === true
|
|
1598
|
+
|| globalThis.navigator?.userAgent?.includes(' Linux ') === true
|
|
1599
|
+
|| globalThis.process?.platform === 'linux';
|
|
1558
1600
|
|
|
1559
|
-
|
|
1601
|
+
platform === 'Android'
|
|
1602
|
+
|| globalThis.navigator?.platform === 'Android'
|
|
1603
|
+
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|
|
1604
|
+
|| globalThis.process?.platform === 'android';
|
|
1560
1605
|
|
|
1561
|
-
|
|
1562
|
-
Object.getOwnPropertyNames(value).forEach((propertyName) => {
|
|
1563
|
-
const propertyNameAsNumber = parseInt(propertyName, 10);
|
|
1564
|
-
const propertyNameSource = nestedHumanize(
|
|
1565
|
-
Number.isInteger(propertyNameAsNumber)
|
|
1566
|
-
? propertyNameAsNumber
|
|
1567
|
-
: propertyName,
|
|
1568
|
-
);
|
|
1569
|
-
propertySourceArray.push({
|
|
1570
|
-
nameOrSymbolSource: propertyNameSource,
|
|
1571
|
-
valueSource: nestedHumanize(value[propertyName], { seen }),
|
|
1572
|
-
});
|
|
1573
|
-
});
|
|
1574
|
-
Object.getOwnPropertySymbols(value).forEach((symbol) => {
|
|
1575
|
-
propertySourceArray.push({
|
|
1576
|
-
nameOrSymbolSource: `[${nestedHumanize(symbol)}]`,
|
|
1577
|
-
valueSource: nestedHumanize(value[symbol], { seen }),
|
|
1578
|
-
});
|
|
1579
|
-
});
|
|
1606
|
+
const ESC = '\u001B[';
|
|
1580
1607
|
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
if (index === 0) {
|
|
1584
|
-
propertiesSource += `${nameOrSymbolSource}: ${valueSource}`;
|
|
1585
|
-
} else {
|
|
1586
|
-
propertiesSource += `,${preNewLineAndIndentation(
|
|
1587
|
-
`${nameOrSymbolSource}: ${valueSource}`,
|
|
1588
|
-
{
|
|
1589
|
-
depth,
|
|
1590
|
-
indentUsingTab,
|
|
1591
|
-
indentSize,
|
|
1592
|
-
},
|
|
1593
|
-
)}`;
|
|
1594
|
-
}
|
|
1595
|
-
});
|
|
1608
|
+
!isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
1609
|
+
const isWindows = !isBrowser && process$1.platform === 'win32';
|
|
1596
1610
|
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
depth,
|
|
1601
|
-
indentUsingTab,
|
|
1602
|
-
indentSize,
|
|
1603
|
-
})}`;
|
|
1604
|
-
} else {
|
|
1605
|
-
objectSource = "";
|
|
1606
|
-
}
|
|
1611
|
+
isBrowser ? () => {
|
|
1612
|
+
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
1613
|
+
} : process$1.cwd;
|
|
1607
1614
|
|
|
1608
|
-
|
|
1609
|
-
objectSource = `Object({${objectSource}})`;
|
|
1610
|
-
} else {
|
|
1611
|
-
objectSource = `{${objectSource}}`;
|
|
1612
|
-
}
|
|
1615
|
+
const cursorUp = (count = 1) => ESC + count + 'A';
|
|
1613
1616
|
|
|
1614
|
-
|
|
1615
|
-
};
|
|
1617
|
+
const cursorLeft = ESC + 'G';
|
|
1616
1618
|
|
|
1617
|
-
const
|
|
1619
|
+
const eraseLines = count => {
|
|
1620
|
+
let clear = '';
|
|
1618
1621
|
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
) => {
|
|
1623
|
-
const stringSource = nestedHumanize(value.valueOf());
|
|
1622
|
+
for (let i = 0; i < count; i++) {
|
|
1623
|
+
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
|
|
1624
|
+
}
|
|
1624
1625
|
|
|
1625
|
-
|
|
1626
|
+
if (count) {
|
|
1627
|
+
clear += cursorLeft;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
return clear;
|
|
1626
1631
|
};
|
|
1632
|
+
const eraseLine = ESC + '2K';
|
|
1633
|
+
const eraseScreen = ESC + '2J';
|
|
1627
1634
|
|
|
1628
|
-
|
|
1635
|
+
const clearTerminal = isWindows
|
|
1636
|
+
? `${eraseScreen}${ESC}0f`
|
|
1637
|
+
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
1638
|
+
// 2. Erases the whole screen including scrollback buffer
|
|
1639
|
+
// 3. Moves cursor to the top-left position
|
|
1640
|
+
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
1641
|
+
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
1629
1642
|
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
const options = {
|
|
1647
|
-
...scopedOptions,
|
|
1648
|
-
nestedHumanize: (nestedValue, nestedOptions = {}) => {
|
|
1649
|
-
return scopedHumanize(nestedValue, {
|
|
1650
|
-
...scopedOptions,
|
|
1651
|
-
depth: scopedOptions.depth + 1,
|
|
1652
|
-
...nestedOptions,
|
|
1653
|
-
});
|
|
1654
|
-
},
|
|
1655
|
-
};
|
|
1656
|
-
return humanizeValue(scopedValue, options);
|
|
1643
|
+
/*
|
|
1644
|
+
* see also https://github.com/vadimdemedes/ink
|
|
1645
|
+
*/
|
|
1646
|
+
|
|
1647
|
+
|
|
1648
|
+
const createDynamicLog = ({
|
|
1649
|
+
stream = process.stdout,
|
|
1650
|
+
clearTerminalAllowed,
|
|
1651
|
+
onVerticalOverflow = () => {},
|
|
1652
|
+
onWriteFromOutside = () => {},
|
|
1653
|
+
} = {}) => {
|
|
1654
|
+
const { columns = 80, rows = 24 } = stream;
|
|
1655
|
+
const dynamicLog = {
|
|
1656
|
+
destroyed: false,
|
|
1657
|
+
onVerticalOverflow,
|
|
1658
|
+
onWriteFromOutside,
|
|
1657
1659
|
};
|
|
1658
1660
|
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
useNew,
|
|
1664
|
-
objectConstructor,
|
|
1665
|
-
showFunctionBody,
|
|
1666
|
-
indentUsingTab,
|
|
1667
|
-
indentSize,
|
|
1668
|
-
numericSeparator,
|
|
1669
|
-
preserveLineBreaks,
|
|
1670
|
-
depth: 0,
|
|
1671
|
-
});
|
|
1672
|
-
};
|
|
1661
|
+
let lastOutput = "";
|
|
1662
|
+
let lastOutputFromOutside = "";
|
|
1663
|
+
let clearAttemptResult;
|
|
1664
|
+
let writing = false;
|
|
1673
1665
|
|
|
1674
|
-
const
|
|
1666
|
+
const getErasePreviousOutput = () => {
|
|
1667
|
+
// nothing to clear
|
|
1668
|
+
if (!lastOutput) {
|
|
1669
|
+
return "";
|
|
1670
|
+
}
|
|
1671
|
+
if (clearAttemptResult !== undefined) {
|
|
1672
|
+
return "";
|
|
1673
|
+
}
|
|
1675
1674
|
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
const compositeType = compositeTypeFromObject(value);
|
|
1687
|
-
const compositeStringifier = compositeStringifiers[compositeType];
|
|
1688
|
-
if (compositeStringifier) {
|
|
1689
|
-
return compositeStringifier(value, options);
|
|
1690
|
-
}
|
|
1691
|
-
return inspectConstructor(
|
|
1692
|
-
`${compositeType}(${inspectObject(value, options)})`,
|
|
1693
|
-
{
|
|
1694
|
-
...options,
|
|
1695
|
-
parenthesis: false,
|
|
1696
|
-
},
|
|
1697
|
-
);
|
|
1698
|
-
};
|
|
1675
|
+
const logLines = lastOutput.split(/\r\n|\r|\n/);
|
|
1676
|
+
let visualLineCount = 0;
|
|
1677
|
+
for (const logLine of logLines) {
|
|
1678
|
+
const width = stringWidth(logLine);
|
|
1679
|
+
if (width === 0) {
|
|
1680
|
+
visualLineCount++;
|
|
1681
|
+
} else {
|
|
1682
|
+
visualLineCount += Math.ceil(width / columns);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1699
1685
|
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
number: inspectNumber,
|
|
1714
|
-
string: inspectString,
|
|
1715
|
-
symbol: inspectSymbol,
|
|
1716
|
-
undefined: inspectUndefined,
|
|
1717
|
-
bigint: inspectBigInt,
|
|
1718
|
-
};
|
|
1719
|
-
const compositeTypeFromObject = (object) => {
|
|
1720
|
-
if (typeof object === "object" && Object.getPrototypeOf(object) === null) {
|
|
1721
|
-
return "Object";
|
|
1722
|
-
}
|
|
1723
|
-
const toStringResult = toString.call(object);
|
|
1724
|
-
// returns format is '[object ${tagName}]';
|
|
1725
|
-
// and we want ${tagName}
|
|
1726
|
-
const tagName = toStringResult.slice("[object ".length, -1);
|
|
1727
|
-
if (tagName === "Object") {
|
|
1728
|
-
const objectConstructorName = object.constructor.name;
|
|
1729
|
-
if (objectConstructorName !== "Object") {
|
|
1730
|
-
return objectConstructorName;
|
|
1686
|
+
if (visualLineCount > rows) {
|
|
1687
|
+
if (clearTerminalAllowed) {
|
|
1688
|
+
clearAttemptResult = true;
|
|
1689
|
+
return clearTerminal;
|
|
1690
|
+
}
|
|
1691
|
+
// the whole log cannot be cleared because it's vertically to long
|
|
1692
|
+
// (longer than terminal height)
|
|
1693
|
+
// readline.moveCursor cannot move cursor higher than screen height
|
|
1694
|
+
// it means we would only clear the visible part of the log
|
|
1695
|
+
// better keep the log untouched
|
|
1696
|
+
clearAttemptResult = false;
|
|
1697
|
+
dynamicLog.onVerticalOverflow();
|
|
1698
|
+
return "";
|
|
1731
1699
|
}
|
|
1732
|
-
}
|
|
1733
|
-
return tagName;
|
|
1734
|
-
};
|
|
1735
|
-
const { toString } = Object.prototype;
|
|
1736
1700
|
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
Boolean: inspectBooleanObject,
|
|
1741
|
-
Error: inspectError,
|
|
1742
|
-
Date: inspectDate,
|
|
1743
|
-
Function: inspectFunction,
|
|
1744
|
-
Number: inspectNumberObject,
|
|
1745
|
-
Object: inspectObject,
|
|
1746
|
-
RegExp: inspectRegExp,
|
|
1747
|
-
String: inspectStringObject,
|
|
1748
|
-
};
|
|
1701
|
+
clearAttemptResult = true;
|
|
1702
|
+
return eraseLines(visualLineCount);
|
|
1703
|
+
};
|
|
1749
1704
|
|
|
1750
|
-
const
|
|
1751
|
-
|
|
1752
|
-
|
|
1705
|
+
const update = (string) => {
|
|
1706
|
+
if (dynamicLog.destroyed) {
|
|
1707
|
+
throw new Error("Cannot write log after destroy");
|
|
1708
|
+
}
|
|
1709
|
+
let stringToWrite = string;
|
|
1710
|
+
if (lastOutput) {
|
|
1711
|
+
if (lastOutputFromOutside) {
|
|
1712
|
+
// We don't want to clear logs written by other code,
|
|
1713
|
+
// it makes output unreadable and might erase precious information
|
|
1714
|
+
// To detect this we put a spy on the stream.
|
|
1715
|
+
// The spy is required only if we actually wrote something in the stream
|
|
1716
|
+
// something else than this code has written in the stream
|
|
1717
|
+
// so we just write without clearing (append instead of replacing)
|
|
1718
|
+
lastOutput = "";
|
|
1719
|
+
lastOutputFromOutside = "";
|
|
1720
|
+
} else {
|
|
1721
|
+
stringToWrite = `${getErasePreviousOutput()}${string}`;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
writing = true;
|
|
1725
|
+
stream.write(stringToWrite);
|
|
1726
|
+
lastOutput = string;
|
|
1727
|
+
writing = false;
|
|
1728
|
+
clearAttemptResult = undefined;
|
|
1729
|
+
};
|
|
1753
1730
|
|
|
1754
|
-
const
|
|
1755
|
-
|
|
1756
|
-
|
|
1731
|
+
const clearDuringFunctionCall = (
|
|
1732
|
+
callback,
|
|
1733
|
+
ouputAfterCallback = lastOutput,
|
|
1734
|
+
) => {
|
|
1735
|
+
// 1. Erase the current log
|
|
1736
|
+
// 2. Call callback (expect to write something on stdout)
|
|
1737
|
+
// 3. Restore the current log
|
|
1738
|
+
// During step 2. we expect a "write from outside" so we uninstall
|
|
1739
|
+
// the stream spy during function call
|
|
1740
|
+
update("");
|
|
1757
1741
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
decimals = 1;
|
|
1774
|
-
} else {
|
|
1775
|
-
decimals = 0;
|
|
1742
|
+
writing = true;
|
|
1743
|
+
callback();
|
|
1744
|
+
writing = false;
|
|
1745
|
+
|
|
1746
|
+
update(ouputAfterCallback);
|
|
1747
|
+
};
|
|
1748
|
+
|
|
1749
|
+
const writeFromOutsideEffect = (value) => {
|
|
1750
|
+
if (!lastOutput) {
|
|
1751
|
+
// we don't care if the log never wrote anything
|
|
1752
|
+
// or if last update() wrote an empty string
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
if (writing) {
|
|
1756
|
+
return;
|
|
1776
1757
|
}
|
|
1758
|
+
lastOutputFromOutside = value;
|
|
1759
|
+
dynamicLog.onWriteFromOutside(value);
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
let removeStreamSpy;
|
|
1763
|
+
if (stream === process.stdout) {
|
|
1764
|
+
const removeStdoutSpy = spyStreamOutput(
|
|
1765
|
+
process.stdout,
|
|
1766
|
+
writeFromOutsideEffect,
|
|
1767
|
+
);
|
|
1768
|
+
const removeStderrSpy = spyStreamOutput(
|
|
1769
|
+
process.stderr,
|
|
1770
|
+
writeFromOutsideEffect,
|
|
1771
|
+
);
|
|
1772
|
+
removeStreamSpy = () => {
|
|
1773
|
+
removeStdoutSpy();
|
|
1774
|
+
removeStderrSpy();
|
|
1775
|
+
};
|
|
1776
|
+
} else {
|
|
1777
|
+
removeStreamSpy = spyStreamOutput(stream, writeFromOutsideEffect);
|
|
1777
1778
|
}
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1779
|
+
|
|
1780
|
+
const destroy = () => {
|
|
1781
|
+
dynamicLog.destroyed = true;
|
|
1782
|
+
if (removeStreamSpy) {
|
|
1783
|
+
removeStreamSpy();
|
|
1784
|
+
removeStreamSpy = null;
|
|
1785
|
+
lastOutput = "";
|
|
1786
|
+
lastOutputFromOutside = "";
|
|
1787
|
+
}
|
|
1788
|
+
};
|
|
1789
|
+
|
|
1790
|
+
Object.assign(dynamicLog, {
|
|
1791
|
+
update,
|
|
1792
|
+
destroy,
|
|
1793
|
+
stream,
|
|
1794
|
+
clearDuringFunctionCall,
|
|
1781
1795
|
});
|
|
1782
|
-
|
|
1783
|
-
? unitNumberRounded.toFixed(decimals)
|
|
1784
|
-
: unitNumberRounded;
|
|
1785
|
-
if (short) {
|
|
1786
|
-
return `${value}${unitName}`;
|
|
1787
|
-
}
|
|
1788
|
-
return `${value} ${unitName}`;
|
|
1796
|
+
return dynamicLog;
|
|
1789
1797
|
};
|
|
1790
1798
|
|
|
1791
|
-
|
|
1799
|
+
// maybe https://github.com/gajus/output-interceptor/tree/v3.0.0 ?
|
|
1800
|
+
// the problem with listening data on stdout
|
|
1801
|
+
// is that node.js will later throw error if stream gets closed
|
|
1802
|
+
// while something listening data on it
|
|
1803
|
+
const spyStreamOutput = (stream, callback) => {
|
|
1804
|
+
const originalWrite = stream.write;
|
|
1792
1805
|
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
)
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
return
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
ratios.pop();
|
|
1810
|
-
ratios.forEach((ratio, index) => {
|
|
1811
|
-
const percentage = ratio * 100;
|
|
1812
|
-
percentages[numberNames[index]] = percentage;
|
|
1813
|
-
});
|
|
1814
|
-
const lowestPercentage = (1 / Math.pow(10, maxPrecisionHint)) * 100;
|
|
1815
|
-
let precision = 0;
|
|
1816
|
-
Object.keys(percentages).forEach((name) => {
|
|
1817
|
-
const percentage = percentages[name];
|
|
1818
|
-
if (percentage < lowestPercentage) {
|
|
1819
|
-
// check the amout of meaningful decimals
|
|
1820
|
-
// and that what we will use
|
|
1821
|
-
const percentageRounded = setRoundedPrecision(percentage);
|
|
1822
|
-
const percentagePrecision = getPrecision(percentageRounded);
|
|
1823
|
-
if (percentagePrecision > precision) {
|
|
1824
|
-
precision = percentagePrecision;
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
});
|
|
1828
|
-
let remainingPercentage = 100;
|
|
1806
|
+
let output = "";
|
|
1807
|
+
let installed = true;
|
|
1808
|
+
|
|
1809
|
+
stream.write = function (...args /* chunk, encoding, callback */) {
|
|
1810
|
+
output += args;
|
|
1811
|
+
callback(output);
|
|
1812
|
+
return originalWrite.call(stream, ...args);
|
|
1813
|
+
};
|
|
1814
|
+
|
|
1815
|
+
const uninstall = () => {
|
|
1816
|
+
if (!installed) {
|
|
1817
|
+
return;
|
|
1818
|
+
}
|
|
1819
|
+
stream.write = originalWrite;
|
|
1820
|
+
installed = false;
|
|
1821
|
+
};
|
|
1829
1822
|
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
});
|
|
1835
|
-
remainingPercentage -= percentageAllocated;
|
|
1836
|
-
percentages[name] = percentageAllocated;
|
|
1837
|
-
});
|
|
1838
|
-
const lastName = numberNames[numberNames.length - 1];
|
|
1839
|
-
percentages[lastName] = setRoundedPrecision(remainingPercentage, {
|
|
1840
|
-
decimals: precision,
|
|
1841
|
-
});
|
|
1842
|
-
return percentages;
|
|
1823
|
+
return () => {
|
|
1824
|
+
uninstall();
|
|
1825
|
+
return output;
|
|
1826
|
+
};
|
|
1843
1827
|
};
|
|
1844
1828
|
|
|
1845
|
-
const
|
|
1829
|
+
const startSpinner = ({
|
|
1830
|
+
dynamicLog,
|
|
1831
|
+
frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
|
1832
|
+
fps = 20,
|
|
1833
|
+
keepProcessAlive = false,
|
|
1834
|
+
stopOnWriteFromOutside = true,
|
|
1835
|
+
stopOnVerticalOverflow = true,
|
|
1836
|
+
render = () => "",
|
|
1837
|
+
effect = () => {},
|
|
1838
|
+
animated = dynamicLog.stream.isTTY,
|
|
1839
|
+
}) => {
|
|
1840
|
+
let frameIndex = 0;
|
|
1841
|
+
let interval;
|
|
1842
|
+
let running = true;
|
|
1846
1843
|
|
|
1847
|
-
const
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
column,
|
|
1844
|
+
const spinner = {
|
|
1845
|
+
message: undefined,
|
|
1846
|
+
};
|
|
1851
1847
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
} = {}) => {
|
|
1860
|
-
const lineStrings = content.split(/\r?\n/);
|
|
1861
|
-
if (line === 0) line = 1;
|
|
1862
|
-
if (column === undefined) {
|
|
1863
|
-
columnMarker = false;
|
|
1864
|
-
column = 1;
|
|
1865
|
-
}
|
|
1866
|
-
if (column === 0) column = 1;
|
|
1848
|
+
const update = (message) => {
|
|
1849
|
+
spinner.message = running
|
|
1850
|
+
? `${frames[frameIndex]} ${message}\n`
|
|
1851
|
+
: `${message}\n`;
|
|
1852
|
+
return spinner.message;
|
|
1853
|
+
};
|
|
1854
|
+
spinner.update = update;
|
|
1867
1855
|
|
|
1868
|
-
let
|
|
1869
|
-
if (
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
if (lineEndIndex > lineStrings.length - 1) {
|
|
1874
|
-
lineEndIndex = lineStrings.length - 1;
|
|
1875
|
-
}
|
|
1876
|
-
if (columnMarker) {
|
|
1877
|
-
// human reader deduce the line when there is a column marker
|
|
1878
|
-
lineMarker = false;
|
|
1879
|
-
}
|
|
1880
|
-
if (line - 1 === lineEndIndex) {
|
|
1881
|
-
lineMarker = false; // useless because last line
|
|
1882
|
-
}
|
|
1883
|
-
let lineIndex = lineStartIndex;
|
|
1856
|
+
let cleanup;
|
|
1857
|
+
if (animated && ANSI.supported) {
|
|
1858
|
+
running = true;
|
|
1859
|
+
cleanup = effect();
|
|
1860
|
+
dynamicLog.update(update(render()));
|
|
1884
1861
|
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1862
|
+
interval = setInterval(() => {
|
|
1863
|
+
frameIndex = frameIndex === frames.length - 1 ? 0 : frameIndex + 1;
|
|
1864
|
+
dynamicLog.update(update(render()));
|
|
1865
|
+
}, 1000 / fps);
|
|
1866
|
+
if (!keepProcessAlive) {
|
|
1867
|
+
interval.unref();
|
|
1868
|
+
}
|
|
1890
1869
|
} else {
|
|
1891
|
-
|
|
1892
|
-
columnsAfter = lineMaxWidth;
|
|
1870
|
+
dynamicLog.update(update(render()));
|
|
1893
1871
|
}
|
|
1894
|
-
let columnMarkerIndex = column - 1 - columnsBefore;
|
|
1895
|
-
|
|
1896
|
-
let source = "";
|
|
1897
|
-
while (lineIndex <= lineEndIndex) {
|
|
1898
|
-
const lineString = lineStrings[lineIndex];
|
|
1899
|
-
const lineNumber = lineIndex + 1;
|
|
1900
|
-
const isLastLine = lineIndex === lineEndIndex;
|
|
1901
|
-
const isMainLine = lineNumber === line;
|
|
1902
|
-
lineIndex++;
|
|
1903
1872
|
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
source += " ";
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
if (lineNumbersOnTheLeft) {
|
|
1913
|
-
// fill with spaces to ensure if line moves from 7,8,9 to 10 the display is still great
|
|
1914
|
-
const asideSource = `${fillLeft(lineNumber, lineEndIndex + 1)} |`;
|
|
1915
|
-
source += `${format(asideSource, "line_number_aside")} `;
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
{
|
|
1919
|
-
source += truncateLine(lineString, {
|
|
1920
|
-
start: columnsBefore,
|
|
1921
|
-
end: columnsAfter,
|
|
1922
|
-
prefix: "…",
|
|
1923
|
-
suffix: "…",
|
|
1924
|
-
format,
|
|
1925
|
-
});
|
|
1873
|
+
const stop = (message) => {
|
|
1874
|
+
running = false;
|
|
1875
|
+
if (interval) {
|
|
1876
|
+
clearInterval(interval);
|
|
1877
|
+
interval = null;
|
|
1926
1878
|
}
|
|
1927
|
-
{
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
if (lineMarker) {
|
|
1931
|
-
source += " ";
|
|
1932
|
-
}
|
|
1933
|
-
if (lineNumbersOnTheLeft) {
|
|
1934
|
-
const asideSpaces = `${fillLeft(lineNumber, lineEndIndex + 1)} | `
|
|
1935
|
-
.length;
|
|
1936
|
-
source += " ".repeat(asideSpaces);
|
|
1937
|
-
}
|
|
1938
|
-
source += " ".repeat(columnMarkerIndex);
|
|
1939
|
-
source += format("^", "marker_column");
|
|
1940
|
-
}
|
|
1879
|
+
if (cleanup) {
|
|
1880
|
+
cleanup();
|
|
1881
|
+
cleanup = null;
|
|
1941
1882
|
}
|
|
1942
|
-
if (
|
|
1943
|
-
|
|
1883
|
+
if (dynamicLog && message) {
|
|
1884
|
+
dynamicLog.update(update(message));
|
|
1885
|
+
dynamicLog = null;
|
|
1944
1886
|
}
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
};
|
|
1948
|
-
|
|
1949
|
-
const truncateLine = (line, { start, end, prefix, suffix, format }) => {
|
|
1950
|
-
const lastIndex = line.length;
|
|
1951
|
-
|
|
1952
|
-
if (line.length === 0) {
|
|
1953
|
-
// don't show any ellipsis if the line is empty
|
|
1954
|
-
// because it's not truncated in that case
|
|
1955
|
-
return "";
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
const startTruncated = start > 0;
|
|
1959
|
-
const endTruncated = lastIndex > end;
|
|
1960
|
-
|
|
1961
|
-
let from = startTruncated ? start + prefix.length : start;
|
|
1962
|
-
let to = endTruncated ? end - suffix.length : end;
|
|
1963
|
-
if (to > lastIndex) to = lastIndex;
|
|
1887
|
+
};
|
|
1888
|
+
spinner.stop = stop;
|
|
1964
1889
|
|
|
1965
|
-
if (
|
|
1966
|
-
|
|
1967
|
-
}
|
|
1968
|
-
let result = "";
|
|
1969
|
-
while (from < to) {
|
|
1970
|
-
result += format(line[from], "char");
|
|
1971
|
-
from++;
|
|
1972
|
-
}
|
|
1973
|
-
if (result.length === 0) {
|
|
1974
|
-
return "";
|
|
1975
|
-
}
|
|
1976
|
-
if (startTruncated && endTruncated) {
|
|
1977
|
-
return `${format(prefix, "marker_overflow_left")}${result}${format(
|
|
1978
|
-
suffix,
|
|
1979
|
-
"marker_overflow_right",
|
|
1980
|
-
)}`;
|
|
1981
|
-
}
|
|
1982
|
-
if (startTruncated) {
|
|
1983
|
-
return `${format(prefix, "marker_overflow_left")}${result}`;
|
|
1890
|
+
if (stopOnVerticalOverflow) {
|
|
1891
|
+
dynamicLog.onVerticalOverflow = stop;
|
|
1984
1892
|
}
|
|
1985
|
-
if (
|
|
1986
|
-
|
|
1893
|
+
if (stopOnWriteFromOutside) {
|
|
1894
|
+
dynamicLog.onWriteFromOutside = stop;
|
|
1987
1895
|
}
|
|
1988
|
-
|
|
1896
|
+
|
|
1897
|
+
return spinner;
|
|
1989
1898
|
};
|
|
1990
1899
|
|
|
1991
|
-
const
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1900
|
+
const createTaskLog = (
|
|
1901
|
+
label,
|
|
1902
|
+
{ disabled = false, animated = true, stopOnWriteFromOutside } = {},
|
|
1903
|
+
) => {
|
|
1904
|
+
if (disabled) {
|
|
1905
|
+
return {
|
|
1906
|
+
setRightText: () => {},
|
|
1907
|
+
done: () => {},
|
|
1908
|
+
happen: () => {},
|
|
1909
|
+
fail: () => {},
|
|
1910
|
+
};
|
|
1998
1911
|
}
|
|
1999
|
-
|
|
2000
|
-
|
|
1912
|
+
const startMs = Date.now();
|
|
1913
|
+
const dynamicLog = createDynamicLog();
|
|
1914
|
+
let message = label;
|
|
1915
|
+
const taskSpinner = startSpinner({
|
|
1916
|
+
dynamicLog,
|
|
1917
|
+
render: () => message,
|
|
1918
|
+
stopOnWriteFromOutside,
|
|
1919
|
+
animated,
|
|
1920
|
+
});
|
|
1921
|
+
return {
|
|
1922
|
+
setRightText: (value) => {
|
|
1923
|
+
message = `${label} ${value}`;
|
|
1924
|
+
},
|
|
1925
|
+
done: () => {
|
|
1926
|
+
const msEllapsed = Date.now() - startMs;
|
|
1927
|
+
taskSpinner.stop(
|
|
1928
|
+
`${UNICODE.OK} ${label} (done in ${humanizeDuration(msEllapsed)})`,
|
|
1929
|
+
);
|
|
1930
|
+
},
|
|
1931
|
+
happen: (message) => {
|
|
1932
|
+
taskSpinner.stop(
|
|
1933
|
+
`${UNICODE.INFO} ${message} (at ${new Date().toLocaleTimeString()})`,
|
|
1934
|
+
);
|
|
1935
|
+
},
|
|
1936
|
+
fail: (message = `failed to ${label}`) => {
|
|
1937
|
+
taskSpinner.stop(`${UNICODE.FAILURE} ${message}`);
|
|
1938
|
+
},
|
|
1939
|
+
};
|
|
2001
1940
|
};
|
|
2002
1941
|
|
|
2003
|
-
export { ANSI, UNICODE, createDetailedMessage, createDynamicLog, createLogger, createTaskLog,
|
|
1942
|
+
export { ANSI, UNICODE, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, startSpinner };
|