@jsenv/humanize 1.3.1 → 1.5.0
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 +145 -16
- package/dist/node/jsenv_humanize_node.js +339 -22
- package/dist/node/jsenv_humanize_node_modules.js +709 -0
- package/package.json +6 -4
- package/src/ansi/ansi_runtime_agnostic.js +67 -9
- package/src/error/error_to_html.js +22 -0
- package/src/error/error_to_markdown.js +14 -0
- package/src/log/call_orderer.js +39 -0
- package/src/log/detailed_message.js +20 -8
- package/src/log/details.js +26 -0
- package/src/log/dynamic_log.js +4 -3
- package/src/log/section.js +50 -0
- package/src/main_browser.js +3 -0
- package/src/main_node.js +9 -1
- package/dist/node/js/vendors.js +0 -295
|
@@ -1,27 +1,73 @@
|
|
|
1
1
|
const createDetailedMessage = (message, details = {}) => {
|
|
2
|
-
let
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
return
|
|
2
|
+
let text = "".concat(message);
|
|
3
|
+
const namedSectionsText = renderNamedSections(details);
|
|
4
|
+
if (namedSectionsText) {
|
|
5
|
+
text += "\n".concat(namedSectionsText);
|
|
6
|
+
}
|
|
7
|
+
return text;
|
|
8
|
+
};
|
|
9
|
+
const renderNamedSections = namedSections => {
|
|
10
|
+
let text = "";
|
|
11
|
+
let keys = Object.keys(namedSections);
|
|
12
|
+
for (const key of keys) {
|
|
13
|
+
const isLastKey = key === keys[keys.length - 1];
|
|
14
|
+
const value = namedSections[key];
|
|
15
|
+
text += "--- ".concat(key, " ---\n").concat(Array.isArray(value) ? value.join("\n") : value);
|
|
16
|
+
if (!isLastKey) {
|
|
17
|
+
text += "\n";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return text;
|
|
8
21
|
};
|
|
9
22
|
|
|
10
23
|
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
11
24
|
// https://stackoverflow.com/a/75985833/2634179
|
|
12
25
|
const RESET = "\x1b[0m";
|
|
26
|
+
const RED = "red";
|
|
27
|
+
const GREEN = "green";
|
|
28
|
+
const YELLOW = "yellow";
|
|
29
|
+
const BLUE = "blue";
|
|
30
|
+
const MAGENTA = "magenta";
|
|
31
|
+
const CYAN = "cyan";
|
|
32
|
+
const GREY = "grey";
|
|
33
|
+
const WHITE = "white";
|
|
34
|
+
const BLACK = "black";
|
|
35
|
+
const TEXT_COLOR_ANSI_CODES = {
|
|
36
|
+
[RED]: "\x1b[31m",
|
|
37
|
+
[GREEN]: "\x1b[32m",
|
|
38
|
+
[YELLOW]: "\x1b[33m",
|
|
39
|
+
[BLUE]: "\x1b[34m",
|
|
40
|
+
[MAGENTA]: "\x1b[35m",
|
|
41
|
+
[CYAN]: "\x1b[36m",
|
|
42
|
+
[GREY]: "\x1b[90m",
|
|
43
|
+
[WHITE]: "\x1b[37m",
|
|
44
|
+
[BLACK]: "\x1b[30m"
|
|
45
|
+
};
|
|
46
|
+
const BACKGROUND_COLOR_ANSI_CODES = {
|
|
47
|
+
[RED]: "\x1b[41m",
|
|
48
|
+
[GREEN]: "\x1b[42m",
|
|
49
|
+
[YELLOW]: "\x1b[43m",
|
|
50
|
+
[BLUE]: "\x1b[44m",
|
|
51
|
+
[MAGENTA]: "\x1b[45m",
|
|
52
|
+
[CYAN]: "\x1b[46m",
|
|
53
|
+
[GREY]: "\x1b[100m",
|
|
54
|
+
[WHITE]: "\x1b[47m",
|
|
55
|
+
[BLACK]: "\x1b[40m"
|
|
56
|
+
};
|
|
13
57
|
const createAnsi = ({
|
|
14
58
|
supported
|
|
15
59
|
}) => {
|
|
16
60
|
const ANSI = {
|
|
17
61
|
supported,
|
|
18
|
-
RED
|
|
19
|
-
GREEN
|
|
20
|
-
YELLOW
|
|
21
|
-
BLUE
|
|
22
|
-
MAGENTA
|
|
23
|
-
CYAN
|
|
24
|
-
GREY
|
|
62
|
+
RED,
|
|
63
|
+
GREEN,
|
|
64
|
+
YELLOW,
|
|
65
|
+
BLUE,
|
|
66
|
+
MAGENTA,
|
|
67
|
+
CYAN,
|
|
68
|
+
GREY,
|
|
69
|
+
WHITE,
|
|
70
|
+
BLACK,
|
|
25
71
|
color: (text, color) => {
|
|
26
72
|
if (!ANSI.supported) {
|
|
27
73
|
return text;
|
|
@@ -33,7 +79,28 @@ const createAnsi = ({
|
|
|
33
79
|
// cannot set color of blank chars
|
|
34
80
|
return text;
|
|
35
81
|
}
|
|
36
|
-
|
|
82
|
+
const ansiEscapeCodeForTextColor = TEXT_COLOR_ANSI_CODES[color];
|
|
83
|
+
if (!ansiEscapeCodeForTextColor) {
|
|
84
|
+
return text;
|
|
85
|
+
}
|
|
86
|
+
return "".concat(ansiEscapeCodeForTextColor).concat(text).concat(RESET);
|
|
87
|
+
},
|
|
88
|
+
backgroundColor: (text, color) => {
|
|
89
|
+
if (!ANSI.supported) {
|
|
90
|
+
return text;
|
|
91
|
+
}
|
|
92
|
+
if (!color) {
|
|
93
|
+
return text;
|
|
94
|
+
}
|
|
95
|
+
if (typeof text === "string" && text.trim() === "") {
|
|
96
|
+
// cannot set background color of blank chars
|
|
97
|
+
return text;
|
|
98
|
+
}
|
|
99
|
+
const ansiEscapeCodeForBackgroundColor = BACKGROUND_COLOR_ANSI_CODES[color];
|
|
100
|
+
if (!ansiEscapeCodeForBackgroundColor) {
|
|
101
|
+
return text;
|
|
102
|
+
}
|
|
103
|
+
return "".concat(ansiEscapeCodeForBackgroundColor).concat(text).concat(RESET);
|
|
37
104
|
},
|
|
38
105
|
BOLD: "\x1b[1m",
|
|
39
106
|
UNDERLINE: "\x1b[4m",
|
|
@@ -49,7 +116,8 @@ const createAnsi = ({
|
|
|
49
116
|
if (text === "") {
|
|
50
117
|
return text;
|
|
51
118
|
}
|
|
52
|
-
|
|
119
|
+
const ansiEscapeCodeForEffect = effect;
|
|
120
|
+
return "".concat(ansiEscapeCodeForEffect).concat(text).concat(RESET);
|
|
53
121
|
}
|
|
54
122
|
};
|
|
55
123
|
return ANSI;
|
|
@@ -1272,4 +1340,65 @@ const fillLeft = (value, biggestValue, char = " ") => {
|
|
|
1272
1340
|
return padded;
|
|
1273
1341
|
};
|
|
1274
1342
|
|
|
1275
|
-
|
|
1343
|
+
const createCallOrderer = () => {
|
|
1344
|
+
const queue = [];
|
|
1345
|
+
const callWhenPreviousExecutionAreDone = (executionIndex, callback) => {
|
|
1346
|
+
if (queue[executionIndex]) {
|
|
1347
|
+
throw new Error("".concat(executionIndex, " already used"));
|
|
1348
|
+
}
|
|
1349
|
+
let allBeforeAreDone = true;
|
|
1350
|
+
if (executionIndex > 0) {
|
|
1351
|
+
let beforeIndex = executionIndex - 1;
|
|
1352
|
+
do {
|
|
1353
|
+
const value = queue[beforeIndex];
|
|
1354
|
+
if (!value) {
|
|
1355
|
+
allBeforeAreDone = false;
|
|
1356
|
+
break;
|
|
1357
|
+
}
|
|
1358
|
+
} while (beforeIndex--);
|
|
1359
|
+
}
|
|
1360
|
+
if (!allBeforeAreDone) {
|
|
1361
|
+
queue[executionIndex] = callback;
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1364
|
+
queue[executionIndex] = true;
|
|
1365
|
+
callback();
|
|
1366
|
+
let afterIndex = executionIndex + 1;
|
|
1367
|
+
while (afterIndex < queue.length) {
|
|
1368
|
+
const value = queue[afterIndex];
|
|
1369
|
+
if (value === undefined) {
|
|
1370
|
+
break;
|
|
1371
|
+
}
|
|
1372
|
+
if (typeof value === "function") {
|
|
1373
|
+
queue[afterIndex] = true;
|
|
1374
|
+
value();
|
|
1375
|
+
}
|
|
1376
|
+
afterIndex++;
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
return callWhenPreviousExecutionAreDone;
|
|
1380
|
+
};
|
|
1381
|
+
|
|
1382
|
+
const errorToMarkdown = error => {
|
|
1383
|
+
const errorIsAPrimitive = error === null || typeof error !== "object" && typeof error !== "function";
|
|
1384
|
+
if (errorIsAPrimitive) {
|
|
1385
|
+
return "```js\n".concat(error, "\n```");
|
|
1386
|
+
}
|
|
1387
|
+
return "```\n".concat(error.stack, "\n```");
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
const errorToHTML = error => {
|
|
1391
|
+
const errorIsAPrimitive = error === null || typeof error !== "object" && typeof error !== "function";
|
|
1392
|
+
if (errorIsAPrimitive) {
|
|
1393
|
+
if (typeof error === "string") {
|
|
1394
|
+
return "<pre>".concat(escapeHtml(error), "</pre>");
|
|
1395
|
+
}
|
|
1396
|
+
return "<pre>".concat(JSON.stringify(error, null, " "), "</pre>");
|
|
1397
|
+
}
|
|
1398
|
+
return "<pre>".concat(escapeHtml(error.stack), "</pre>");
|
|
1399
|
+
};
|
|
1400
|
+
const escapeHtml = string => {
|
|
1401
|
+
return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
export { ANSI, UNICODE, createCallOrderer, createDetailedMessage, distributePercentages, errorToHTML, errorToMarkdown, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol };
|
|
@@ -1,42 +1,89 @@
|
|
|
1
|
-
import { createSupportsColor, isUnicodeSupported, clearTerminal, eraseLines } from "./
|
|
2
|
-
import
|
|
1
|
+
import { createSupportsColor, isUnicodeSupported, stripAnsi, emojiRegex, eastAsianWidth, clearTerminal, eraseLines } from "./jsenv_humanize_node_modules.js";
|
|
2
|
+
import { stripVTControlCharacters } from "node:util";
|
|
3
3
|
import "node:process";
|
|
4
4
|
import "node:os";
|
|
5
5
|
import "node:tty";
|
|
6
6
|
|
|
7
7
|
const createDetailedMessage = (message, details = {}) => {
|
|
8
|
-
let
|
|
8
|
+
let text = `${message}`;
|
|
9
|
+
const namedSectionsText = renderNamedSections(details);
|
|
10
|
+
if (namedSectionsText) {
|
|
11
|
+
text += `
|
|
12
|
+
${namedSectionsText}`;
|
|
13
|
+
}
|
|
14
|
+
return text;
|
|
15
|
+
};
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
const renderNamedSections = (namedSections) => {
|
|
18
|
+
let text = "";
|
|
19
|
+
let keys = Object.keys(namedSections);
|
|
20
|
+
for (const key of keys) {
|
|
21
|
+
const isLastKey = key === keys[keys.length - 1];
|
|
22
|
+
const value = namedSections[key];
|
|
23
|
+
text += `--- ${key} ---
|
|
14
24
|
${
|
|
15
25
|
Array.isArray(value)
|
|
16
26
|
? value.join(`
|
|
17
27
|
`)
|
|
18
28
|
: value
|
|
19
29
|
}`;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
if (!isLastKey) {
|
|
31
|
+
text += "\n";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return text;
|
|
23
35
|
};
|
|
24
36
|
|
|
25
37
|
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
26
38
|
// https://stackoverflow.com/a/75985833/2634179
|
|
27
39
|
const RESET = "\x1b[0m";
|
|
28
40
|
|
|
41
|
+
const RED = "red";
|
|
42
|
+
const GREEN = "green";
|
|
43
|
+
const YELLOW = "yellow";
|
|
44
|
+
const BLUE = "blue";
|
|
45
|
+
const MAGENTA = "magenta";
|
|
46
|
+
const CYAN = "cyan";
|
|
47
|
+
const GREY = "grey";
|
|
48
|
+
const WHITE = "white";
|
|
49
|
+
const BLACK = "black";
|
|
50
|
+
|
|
51
|
+
const TEXT_COLOR_ANSI_CODES = {
|
|
52
|
+
[RED]: "\x1b[31m",
|
|
53
|
+
[GREEN]: "\x1b[32m",
|
|
54
|
+
[YELLOW]: "\x1b[33m",
|
|
55
|
+
[BLUE]: "\x1b[34m",
|
|
56
|
+
[MAGENTA]: "\x1b[35m",
|
|
57
|
+
[CYAN]: "\x1b[36m",
|
|
58
|
+
[GREY]: "\x1b[90m",
|
|
59
|
+
[WHITE]: "\x1b[37m",
|
|
60
|
+
[BLACK]: "\x1b[30m",
|
|
61
|
+
};
|
|
62
|
+
const BACKGROUND_COLOR_ANSI_CODES = {
|
|
63
|
+
[RED]: "\x1b[41m",
|
|
64
|
+
[GREEN]: "\x1b[42m",
|
|
65
|
+
[YELLOW]: "\x1b[43m",
|
|
66
|
+
[BLUE]: "\x1b[44m",
|
|
67
|
+
[MAGENTA]: "\x1b[45m",
|
|
68
|
+
[CYAN]: "\x1b[46m",
|
|
69
|
+
[GREY]: "\x1b[100m",
|
|
70
|
+
[WHITE]: "\x1b[47m",
|
|
71
|
+
[BLACK]: "\x1b[40m",
|
|
72
|
+
};
|
|
73
|
+
|
|
29
74
|
const createAnsi = ({ supported }) => {
|
|
30
75
|
const ANSI = {
|
|
31
76
|
supported,
|
|
32
77
|
|
|
33
|
-
RED
|
|
34
|
-
GREEN
|
|
35
|
-
YELLOW
|
|
36
|
-
BLUE
|
|
37
|
-
MAGENTA
|
|
38
|
-
CYAN
|
|
39
|
-
GREY
|
|
78
|
+
RED,
|
|
79
|
+
GREEN,
|
|
80
|
+
YELLOW,
|
|
81
|
+
BLUE,
|
|
82
|
+
MAGENTA,
|
|
83
|
+
CYAN,
|
|
84
|
+
GREY,
|
|
85
|
+
WHITE,
|
|
86
|
+
BLACK,
|
|
40
87
|
color: (text, color) => {
|
|
41
88
|
if (!ANSI.supported) {
|
|
42
89
|
return text;
|
|
@@ -48,7 +95,29 @@ const createAnsi = ({ supported }) => {
|
|
|
48
95
|
// cannot set color of blank chars
|
|
49
96
|
return text;
|
|
50
97
|
}
|
|
51
|
-
|
|
98
|
+
const ansiEscapeCodeForTextColor = TEXT_COLOR_ANSI_CODES[color];
|
|
99
|
+
if (!ansiEscapeCodeForTextColor) {
|
|
100
|
+
return text;
|
|
101
|
+
}
|
|
102
|
+
return `${ansiEscapeCodeForTextColor}${text}${RESET}`;
|
|
103
|
+
},
|
|
104
|
+
backgroundColor: (text, color) => {
|
|
105
|
+
if (!ANSI.supported) {
|
|
106
|
+
return text;
|
|
107
|
+
}
|
|
108
|
+
if (!color) {
|
|
109
|
+
return text;
|
|
110
|
+
}
|
|
111
|
+
if (typeof text === "string" && text.trim() === "") {
|
|
112
|
+
// cannot set background color of blank chars
|
|
113
|
+
return text;
|
|
114
|
+
}
|
|
115
|
+
const ansiEscapeCodeForBackgroundColor =
|
|
116
|
+
BACKGROUND_COLOR_ANSI_CODES[color];
|
|
117
|
+
if (!ansiEscapeCodeForBackgroundColor) {
|
|
118
|
+
return text;
|
|
119
|
+
}
|
|
120
|
+
return `${ansiEscapeCodeForBackgroundColor}${text}${RESET}`;
|
|
52
121
|
},
|
|
53
122
|
|
|
54
123
|
BOLD: "\x1b[1m",
|
|
@@ -65,7 +134,8 @@ const createAnsi = ({ supported }) => {
|
|
|
65
134
|
if (text === "") {
|
|
66
135
|
return text;
|
|
67
136
|
}
|
|
68
|
-
|
|
137
|
+
const ansiEscapeCodeForEffect = effect;
|
|
138
|
+
return `${ansiEscapeCodeForEffect}${text}${RESET}`;
|
|
69
139
|
},
|
|
70
140
|
};
|
|
71
141
|
|
|
@@ -1297,6 +1367,157 @@ const fillLeft = (value, biggestValue, char = " ") => {
|
|
|
1297
1367
|
return padded;
|
|
1298
1368
|
};
|
|
1299
1369
|
|
|
1370
|
+
const createCallOrderer = () => {
|
|
1371
|
+
const queue = [];
|
|
1372
|
+
const callWhenPreviousExecutionAreDone = (executionIndex, callback) => {
|
|
1373
|
+
if (queue[executionIndex]) {
|
|
1374
|
+
throw new Error(`${executionIndex} already used`);
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
let allBeforeAreDone = true;
|
|
1378
|
+
if (executionIndex > 0) {
|
|
1379
|
+
let beforeIndex = executionIndex - 1;
|
|
1380
|
+
do {
|
|
1381
|
+
const value = queue[beforeIndex];
|
|
1382
|
+
if (!value) {
|
|
1383
|
+
allBeforeAreDone = false;
|
|
1384
|
+
break;
|
|
1385
|
+
}
|
|
1386
|
+
} while (beforeIndex--);
|
|
1387
|
+
}
|
|
1388
|
+
if (!allBeforeAreDone) {
|
|
1389
|
+
queue[executionIndex] = callback;
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
queue[executionIndex] = true;
|
|
1393
|
+
callback();
|
|
1394
|
+
let afterIndex = executionIndex + 1;
|
|
1395
|
+
while (afterIndex < queue.length) {
|
|
1396
|
+
const value = queue[afterIndex];
|
|
1397
|
+
if (value === undefined) {
|
|
1398
|
+
break;
|
|
1399
|
+
}
|
|
1400
|
+
if (typeof value === "function") {
|
|
1401
|
+
queue[afterIndex] = true;
|
|
1402
|
+
value();
|
|
1403
|
+
}
|
|
1404
|
+
afterIndex++;
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
return callWhenPreviousExecutionAreDone;
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
const errorToMarkdown = (error) => {
|
|
1411
|
+
const errorIsAPrimitive =
|
|
1412
|
+
error === null ||
|
|
1413
|
+
(typeof error !== "object" && typeof error !== "function");
|
|
1414
|
+
|
|
1415
|
+
if (errorIsAPrimitive) {
|
|
1416
|
+
return `\`\`\`js
|
|
1417
|
+
${error}
|
|
1418
|
+
\`\`\``;
|
|
1419
|
+
}
|
|
1420
|
+
return `\`\`\`
|
|
1421
|
+
${error.stack}
|
|
1422
|
+
\`\`\``;
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
const errorToHTML = (error) => {
|
|
1426
|
+
const errorIsAPrimitive =
|
|
1427
|
+
error === null ||
|
|
1428
|
+
(typeof error !== "object" && typeof error !== "function");
|
|
1429
|
+
|
|
1430
|
+
if (errorIsAPrimitive) {
|
|
1431
|
+
if (typeof error === "string") {
|
|
1432
|
+
return `<pre>${escapeHtml(error)}</pre>`;
|
|
1433
|
+
}
|
|
1434
|
+
return `<pre>${JSON.stringify(error, null, " ")}</pre>`;
|
|
1435
|
+
}
|
|
1436
|
+
return `<pre>${escapeHtml(error.stack)}</pre>`;
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1439
|
+
const escapeHtml = (string) => {
|
|
1440
|
+
return string
|
|
1441
|
+
.replace(/&/g, "&")
|
|
1442
|
+
.replace(/</g, "<")
|
|
1443
|
+
.replace(/>/g, ">")
|
|
1444
|
+
.replace(/"/g, """)
|
|
1445
|
+
.replace(/'/g, "'");
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1448
|
+
const renderBigSection = (params) => {
|
|
1449
|
+
return renderSection({
|
|
1450
|
+
width: 45,
|
|
1451
|
+
...params,
|
|
1452
|
+
});
|
|
1453
|
+
};
|
|
1454
|
+
|
|
1455
|
+
const renderSection = ({
|
|
1456
|
+
title,
|
|
1457
|
+
content,
|
|
1458
|
+
dashColor = ANSI.GREY,
|
|
1459
|
+
width = 38,
|
|
1460
|
+
bottomSeparator = true,
|
|
1461
|
+
}) => {
|
|
1462
|
+
let section = "";
|
|
1463
|
+
|
|
1464
|
+
if (title) {
|
|
1465
|
+
const titleWidth = stripAnsi(title).length;
|
|
1466
|
+
const minWidthRequired = `--- … ---`.length;
|
|
1467
|
+
const needsTruncate = titleWidth + minWidthRequired >= width;
|
|
1468
|
+
if (needsTruncate) {
|
|
1469
|
+
const titleTruncated = title.slice(0, width - minWidthRequired);
|
|
1470
|
+
const leftDashes = ANSI.color("---", dashColor);
|
|
1471
|
+
const rightDashes = ANSI.color("---", dashColor);
|
|
1472
|
+
section += `${leftDashes} ${titleTruncated}… ${rightDashes}`;
|
|
1473
|
+
} else {
|
|
1474
|
+
const remainingWidth = width - titleWidth - 2; // 2 for spaces around the title
|
|
1475
|
+
const dashLeftCount = Math.floor(remainingWidth / 2);
|
|
1476
|
+
const dashRightCount = remainingWidth - dashLeftCount;
|
|
1477
|
+
const leftDashes = ANSI.color("-".repeat(dashLeftCount), dashColor);
|
|
1478
|
+
const rightDashes = ANSI.color("-".repeat(dashRightCount), dashColor);
|
|
1479
|
+
section += `${leftDashes} ${title} ${rightDashes}`;
|
|
1480
|
+
}
|
|
1481
|
+
section += "\n";
|
|
1482
|
+
} else {
|
|
1483
|
+
const topDashes = ANSI.color(`-`.repeat(width), dashColor);
|
|
1484
|
+
section += topDashes;
|
|
1485
|
+
section += "\n";
|
|
1486
|
+
}
|
|
1487
|
+
section += `${content}`;
|
|
1488
|
+
if (bottomSeparator) {
|
|
1489
|
+
section += "\n";
|
|
1490
|
+
const bottomDashes = ANSI.color(`-`.repeat(width), dashColor);
|
|
1491
|
+
section += bottomDashes;
|
|
1492
|
+
}
|
|
1493
|
+
return section;
|
|
1494
|
+
};
|
|
1495
|
+
|
|
1496
|
+
const renderDetails = (data) => {
|
|
1497
|
+
const details = [];
|
|
1498
|
+
for (const key of Object.keys(data)) {
|
|
1499
|
+
const value = data[key];
|
|
1500
|
+
let valueString = "";
|
|
1501
|
+
valueString += ANSI.color(`${key}:`, ANSI.GREY);
|
|
1502
|
+
const useNonGreyAnsiColor =
|
|
1503
|
+
typeof value === "string" && value.includes("\x1b");
|
|
1504
|
+
valueString += " ";
|
|
1505
|
+
valueString += useNonGreyAnsiColor
|
|
1506
|
+
? value
|
|
1507
|
+
: ANSI.color(String(value), ANSI.GREY);
|
|
1508
|
+
details.push(valueString);
|
|
1509
|
+
}
|
|
1510
|
+
if (details.length === 0) {
|
|
1511
|
+
return "";
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
let string = "";
|
|
1515
|
+
string += ` ${ANSI.color("(", ANSI.GREY)}`;
|
|
1516
|
+
string += details.join(ANSI.color(", ", ANSI.GREY));
|
|
1517
|
+
string += ANSI.color(")", ANSI.GREY);
|
|
1518
|
+
return string;
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1300
1521
|
const LOG_LEVEL_OFF = "off";
|
|
1301
1522
|
|
|
1302
1523
|
const LOG_LEVEL_DEBUG = "debug";
|
|
@@ -1385,6 +1606,101 @@ const error = (...args) => console.error(...args);
|
|
|
1385
1606
|
|
|
1386
1607
|
const errorDisabled = () => {};
|
|
1387
1608
|
|
|
1609
|
+
const createMeasureTextWidth = ({ stripAnsi }) => {
|
|
1610
|
+
const segmenter = new Intl.Segmenter();
|
|
1611
|
+
const defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
1612
|
+
|
|
1613
|
+
const measureTextWidth = (
|
|
1614
|
+
string,
|
|
1615
|
+
{
|
|
1616
|
+
ambiguousIsNarrow = true,
|
|
1617
|
+
countAnsiEscapeCodes = false,
|
|
1618
|
+
skipEmojis = false,
|
|
1619
|
+
} = {},
|
|
1620
|
+
) => {
|
|
1621
|
+
if (typeof string !== "string" || string.length === 0) {
|
|
1622
|
+
return 0;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
if (!countAnsiEscapeCodes) {
|
|
1626
|
+
string = stripAnsi(string);
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
if (string.length === 0) {
|
|
1630
|
+
return 0;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
let width = 0;
|
|
1634
|
+
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
1635
|
+
|
|
1636
|
+
for (const { segment: character } of segmenter.segment(string)) {
|
|
1637
|
+
const codePoint = character.codePointAt(0);
|
|
1638
|
+
|
|
1639
|
+
// Ignore control characters
|
|
1640
|
+
if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) {
|
|
1641
|
+
continue;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// Ignore zero-width characters
|
|
1645
|
+
if (
|
|
1646
|
+
(codePoint >= 0x20_0b && codePoint <= 0x20_0f) || // Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark
|
|
1647
|
+
codePoint === 0xfe_ff // Zero-width no-break space
|
|
1648
|
+
) {
|
|
1649
|
+
continue;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
// Ignore combining characters
|
|
1653
|
+
if (
|
|
1654
|
+
(codePoint >= 0x3_00 && codePoint <= 0x3_6f) || // Combining diacritical marks
|
|
1655
|
+
(codePoint >= 0x1a_b0 && codePoint <= 0x1a_ff) || // Combining diacritical marks extended
|
|
1656
|
+
(codePoint >= 0x1d_c0 && codePoint <= 0x1d_ff) || // Combining diacritical marks supplement
|
|
1657
|
+
(codePoint >= 0x20_d0 && codePoint <= 0x20_ff) || // Combining diacritical marks for symbols
|
|
1658
|
+
(codePoint >= 0xfe_20 && codePoint <= 0xfe_2f) // Combining half marks
|
|
1659
|
+
) {
|
|
1660
|
+
continue;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
// Ignore surrogate pairs
|
|
1664
|
+
if (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) {
|
|
1665
|
+
continue;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
// Ignore variation selectors
|
|
1669
|
+
if (codePoint >= 0xfe_00 && codePoint <= 0xfe_0f) {
|
|
1670
|
+
continue;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
// This covers some of the above cases, but we still keep them for performance reasons.
|
|
1674
|
+
if (defaultIgnorableCodePointRegex.test(character)) {
|
|
1675
|
+
continue;
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
if (!skipEmojis && emojiRegex().test(character)) {
|
|
1679
|
+
if (process.env.CAPTURING_SIDE_EFFECTS) {
|
|
1680
|
+
if (character === "✔️") {
|
|
1681
|
+
width += 2;
|
|
1682
|
+
continue;
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
width += measureTextWidth(character, {
|
|
1686
|
+
skipEmojis: true,
|
|
1687
|
+
countAnsiEscapeCodes: true, // to skip call to stripAnsi
|
|
1688
|
+
});
|
|
1689
|
+
continue;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
return width;
|
|
1696
|
+
};
|
|
1697
|
+
return measureTextWidth;
|
|
1698
|
+
};
|
|
1699
|
+
|
|
1700
|
+
const measureTextWidth = createMeasureTextWidth({
|
|
1701
|
+
stripAnsi: stripVTControlCharacters,
|
|
1702
|
+
});
|
|
1703
|
+
|
|
1388
1704
|
/*
|
|
1389
1705
|
* see also https://github.com/vadimdemedes/ink
|
|
1390
1706
|
*/
|
|
@@ -1420,7 +1736,7 @@ const createDynamicLog = ({
|
|
|
1420
1736
|
const logLines = lastOutput.split(/\r\n|\r|\n/);
|
|
1421
1737
|
let visualLineCount = 0;
|
|
1422
1738
|
for (const logLine of logLines) {
|
|
1423
|
-
const width =
|
|
1739
|
+
const width = measureTextWidth(logLine);
|
|
1424
1740
|
if (width === 0) {
|
|
1425
1741
|
visualLineCount++;
|
|
1426
1742
|
} else {
|
|
@@ -1485,7 +1801,8 @@ const createDynamicLog = ({
|
|
|
1485
1801
|
update("");
|
|
1486
1802
|
|
|
1487
1803
|
writing = true;
|
|
1488
|
-
callback();
|
|
1804
|
+
callback(update);
|
|
1805
|
+
lastOutput = "";
|
|
1489
1806
|
writing = false;
|
|
1490
1807
|
|
|
1491
1808
|
update(ouputAfterCallback);
|
|
@@ -1685,4 +2002,4 @@ const createTaskLog = (
|
|
|
1685
2002
|
};
|
|
1686
2003
|
};
|
|
1687
2004
|
|
|
1688
|
-
export { ANSI, UNICODE, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, startSpinner };
|
|
2005
|
+
export { ANSI, UNICODE, createCallOrderer, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, distributePercentages, errorToHTML, errorToMarkdown, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, renderBigSection, renderDetails, renderNamedSections, renderSection, startSpinner };
|