@jsenv/humanize 1.4.0 → 1.5.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 +23 -1
- package/dist/node/jsenv_humanize_node.js +44 -4
- package/dist/node/jsenv_humanize_node_modules.js +1 -106
- package/package.json +4 -2
- package/src/error/error_to_html.js +22 -0
- package/src/error/error_to_markdown.js +14 -0
- package/src/main_browser.js +2 -0
- package/src/main_node.js +2 -0
|
@@ -1379,4 +1379,26 @@ const createCallOrderer = () => {
|
|
|
1379
1379
|
return callWhenPreviousExecutionAreDone;
|
|
1380
1380
|
};
|
|
1381
1381
|
|
|
1382
|
-
|
|
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,5 +1,7 @@
|
|
|
1
|
-
import { createSupportsColor, isUnicodeSupported,
|
|
1
|
+
import { createSupportsColor, isUnicodeSupported, emojiRegex, eastAsianWidth } from "./jsenv_humanize_node_modules.js";
|
|
2
|
+
import stripAnsi from "strip-ansi";
|
|
2
3
|
import { stripVTControlCharacters } from "node:util";
|
|
4
|
+
import ansiEscapes from "ansi-escapes";
|
|
3
5
|
import "node:process";
|
|
4
6
|
import "node:os";
|
|
5
7
|
import "node:tty";
|
|
@@ -1407,6 +1409,44 @@ const createCallOrderer = () => {
|
|
|
1407
1409
|
return callWhenPreviousExecutionAreDone;
|
|
1408
1410
|
};
|
|
1409
1411
|
|
|
1412
|
+
const errorToMarkdown = (error) => {
|
|
1413
|
+
const errorIsAPrimitive =
|
|
1414
|
+
error === null ||
|
|
1415
|
+
(typeof error !== "object" && typeof error !== "function");
|
|
1416
|
+
|
|
1417
|
+
if (errorIsAPrimitive) {
|
|
1418
|
+
return `\`\`\`js
|
|
1419
|
+
${error}
|
|
1420
|
+
\`\`\``;
|
|
1421
|
+
}
|
|
1422
|
+
return `\`\`\`
|
|
1423
|
+
${error.stack}
|
|
1424
|
+
\`\`\``;
|
|
1425
|
+
};
|
|
1426
|
+
|
|
1427
|
+
const errorToHTML = (error) => {
|
|
1428
|
+
const errorIsAPrimitive =
|
|
1429
|
+
error === null ||
|
|
1430
|
+
(typeof error !== "object" && typeof error !== "function");
|
|
1431
|
+
|
|
1432
|
+
if (errorIsAPrimitive) {
|
|
1433
|
+
if (typeof error === "string") {
|
|
1434
|
+
return `<pre>${escapeHtml(error)}</pre>`;
|
|
1435
|
+
}
|
|
1436
|
+
return `<pre>${JSON.stringify(error, null, " ")}</pre>`;
|
|
1437
|
+
}
|
|
1438
|
+
return `<pre>${escapeHtml(error.stack)}</pre>`;
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1441
|
+
const escapeHtml = (string) => {
|
|
1442
|
+
return string
|
|
1443
|
+
.replace(/&/g, "&")
|
|
1444
|
+
.replace(/</g, "<")
|
|
1445
|
+
.replace(/>/g, ">")
|
|
1446
|
+
.replace(/"/g, """)
|
|
1447
|
+
.replace(/'/g, "'");
|
|
1448
|
+
};
|
|
1449
|
+
|
|
1410
1450
|
const renderBigSection = (params) => {
|
|
1411
1451
|
return renderSection({
|
|
1412
1452
|
width: 45,
|
|
@@ -1709,7 +1749,7 @@ const createDynamicLog = ({
|
|
|
1709
1749
|
if (visualLineCount > rows) {
|
|
1710
1750
|
if (clearTerminalAllowed) {
|
|
1711
1751
|
clearAttemptResult = true;
|
|
1712
|
-
return clearTerminal;
|
|
1752
|
+
return ansiEscapes.clearTerminal;
|
|
1713
1753
|
}
|
|
1714
1754
|
// the whole log cannot be cleared because it's vertically to long
|
|
1715
1755
|
// (longer than terminal height)
|
|
@@ -1722,7 +1762,7 @@ const createDynamicLog = ({
|
|
|
1722
1762
|
}
|
|
1723
1763
|
|
|
1724
1764
|
clearAttemptResult = true;
|
|
1725
|
-
return eraseLines(visualLineCount);
|
|
1765
|
+
return ansiEscapes.eraseLines(visualLineCount);
|
|
1726
1766
|
};
|
|
1727
1767
|
|
|
1728
1768
|
const update = (string) => {
|
|
@@ -1964,4 +2004,4 @@ const createTaskLog = (
|
|
|
1964
2004
|
};
|
|
1965
2005
|
};
|
|
1966
2006
|
|
|
1967
|
-
export { ANSI, UNICODE, createCallOrderer, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, renderBigSection, renderDetails, renderNamedSections, renderSection, startSpinner };
|
|
2007
|
+
export { ANSI, UNICODE, createCallOrderer, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, distributePercentages, errorToHTML, errorToMarkdown, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, renderBigSection, renderDetails, renderNamedSections, renderSection, startSpinner };
|
|
@@ -211,30 +211,6 @@ function isUnicodeSupported() {
|
|
|
211
211
|
|| env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
function ansiRegex({onlyFirst = false} = {}) {
|
|
215
|
-
// Valid string terminator sequences are BEL, ESC\, and 0x9c
|
|
216
|
-
const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
|
|
217
|
-
const pattern = [
|
|
218
|
-
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
|
|
219
|
-
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
|
|
220
|
-
].join('|');
|
|
221
|
-
|
|
222
|
-
return new RegExp(pattern, onlyFirst ? undefined : 'g');
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const regex = ansiRegex();
|
|
226
|
-
|
|
227
|
-
function stripAnsi(string) {
|
|
228
|
-
if (typeof string !== 'string') {
|
|
229
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Even though the regex is global, we don't need to reset the `.lastIndex`
|
|
233
|
-
// because unlike `.exec()` and `.test()`, `.replace()` does it automatically
|
|
234
|
-
// and doing it manually has a performance penalty.
|
|
235
|
-
return string.replace(regex, '');
|
|
236
|
-
}
|
|
237
|
-
|
|
238
214
|
const r = String.raw;
|
|
239
215
|
const seq = r`(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})`;
|
|
240
216
|
const sTags = r`\u{E0061}-\u{E007A}`;
|
|
@@ -625,85 +601,4 @@ function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {
|
|
|
625
601
|
return 1;
|
|
626
602
|
}
|
|
627
603
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
const isBrowser = globalThis.window?.document !== undefined;
|
|
631
|
-
|
|
632
|
-
globalThis.process?.versions?.node !== undefined;
|
|
633
|
-
|
|
634
|
-
globalThis.process?.versions?.bun !== undefined;
|
|
635
|
-
|
|
636
|
-
globalThis.Deno?.version?.deno !== undefined;
|
|
637
|
-
|
|
638
|
-
globalThis.process?.versions?.electron !== undefined;
|
|
639
|
-
|
|
640
|
-
globalThis.navigator?.userAgent?.includes('jsdom') === true;
|
|
641
|
-
|
|
642
|
-
typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
|
|
643
|
-
|
|
644
|
-
typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
645
|
-
|
|
646
|
-
typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
|
|
647
|
-
|
|
648
|
-
typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
|
|
649
|
-
|
|
650
|
-
// Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
|
|
651
|
-
const platform = globalThis.navigator?.userAgentData?.platform;
|
|
652
|
-
|
|
653
|
-
platform === 'macOS'
|
|
654
|
-
|| globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
|
|
655
|
-
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|
|
656
|
-
|| globalThis.process?.platform === 'darwin';
|
|
657
|
-
|
|
658
|
-
platform === 'Windows'
|
|
659
|
-
|| globalThis.navigator?.platform === 'Win32'
|
|
660
|
-
|| globalThis.process?.platform === 'win32';
|
|
661
|
-
|
|
662
|
-
platform === 'Linux'
|
|
663
|
-
|| globalThis.navigator?.platform?.startsWith('Linux') === true
|
|
664
|
-
|| globalThis.navigator?.userAgent?.includes(' Linux ') === true
|
|
665
|
-
|| globalThis.process?.platform === 'linux';
|
|
666
|
-
|
|
667
|
-
platform === 'Android'
|
|
668
|
-
|| globalThis.navigator?.platform === 'Android'
|
|
669
|
-
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|
|
670
|
-
|| globalThis.process?.platform === 'android';
|
|
671
|
-
|
|
672
|
-
const ESC = '\u001B[';
|
|
673
|
-
|
|
674
|
-
!isBrowser && process.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
675
|
-
const isWindows = !isBrowser && process.platform === 'win32';
|
|
676
|
-
|
|
677
|
-
isBrowser ? () => {
|
|
678
|
-
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
679
|
-
} : process.cwd;
|
|
680
|
-
|
|
681
|
-
const cursorUp = (count = 1) => ESC + count + 'A';
|
|
682
|
-
|
|
683
|
-
const cursorLeft = ESC + 'G';
|
|
684
|
-
|
|
685
|
-
const eraseLines = count => {
|
|
686
|
-
let clear = '';
|
|
687
|
-
|
|
688
|
-
for (let i = 0; i < count; i++) {
|
|
689
|
-
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
if (count) {
|
|
693
|
-
clear += cursorLeft;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
return clear;
|
|
697
|
-
};
|
|
698
|
-
const eraseLine = ESC + '2K';
|
|
699
|
-
const eraseScreen = ESC + '2J';
|
|
700
|
-
|
|
701
|
-
const clearTerminal = isWindows
|
|
702
|
-
? `${eraseScreen}${ESC}0f`
|
|
703
|
-
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
704
|
-
// 2. Erases the whole screen including scrollback buffer
|
|
705
|
-
// 3. Moves cursor to the top-left position
|
|
706
|
-
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
707
|
-
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
708
|
-
|
|
709
|
-
export { clearTerminal, createSupportsColor, eastAsianWidth, emojiRegex, eraseLines, isUnicodeSupported, stripAnsi };
|
|
604
|
+
export { createSupportsColor, eastAsianWidth, emojiRegex, isUnicodeSupported };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/humanize",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Generate messages meant to read by humans",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"/dist/",
|
|
33
33
|
"/src/"
|
|
34
34
|
],
|
|
35
|
-
"sideEffects":
|
|
35
|
+
"sideEffects": [
|
|
36
|
+
"./dist/node/jsenv_humanize_node_modules.js"
|
|
37
|
+
],
|
|
36
38
|
"scripts": {
|
|
37
39
|
"build": "node ./scripts/build.mjs",
|
|
38
40
|
"prepublishOnly": "npm run build"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const errorToHTML = (error) => {
|
|
2
|
+
const errorIsAPrimitive =
|
|
3
|
+
error === null ||
|
|
4
|
+
(typeof error !== "object" && typeof error !== "function");
|
|
5
|
+
|
|
6
|
+
if (errorIsAPrimitive) {
|
|
7
|
+
if (typeof error === "string") {
|
|
8
|
+
return `<pre>${escapeHtml(error)}</pre>`;
|
|
9
|
+
}
|
|
10
|
+
return `<pre>${JSON.stringify(error, null, " ")}</pre>`;
|
|
11
|
+
}
|
|
12
|
+
return `<pre>${escapeHtml(error.stack)}</pre>`;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const escapeHtml = (string) => {
|
|
16
|
+
return string
|
|
17
|
+
.replace(/&/g, "&")
|
|
18
|
+
.replace(/</g, "<")
|
|
19
|
+
.replace(/>/g, ">")
|
|
20
|
+
.replace(/"/g, """)
|
|
21
|
+
.replace(/'/g, "'");
|
|
22
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const errorToMarkdown = (error) => {
|
|
2
|
+
const errorIsAPrimitive =
|
|
3
|
+
error === null ||
|
|
4
|
+
(typeof error !== "object" && typeof error !== "function");
|
|
5
|
+
|
|
6
|
+
if (errorIsAPrimitive) {
|
|
7
|
+
return `\`\`\`js
|
|
8
|
+
${error}
|
|
9
|
+
\`\`\``;
|
|
10
|
+
}
|
|
11
|
+
return `\`\`\`
|
|
12
|
+
${error.stack}
|
|
13
|
+
\`\`\``;
|
|
14
|
+
};
|
package/src/main_browser.js
CHANGED
|
@@ -9,3 +9,5 @@ export { humanizeFileSize, humanizeMemory } from "./byte/byte.js";
|
|
|
9
9
|
export { distributePercentages } from "./percentage/distribute_percentages.js";
|
|
10
10
|
export { generateContentFrame } from "./content_frame/content_frame.js";
|
|
11
11
|
export { createCallOrderer } from "./log/call_orderer.js";
|
|
12
|
+
export { errorToMarkdown } from "./error/error_to_markdown.js";
|
|
13
|
+
export { errorToHTML } from "./error/error_to_html.js";
|
package/src/main_node.js
CHANGED
|
@@ -12,6 +12,8 @@ export { humanizeFileSize, humanizeMemory } from "./byte/byte.js";
|
|
|
12
12
|
export { distributePercentages } from "./percentage/distribute_percentages.js";
|
|
13
13
|
export { generateContentFrame } from "./content_frame/content_frame.js";
|
|
14
14
|
export { createCallOrderer } from "./log/call_orderer.js";
|
|
15
|
+
export { errorToMarkdown } from "./error/error_to_markdown.js";
|
|
16
|
+
export { errorToHTML } from "./error/error_to_html.js";
|
|
15
17
|
|
|
16
18
|
// node only
|
|
17
19
|
export { renderSection, renderBigSection } from "./log/section.js";
|