@jsenv/humanize 1.0.0 → 1.1.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/README.md +25 -10
- package/dist/browser/jsenv_humanize_browser.js +76 -2
- package/dist/node/jsenv_humanize_node.js +73 -147
- package/package.json +3 -3
- package/src/.jsenv/jsenv_tests_output.txt +26 -29
- package/src/_tests/byte/file_size.test.js +2 -2
- package/src/_tests/byte/memory.test.js +11 -0
- package/src/_tests/js_value/array.test.js +14 -14
- package/src/_tests/js_value/biginit.test.js +10 -10
- package/src/_tests/js_value/boolean.test.js +12 -12
- package/src/_tests/js_value/date.test.js +4 -4
- package/src/_tests/js_value/error.test.js +8 -8
- package/src/_tests/js_value/function.test.js +12 -12
- package/src/_tests/js_value/instance.test.js +2 -2
- package/src/_tests/js_value/null.test.js +2 -2
- package/src/_tests/js_value/number.test.js +54 -54
- package/src/_tests/js_value/object.test.js +34 -34
- package/src/_tests/js_value/regexp.test.js +4 -4
- package/src/_tests/js_value/string.test.js +32 -32
- package/src/_tests/js_value/symbol.test.js +6 -6
- package/src/_tests/js_value/undefined.test.js +2 -2
- package/src/_tests/log/logger.test.mjs +14 -14
- package/src/_tests/log/spinner.test.mjs +6 -6
- package/src/_tests/percentage/percentage_distribution.test.mjs +2 -2
- package/src/_tests/time/decimals.test.js +40 -40
- package/src/_tests/time/duration.test.js +2 -2
- package/src/_tests/time/ellapsed.test.js +2 -2
- package/src/byte/byte.js +1 -1
- package/src/js_value/humanize.js +1 -1
- package/src/log/ansi_browser.js +27 -0
- package/src/log/{ansi.js → ansi_node.js} +7 -2
- package/src/log/dynamic_log.js +6 -4
- package/src/log/spinner.js +1 -1
- package/src/log/task_log.js +1 -1
- package/src/log/unicode_browser.js +53 -0
- package/src/log/{unicode.js → unicode_node.js} +4 -1
- package/src/main_browser.js +4 -1
- package/src/main_node.js +3 -3
- package/src/_tests/byte/memory_usage.test.js +0 -11
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# humanize [](https://www.npmjs.com/package/@jsenv/humanize)
|
|
2
2
|
|
|
3
|
-
`@jsenv/humanize`
|
|
3
|
+
`@jsenv/humanize` helps to generate messages meant to be read by humans
|
|
4
|
+
|
|
5
|
+
It is written in ES6 and compatible with browsers and Node.js.
|
|
6
|
+
|
|
7
|
+
# API
|
|
8
|
+
|
|
9
|
+
## humanize(jsValue)
|
|
10
|
+
|
|
11
|
+
Turns a JavaScript value into a string meant to be read by a human.
|
|
4
12
|
|
|
5
13
|
```js
|
|
6
14
|
import { humanize } from "@jsenv/humanize";
|
|
@@ -15,7 +23,6 @@ console.log(
|
|
|
15
23
|
```
|
|
16
24
|
|
|
17
25
|
```console
|
|
18
|
-
❯ node ./docs/demo.mjs
|
|
19
26
|
{
|
|
20
27
|
"boolean": true,
|
|
21
28
|
"number": 10,
|
|
@@ -23,13 +30,21 @@ console.log(
|
|
|
23
30
|
}
|
|
24
31
|
```
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
### Comparison with JSON.stringify
|
|
34
|
+
|
|
35
|
+
Table comparing `JSON.stringify` and `humanize()` to demonstrates how inspect focuses on readability and accuracy.
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
| value | JSON.stringify | humanize |
|
|
38
|
+
| --------- | -------------- | ----------- |
|
|
39
|
+
| 123456789 | "123456789" | 123_456_789 |
|
|
40
|
+
| Infinity | "null" | Infinity |
|
|
41
|
+
| -0 | "0" | -0 |
|
|
42
|
+
| '"' | '"\\""' | '"' |
|
|
29
43
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
## humanizeDuration(ms, options)
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
import { humanizeDuration } from "@jsenv/humanize";
|
|
48
|
+
|
|
49
|
+
humanizeDuration(61_421); // "1 minute and 1 second"
|
|
50
|
+
```
|
|
@@ -678,6 +678,80 @@ const compositeStringifiers = {
|
|
|
678
678
|
String: inspectStringObject
|
|
679
679
|
};
|
|
680
680
|
|
|
681
|
+
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
682
|
+
// https://stackoverflow.com/a/75985833/2634179
|
|
683
|
+
const RESET = "\x1b[0m";
|
|
684
|
+
const ANSI = {
|
|
685
|
+
supported: true,
|
|
686
|
+
RED: "\x1b[31m",
|
|
687
|
+
GREEN: "\x1b[32m",
|
|
688
|
+
YELLOW: "\x1b[33m",
|
|
689
|
+
BLUE: "\x1b[34m",
|
|
690
|
+
MAGENTA: "\x1b[35m",
|
|
691
|
+
CYAN: "\x1b[36m",
|
|
692
|
+
GREY: "\x1b[90m",
|
|
693
|
+
color: (text, ANSI_COLOR) => {
|
|
694
|
+
return ANSI.supported && ANSI_COLOR ? "".concat(ANSI_COLOR).concat(text).concat(RESET) : text;
|
|
695
|
+
},
|
|
696
|
+
BOLD: "\x1b[1m",
|
|
697
|
+
UNDERLINE: "\x1b[4m",
|
|
698
|
+
STRIKE: "\x1b[9m",
|
|
699
|
+
effect: (text, ANSI_EFFECT) => {
|
|
700
|
+
return ANSI.supported && ANSI_EFFECT ? "".concat(ANSI_EFFECT).concat(text).concat(RESET) : text;
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
// see also https://github.com/sindresorhus/figures
|
|
705
|
+
|
|
706
|
+
const UNICODE = {
|
|
707
|
+
supported: true,
|
|
708
|
+
get COMMAND_RAW() {
|
|
709
|
+
return UNICODE.supported ? "\u276F" : ">";
|
|
710
|
+
},
|
|
711
|
+
get OK_RAW() {
|
|
712
|
+
return UNICODE.supported ? "\u2714" : "\u221A";
|
|
713
|
+
},
|
|
714
|
+
get FAILURE_RAW() {
|
|
715
|
+
return UNICODE.supported ? "\u2716" : "\xD7";
|
|
716
|
+
},
|
|
717
|
+
get DEBUG_RAW() {
|
|
718
|
+
return UNICODE.supported ? "\u25C6" : "\u2666";
|
|
719
|
+
},
|
|
720
|
+
get INFO_RAW() {
|
|
721
|
+
return UNICODE.supported ? "\u2139" : "i";
|
|
722
|
+
},
|
|
723
|
+
get WARNING_RAW() {
|
|
724
|
+
return UNICODE.supported ? "\u26A0" : "\u203C";
|
|
725
|
+
},
|
|
726
|
+
get CIRCLE_CROSS_RAW() {
|
|
727
|
+
return UNICODE.supported ? "\u24E7" : "(\xD7)";
|
|
728
|
+
},
|
|
729
|
+
get COMMAND() {
|
|
730
|
+
return ANSI.color(UNICODE.COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
|
|
731
|
+
},
|
|
732
|
+
get OK() {
|
|
733
|
+
return ANSI.color(UNICODE.OK_RAW, ANSI.GREEN);
|
|
734
|
+
},
|
|
735
|
+
get FAILURE() {
|
|
736
|
+
return ANSI.color(UNICODE.FAILURE_RAW, ANSI.RED);
|
|
737
|
+
},
|
|
738
|
+
get DEBUG() {
|
|
739
|
+
return ANSI.color(UNICODE.DEBUG_RAW, ANSI.GREY);
|
|
740
|
+
},
|
|
741
|
+
get INFO() {
|
|
742
|
+
return ANSI.color(UNICODE.INFO_RAW, ANSI.BLUE);
|
|
743
|
+
},
|
|
744
|
+
get WARNING() {
|
|
745
|
+
return ANSI.color(UNICODE.WARNING_RAW, ANSI.YELLOW);
|
|
746
|
+
},
|
|
747
|
+
get CIRCLE_CROSS() {
|
|
748
|
+
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
749
|
+
},
|
|
750
|
+
get ELLIPSIS() {
|
|
751
|
+
return UNICODE.supported ? "\u2026" : "...";
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
|
|
681
755
|
const getPrecision = number => {
|
|
682
756
|
if (Math.floor(number) === number) return 0;
|
|
683
757
|
const [, decimals] = number.toString().split(".");
|
|
@@ -914,7 +988,7 @@ const humanizeFileSize = (numberOfBytes, {
|
|
|
914
988
|
short
|
|
915
989
|
});
|
|
916
990
|
};
|
|
917
|
-
const
|
|
991
|
+
const humanizeMemory = (metricValue, {
|
|
918
992
|
decimals,
|
|
919
993
|
short
|
|
920
994
|
} = {}) => {
|
|
@@ -1154,4 +1228,4 @@ const fillLeft = (value, biggestValue, char = " ") => {
|
|
|
1154
1228
|
return padded;
|
|
1155
1229
|
};
|
|
1156
1230
|
|
|
1157
|
-
export { createDetailedMessage, determineQuote, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize,
|
|
1231
|
+
export { ANSI, UNICODE, createDetailedMessage, determineQuote, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, inspectChar };
|
|
@@ -91,170 +91,86 @@ const error = (...args) => console.error(...args);
|
|
|
91
91
|
|
|
92
92
|
const errorDisabled = () => {};
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
const OSC = '\u001B]';
|
|
96
|
-
const BEL = '\u0007';
|
|
97
|
-
const SEP = ';';
|
|
94
|
+
/* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
|
|
98
95
|
|
|
99
|
-
|
|
100
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
96
|
+
const isBrowser = globalThis.window?.document !== undefined;
|
|
101
97
|
|
|
102
|
-
|
|
103
|
-
const isWindows = !isBrowser && process$1.platform === 'win32';
|
|
104
|
-
const cwdFunction = isBrowser ? () => {
|
|
105
|
-
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
106
|
-
} : process$1.cwd;
|
|
98
|
+
globalThis.process?.versions?.node !== undefined;
|
|
107
99
|
|
|
108
|
-
|
|
100
|
+
globalThis.process?.versions?.bun !== undefined;
|
|
109
101
|
|
|
110
|
-
|
|
111
|
-
if (typeof x !== 'number') {
|
|
112
|
-
throw new TypeError('The `x` argument is required');
|
|
113
|
-
}
|
|
102
|
+
globalThis.Deno?.version?.deno !== undefined;
|
|
114
103
|
|
|
115
|
-
|
|
116
|
-
return ESC + (x + 1) + 'G';
|
|
117
|
-
}
|
|
104
|
+
globalThis.process?.versions?.electron !== undefined;
|
|
118
105
|
|
|
119
|
-
|
|
120
|
-
};
|
|
106
|
+
globalThis.navigator?.userAgent?.includes('jsdom') === true;
|
|
121
107
|
|
|
122
|
-
|
|
123
|
-
if (typeof x !== 'number') {
|
|
124
|
-
throw new TypeError('The `x` argument is required');
|
|
125
|
-
}
|
|
108
|
+
typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
|
|
126
109
|
|
|
127
|
-
|
|
110
|
+
typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
128
111
|
|
|
129
|
-
|
|
130
|
-
returnValue += ESC + (-x) + 'D';
|
|
131
|
-
} else if (x > 0) {
|
|
132
|
-
returnValue += ESC + x + 'C';
|
|
133
|
-
}
|
|
112
|
+
typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
|
|
134
113
|
|
|
135
|
-
|
|
136
|
-
returnValue += ESC + (-y) + 'A';
|
|
137
|
-
} else if (y > 0) {
|
|
138
|
-
returnValue += ESC + y + 'B';
|
|
139
|
-
}
|
|
114
|
+
typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
|
|
140
115
|
|
|
141
|
-
|
|
142
|
-
|
|
116
|
+
// Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
|
|
117
|
+
const platform = globalThis.navigator?.userAgentData?.platform;
|
|
118
|
+
|
|
119
|
+
platform === 'macOS'
|
|
120
|
+
|| globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
|
|
121
|
+
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|
|
122
|
+
|| globalThis.process?.platform === 'darwin';
|
|
123
|
+
|
|
124
|
+
platform === 'Windows'
|
|
125
|
+
|| globalThis.navigator?.platform === 'Win32'
|
|
126
|
+
|| globalThis.process?.platform === 'win32';
|
|
127
|
+
|
|
128
|
+
platform === 'Linux'
|
|
129
|
+
|| globalThis.navigator?.platform?.startsWith('Linux') === true
|
|
130
|
+
|| globalThis.navigator?.userAgent?.includes(' Linux ') === true
|
|
131
|
+
|| globalThis.process?.platform === 'linux';
|
|
132
|
+
|
|
133
|
+
platform === 'Android'
|
|
134
|
+
|| globalThis.navigator?.platform === 'Android'
|
|
135
|
+
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|
|
136
|
+
|| globalThis.process?.platform === 'android';
|
|
137
|
+
|
|
138
|
+
const ESC = '\u001B[';
|
|
139
|
+
|
|
140
|
+
!isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
141
|
+
const isWindows = !isBrowser && process$1.platform === 'win32';
|
|
142
|
+
|
|
143
|
+
isBrowser ? () => {
|
|
144
|
+
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
145
|
+
} : process$1.cwd;
|
|
143
146
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
ansiEscapes.cursorLeft = ESC + 'G';
|
|
150
|
-
ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
|
|
151
|
-
ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
|
|
152
|
-
ansiEscapes.cursorGetPosition = ESC + '6n';
|
|
153
|
-
ansiEscapes.cursorNextLine = ESC + 'E';
|
|
154
|
-
ansiEscapes.cursorPrevLine = ESC + 'F';
|
|
155
|
-
ansiEscapes.cursorHide = ESC + '?25l';
|
|
156
|
-
ansiEscapes.cursorShow = ESC + '?25h';
|
|
157
|
-
|
|
158
|
-
ansiEscapes.eraseLines = count => {
|
|
147
|
+
const cursorUp = (count = 1) => ESC + count + 'A';
|
|
148
|
+
|
|
149
|
+
const cursorLeft = ESC + 'G';
|
|
150
|
+
|
|
151
|
+
const eraseLines = count => {
|
|
159
152
|
let clear = '';
|
|
160
153
|
|
|
161
154
|
for (let i = 0; i < count; i++) {
|
|
162
|
-
clear +=
|
|
155
|
+
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
|
|
163
156
|
}
|
|
164
157
|
|
|
165
158
|
if (count) {
|
|
166
|
-
clear +=
|
|
159
|
+
clear += cursorLeft;
|
|
167
160
|
}
|
|
168
161
|
|
|
169
162
|
return clear;
|
|
170
163
|
};
|
|
164
|
+
const eraseLine = ESC + '2K';
|
|
165
|
+
const eraseScreen = ESC + '2J';
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
ansiEscapes.eraseLine = ESC + '2K';
|
|
175
|
-
ansiEscapes.eraseDown = ESC + 'J';
|
|
176
|
-
ansiEscapes.eraseUp = ESC + '1J';
|
|
177
|
-
ansiEscapes.eraseScreen = ESC + '2J';
|
|
178
|
-
ansiEscapes.scrollUp = ESC + 'S';
|
|
179
|
-
ansiEscapes.scrollDown = ESC + 'T';
|
|
180
|
-
|
|
181
|
-
ansiEscapes.clearScreen = '\u001Bc';
|
|
182
|
-
|
|
183
|
-
ansiEscapes.clearTerminal = isWindows
|
|
184
|
-
? `${ansiEscapes.eraseScreen}${ESC}0f`
|
|
167
|
+
const clearTerminal = isWindows
|
|
168
|
+
? `${eraseScreen}${ESC}0f`
|
|
185
169
|
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
186
170
|
// 2. Erases the whole screen including scrollback buffer
|
|
187
171
|
// 3. Moves cursor to the top-left position
|
|
188
172
|
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
189
|
-
:
|
|
190
|
-
|
|
191
|
-
ansiEscapes.enterAlternativeScreen = ESC + '?1049h';
|
|
192
|
-
ansiEscapes.exitAlternativeScreen = ESC + '?1049l';
|
|
193
|
-
|
|
194
|
-
ansiEscapes.beep = BEL;
|
|
195
|
-
|
|
196
|
-
ansiEscapes.link = (text, url) => [
|
|
197
|
-
OSC,
|
|
198
|
-
'8',
|
|
199
|
-
SEP,
|
|
200
|
-
SEP,
|
|
201
|
-
url,
|
|
202
|
-
BEL,
|
|
203
|
-
text,
|
|
204
|
-
OSC,
|
|
205
|
-
'8',
|
|
206
|
-
SEP,
|
|
207
|
-
SEP,
|
|
208
|
-
BEL,
|
|
209
|
-
].join('');
|
|
210
|
-
|
|
211
|
-
ansiEscapes.image = (buffer, options = {}) => {
|
|
212
|
-
let returnValue = `${OSC}1337;File=inline=1`;
|
|
213
|
-
|
|
214
|
-
if (options.width) {
|
|
215
|
-
returnValue += `;width=${options.width}`;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (options.height) {
|
|
219
|
-
returnValue += `;height=${options.height}`;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (options.preserveAspectRatio === false) {
|
|
223
|
-
returnValue += ';preserveAspectRatio=0';
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return returnValue + ':' + buffer.toString('base64') + BEL;
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
ansiEscapes.iTerm = {
|
|
230
|
-
setCwd: (cwd = cwdFunction()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
|
|
231
|
-
|
|
232
|
-
annotation(message, options = {}) {
|
|
233
|
-
let returnValue = `${OSC}1337;`;
|
|
234
|
-
|
|
235
|
-
const hasX = typeof options.x !== 'undefined';
|
|
236
|
-
const hasY = typeof options.y !== 'undefined';
|
|
237
|
-
if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
|
|
238
|
-
throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
message = message.replace(/\|/g, '');
|
|
242
|
-
|
|
243
|
-
returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
|
|
244
|
-
|
|
245
|
-
if (options.length > 0) {
|
|
246
|
-
returnValue += (
|
|
247
|
-
hasX
|
|
248
|
-
? [message, options.length, options.x, options.y]
|
|
249
|
-
: [options.length, message]
|
|
250
|
-
).join('|');
|
|
251
|
-
} else {
|
|
252
|
-
returnValue += message;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return returnValue + BEL;
|
|
256
|
-
},
|
|
257
|
-
};
|
|
173
|
+
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
258
174
|
|
|
259
175
|
/*
|
|
260
176
|
* see also https://github.com/vadimdemedes/ink
|
|
@@ -302,7 +218,7 @@ const createDynamicLog = ({
|
|
|
302
218
|
if (visualLineCount > rows) {
|
|
303
219
|
if (clearTerminalAllowed) {
|
|
304
220
|
clearAttemptResult = true;
|
|
305
|
-
return
|
|
221
|
+
return clearTerminal;
|
|
306
222
|
}
|
|
307
223
|
// the whole log cannot be cleared because it's vertically to long
|
|
308
224
|
// (longer than terminal height)
|
|
@@ -315,7 +231,7 @@ const createDynamicLog = ({
|
|
|
315
231
|
}
|
|
316
232
|
|
|
317
233
|
clearAttemptResult = true;
|
|
318
|
-
return
|
|
234
|
+
return eraseLines(visualLineCount);
|
|
319
235
|
};
|
|
320
236
|
|
|
321
237
|
const update = (string) => {
|
|
@@ -344,20 +260,22 @@ const createDynamicLog = ({
|
|
|
344
260
|
clearAttemptResult = undefined;
|
|
345
261
|
};
|
|
346
262
|
|
|
347
|
-
const clearDuringFunctionCall = (
|
|
263
|
+
const clearDuringFunctionCall = (
|
|
264
|
+
callback,
|
|
265
|
+
ouputAfterCallback = lastOutput,
|
|
266
|
+
) => {
|
|
348
267
|
// 1. Erase the current log
|
|
349
|
-
// 2. Call callback (
|
|
268
|
+
// 2. Call callback (expect to write something on stdout)
|
|
350
269
|
// 3. Restore the current log
|
|
351
270
|
// During step 2. we expect a "write from outside" so we uninstall
|
|
352
271
|
// the stream spy during function call
|
|
353
|
-
const currentOutput = lastOutput;
|
|
354
272
|
update("");
|
|
355
273
|
|
|
356
274
|
writing = true;
|
|
357
275
|
callback();
|
|
358
276
|
writing = false;
|
|
359
277
|
|
|
360
|
-
update(
|
|
278
|
+
update(ouputAfterCallback);
|
|
361
279
|
};
|
|
362
280
|
|
|
363
281
|
const writeFromOutsideEffect = (value) => {
|
|
@@ -630,14 +548,19 @@ const ANSI = {
|
|
|
630
548
|
YELLOW: "\x1b[33m",
|
|
631
549
|
BLUE: "\x1b[34m",
|
|
632
550
|
MAGENTA: "\x1b[35m",
|
|
551
|
+
CYAN: "\x1b[36m",
|
|
633
552
|
GREY: "\x1b[90m",
|
|
634
553
|
color: (text, ANSI_COLOR) => {
|
|
635
|
-
return ANSI.supported ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
554
|
+
return ANSI.supported && ANSI_COLOR ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
636
555
|
},
|
|
637
556
|
|
|
638
557
|
BOLD: "\x1b[1m",
|
|
558
|
+
UNDERLINE: "\x1b[4m",
|
|
559
|
+
STRIKE: "\x1b[9m",
|
|
639
560
|
effect: (text, ANSI_EFFECT) => {
|
|
640
|
-
return ANSI.supported
|
|
561
|
+
return ANSI.supported && ANSI_EFFECT
|
|
562
|
+
? `${ANSI_EFFECT}${text}${RESET}`
|
|
563
|
+
: text;
|
|
641
564
|
},
|
|
642
565
|
};
|
|
643
566
|
|
|
@@ -1011,6 +934,9 @@ const UNICODE = {
|
|
|
1011
934
|
get CIRCLE_CROSS() {
|
|
1012
935
|
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
1013
936
|
},
|
|
937
|
+
get ELLIPSIS() {
|
|
938
|
+
return UNICODE.supported ? `…` : `...`;
|
|
939
|
+
},
|
|
1014
940
|
};
|
|
1015
941
|
|
|
1016
942
|
const createTaskLog = (
|
|
@@ -1751,7 +1677,7 @@ const humanizeFileSize = (numberOfBytes, { decimals, short } = {}) => {
|
|
|
1751
1677
|
return inspectBytes(numberOfBytes, { decimals, short });
|
|
1752
1678
|
};
|
|
1753
1679
|
|
|
1754
|
-
const
|
|
1680
|
+
const humanizeMemory = (metricValue, { decimals, short } = {}) => {
|
|
1755
1681
|
return inspectBytes(metricValue, { decimals, fixedDecimals: true, short });
|
|
1756
1682
|
};
|
|
1757
1683
|
|
|
@@ -2000,4 +1926,4 @@ const fillLeft = (value, biggestValue, char = " ") => {
|
|
|
2000
1926
|
return padded;
|
|
2001
1927
|
};
|
|
2002
1928
|
|
|
2003
|
-
export { ANSI, UNICODE, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, determineQuote, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize,
|
|
1929
|
+
export { ANSI, UNICODE, createDetailedMessage, createDynamicLog, createLogger, createTaskLog, determineQuote, distributePercentages, generateContentFrame, humanize, humanizeDuration, humanizeEllapsedTime, humanizeFileSize, humanizeMemory, humanizeMethodSymbol, inspectChar, startSpinner };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/humanize",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Generate messages meant to read by humans",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"prepublishOnly": "npm run build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"string-width": "7.
|
|
42
|
+
"string-width": "7.2.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"ansi-escapes": "
|
|
45
|
+
"ansi-escapes": "7.0.0",
|
|
46
46
|
"is-unicode-supported": "2.0.0",
|
|
47
47
|
"supports-color": "9.4.0"
|
|
48
48
|
}
|
|
@@ -1,35 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
1 with chromium (chromium@120.0.6099.28)
|
|
4
|
-
1 with firefox (firefox@119.0)
|
|
5
|
-
1 with webkit (webkit@17.4)
|
|
1
|
+
-------------- execution start --------------
|
|
2
|
+
21 files matching "testPlan" in /Users/damien.maillard/dev/perso/jsenv-core/packages/independent/humanize/src
|
|
6
3
|
---------------------------------------------
|
|
7
4
|
|
|
8
|
-
✔ 01/23 _tests/byte/file_size.test.js [node/0.03s
|
|
9
|
-
✔ 02/23 _tests/byte/
|
|
10
|
-
✔ 03/23 _tests/content_frame/content_frame.test.js [node/0.
|
|
11
|
-
✔ 04/23 _tests/js_value/_inspect.test.html [chromium/0.2s
|
|
12
|
-
✔ 05/23 _tests/js_value/_inspect.test.html [firefox/0.
|
|
5
|
+
✔ 01/23 _tests/byte/file_size.test.js [node/0.03s] (1 completed)
|
|
6
|
+
✔ 02/23 _tests/byte/memory.test.js [node/0.03s] (2 completed)
|
|
7
|
+
✔ 03/23 _tests/content_frame/content_frame.test.js [node/0.07s] (3 completed)
|
|
8
|
+
✔ 04/23 _tests/js_value/_inspect.test.html [chromium/0.2s] (4 completed)
|
|
9
|
+
✔ 05/23 _tests/js_value/_inspect.test.html [firefox/0.1s] (5 completed)
|
|
13
10
|
✔ 06/23 _tests/js_value/_inspect.test.html [webkit/0.3s] (6 completed)
|
|
14
|
-
✔ 07/23 _tests/js_value/array.test.js [node/0.
|
|
15
|
-
✔ 08/23 _tests/js_value/biginit.test.js [node/0.
|
|
16
|
-
✔ 09/23 _tests/js_value/boolean.test.js [node/0.1s
|
|
17
|
-
✔ 10/23 _tests/js_value/date.test.js [node/0.
|
|
18
|
-
✔ 11/23 _tests/js_value/error.test.js [node/0.
|
|
19
|
-
✔ 12/23 _tests/js_value/function.test.js [node/0.05s
|
|
20
|
-
✔ 13/23 _tests/js_value/instance.test.js [node/0.
|
|
21
|
-
✔ 14/23 _tests/js_value/null.test.js [node/0.04s
|
|
22
|
-
✔ 15/23 _tests/js_value/number.test.js [node/0.06s
|
|
23
|
-
✔ 16/23 _tests/js_value/object.test.js [node/0.
|
|
24
|
-
✔ 17/23 _tests/js_value/regexp.test.js [node/0.
|
|
25
|
-
✔ 18/23 _tests/js_value/string.test.js [node/0.05s
|
|
26
|
-
✔ 19/23 _tests/js_value/symbol.test.js [node/0.
|
|
27
|
-
✔ 20/23 _tests/js_value/undefined.test.js [node/0.
|
|
28
|
-
✔ 21/23 _tests/time/decimals.test.js [node/0.03s
|
|
29
|
-
✔ 22/23 _tests/time/duration.test.js [node/0.03s
|
|
30
|
-
✔ 23/23 _tests/time/ellapsed.test.js [node/0.
|
|
11
|
+
✔ 07/23 _tests/js_value/array.test.js [node/0.03s] (7 completed)
|
|
12
|
+
✔ 08/23 _tests/js_value/biginit.test.js [node/0.03s] (8 completed)
|
|
13
|
+
✔ 09/23 _tests/js_value/boolean.test.js [node/0.1s] (9 completed)
|
|
14
|
+
✔ 10/23 _tests/js_value/date.test.js [node/0.1s] (10 completed)
|
|
15
|
+
✔ 11/23 _tests/js_value/error.test.js [node/0.1s] (11 completed)
|
|
16
|
+
✔ 12/23 _tests/js_value/function.test.js [node/0.05s] (12 completed)
|
|
17
|
+
✔ 13/23 _tests/js_value/instance.test.js [node/0.1s] (13 completed)
|
|
18
|
+
✔ 14/23 _tests/js_value/null.test.js [node/0.04s] (14 completed)
|
|
19
|
+
✔ 15/23 _tests/js_value/number.test.js [node/0.06s] (15 completed)
|
|
20
|
+
✔ 16/23 _tests/js_value/object.test.js [node/0.06s] (16 completed)
|
|
21
|
+
✔ 17/23 _tests/js_value/regexp.test.js [node/0.04s] (17 completed)
|
|
22
|
+
✔ 18/23 _tests/js_value/string.test.js [node/0.05s] (18 completed)
|
|
23
|
+
✔ 19/23 _tests/js_value/symbol.test.js [node/0.02s] (19 completed)
|
|
24
|
+
✔ 20/23 _tests/js_value/undefined.test.js [node/0.03s] (20 completed)
|
|
25
|
+
✔ 21/23 _tests/time/decimals.test.js [node/0.03s] (21 completed)
|
|
26
|
+
✔ 22/23 _tests/time/duration.test.js [node/0.03s] (22 completed)
|
|
27
|
+
✔ 23/23 _tests/time/ellapsed.test.js [node/0.03s] (all completed)
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
--------------- execution end ---------------
|
|
33
30
|
23 executions: all completed
|
|
34
|
-
duration:
|
|
31
|
+
duration: 2.6s (setup: 0.4s, execution: 2.4s, teardown: 0.2s)
|
|
35
32
|
---------------------------------------------
|
|
@@ -2,9 +2,9 @@ import { assert } from "@jsenv/assert";
|
|
|
2
2
|
|
|
3
3
|
import { humanizeFileSize } from "@jsenv/humanize";
|
|
4
4
|
|
|
5
|
-
const test = (fileSize,
|
|
5
|
+
const test = (fileSize, expect) => {
|
|
6
6
|
const actual = humanizeFileSize(fileSize);
|
|
7
|
-
assert({ actual,
|
|
7
|
+
assert({ actual, expect });
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
test(0, "0 B");
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { assert } from "@jsenv/assert";
|
|
2
|
+
|
|
3
|
+
import { humanizeMemory } from "@jsenv/humanize";
|
|
4
|
+
|
|
5
|
+
const test = (memoryUsageInBytes, expect) => {
|
|
6
|
+
const actual = humanizeMemory(memoryUsageInBytes);
|
|
7
|
+
assert({ actual, expect });
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
test(1000, "1.0 kB");
|
|
11
|
+
test(1100, "1.1 kB");
|
|
@@ -3,35 +3,35 @@ import { humanize } from "@jsenv/humanize";
|
|
|
3
3
|
|
|
4
4
|
{
|
|
5
5
|
const actual = humanize([]);
|
|
6
|
-
const
|
|
7
|
-
assert({ actual,
|
|
6
|
+
const expect = `[]`;
|
|
7
|
+
assert({ actual, expect });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
{
|
|
11
11
|
const actual = humanize([[]]);
|
|
12
|
-
const
|
|
12
|
+
const expect = `[
|
|
13
13
|
[]
|
|
14
14
|
]`;
|
|
15
|
-
assert({ actual,
|
|
15
|
+
assert({ actual, expect });
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
{
|
|
19
19
|
const actual = humanize(Array(3));
|
|
20
20
|
// prettier-ignore
|
|
21
|
-
const
|
|
21
|
+
const expect = `[
|
|
22
22
|
,
|
|
23
23
|
,
|
|
24
24
|
${" "}
|
|
25
25
|
]`
|
|
26
|
-
assert({ actual,
|
|
26
|
+
assert({ actual, expect });
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
{
|
|
30
30
|
const actual = humanize([Symbol()]);
|
|
31
|
-
const
|
|
31
|
+
const expect = `[
|
|
32
32
|
Symbol()
|
|
33
33
|
]`;
|
|
34
|
-
assert({ actual,
|
|
34
|
+
assert({ actual, expect });
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
{
|
|
@@ -40,23 +40,23 @@ ${" "}
|
|
|
40
40
|
|
|
41
41
|
{
|
|
42
42
|
const actual = humanize(newArray);
|
|
43
|
-
const
|
|
43
|
+
const expect = `[
|
|
44
44
|
"foo",
|
|
45
45
|
1
|
|
46
46
|
]`;
|
|
47
47
|
assert({
|
|
48
48
|
actual,
|
|
49
|
-
|
|
49
|
+
expect,
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
{
|
|
54
54
|
const actual = humanize(newArray);
|
|
55
|
-
const
|
|
55
|
+
const expect = `[
|
|
56
56
|
"foo",
|
|
57
57
|
1
|
|
58
58
|
]`;
|
|
59
|
-
assert({ actual,
|
|
59
|
+
assert({ actual, expect });
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -64,9 +64,9 @@ ${" "}
|
|
|
64
64
|
const circularArray = [0];
|
|
65
65
|
circularArray.push(circularArray);
|
|
66
66
|
const actual = humanize(circularArray);
|
|
67
|
-
const
|
|
67
|
+
const expect = `[
|
|
68
68
|
0,
|
|
69
69
|
Symbol.for('circular')
|
|
70
70
|
]`;
|
|
71
|
-
assert({ actual,
|
|
71
|
+
assert({ actual, expect });
|
|
72
72
|
}
|