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