@jsenv/test 3.0.16 → 3.0.18
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/jsenv_test.js
CHANGED
|
@@ -4,8 +4,8 @@ import { readdir, chmod, stat, lstat, promises, readFile as readFile$1, writeFil
|
|
|
4
4
|
import { takeCoverage } from "node:v8";
|
|
5
5
|
import stripAnsi from "strip-ansi";
|
|
6
6
|
import { URL_META, createException } from "./js/exception.js";
|
|
7
|
-
import stringWidth from "string-width";
|
|
8
7
|
import tty from "node:tty";
|
|
8
|
+
import stringWidth from "string-width";
|
|
9
9
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
10
10
|
import { dirname } from "node:path";
|
|
11
11
|
import crypto from "node:crypto";
|
|
@@ -530,599 +530,339 @@ const SIGINT_CALLBACK = {
|
|
|
530
530
|
},
|
|
531
531
|
};
|
|
532
532
|
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
const LOG_LEVEL_DEBUG = "debug";
|
|
536
|
-
|
|
537
|
-
const LOG_LEVEL_INFO = "info";
|
|
538
|
-
|
|
539
|
-
const LOG_LEVEL_WARN = "warn";
|
|
533
|
+
const createDetailedMessage = (message, details = {}) => {
|
|
534
|
+
let string = `${message}`;
|
|
540
535
|
|
|
541
|
-
|
|
536
|
+
Object.keys(details).forEach((key) => {
|
|
537
|
+
const value = details[key];
|
|
538
|
+
string += `
|
|
539
|
+
--- ${key} ---
|
|
540
|
+
${
|
|
541
|
+
Array.isArray(value)
|
|
542
|
+
? value.join(`
|
|
543
|
+
`)
|
|
544
|
+
: value
|
|
545
|
+
}`;
|
|
546
|
+
});
|
|
542
547
|
|
|
543
|
-
|
|
544
|
-
if (logLevel === LOG_LEVEL_DEBUG) {
|
|
545
|
-
return {
|
|
546
|
-
level: "debug",
|
|
547
|
-
levels: { debug: true, info: true, warn: true, error: true },
|
|
548
|
-
debug,
|
|
549
|
-
info,
|
|
550
|
-
warn,
|
|
551
|
-
error,
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
if (logLevel === LOG_LEVEL_INFO) {
|
|
555
|
-
return {
|
|
556
|
-
level: "info",
|
|
557
|
-
levels: { debug: false, info: true, warn: true, error: true },
|
|
558
|
-
debug: debugDisabled,
|
|
559
|
-
info,
|
|
560
|
-
warn,
|
|
561
|
-
error,
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
if (logLevel === LOG_LEVEL_WARN) {
|
|
565
|
-
return {
|
|
566
|
-
level: "warn",
|
|
567
|
-
levels: { debug: false, info: false, warn: true, error: true },
|
|
568
|
-
debug: debugDisabled,
|
|
569
|
-
info: infoDisabled,
|
|
570
|
-
warn,
|
|
571
|
-
error,
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
if (logLevel === LOG_LEVEL_ERROR) {
|
|
575
|
-
return {
|
|
576
|
-
level: "error",
|
|
577
|
-
levels: { debug: false, info: false, warn: false, error: true },
|
|
578
|
-
debug: debugDisabled,
|
|
579
|
-
info: infoDisabled,
|
|
580
|
-
warn: warnDisabled,
|
|
581
|
-
error,
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
if (logLevel === LOG_LEVEL_OFF) {
|
|
585
|
-
return {
|
|
586
|
-
level: "off",
|
|
587
|
-
levels: { debug: false, info: false, warn: false, error: false },
|
|
588
|
-
debug: debugDisabled,
|
|
589
|
-
info: infoDisabled,
|
|
590
|
-
warn: warnDisabled,
|
|
591
|
-
error: errorDisabled,
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
throw new Error(`unexpected logLevel.
|
|
595
|
-
--- logLevel ---
|
|
596
|
-
${logLevel}
|
|
597
|
-
--- allowed log levels ---
|
|
598
|
-
${LOG_LEVEL_OFF}
|
|
599
|
-
${LOG_LEVEL_ERROR}
|
|
600
|
-
${LOG_LEVEL_WARN}
|
|
601
|
-
${LOG_LEVEL_INFO}
|
|
602
|
-
${LOG_LEVEL_DEBUG}`);
|
|
548
|
+
return string;
|
|
603
549
|
};
|
|
604
550
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
const
|
|
551
|
+
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
|
|
552
|
+
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
|
|
553
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
|
|
554
|
+
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
555
|
+
const position = argv.indexOf(prefix + flag);
|
|
556
|
+
const terminatorPosition = argv.indexOf('--');
|
|
557
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
558
|
+
}
|
|
610
559
|
|
|
611
|
-
const
|
|
560
|
+
const {env} = process$1;
|
|
612
561
|
|
|
613
|
-
|
|
562
|
+
let flagForceColor;
|
|
563
|
+
if (
|
|
564
|
+
hasFlag('no-color')
|
|
565
|
+
|| hasFlag('no-colors')
|
|
566
|
+
|| hasFlag('color=false')
|
|
567
|
+
|| hasFlag('color=never')
|
|
568
|
+
) {
|
|
569
|
+
flagForceColor = 0;
|
|
570
|
+
} else if (
|
|
571
|
+
hasFlag('color')
|
|
572
|
+
|| hasFlag('colors')
|
|
573
|
+
|| hasFlag('color=true')
|
|
574
|
+
|| hasFlag('color=always')
|
|
575
|
+
) {
|
|
576
|
+
flagForceColor = 1;
|
|
577
|
+
}
|
|
614
578
|
|
|
615
|
-
|
|
579
|
+
function envForceColor() {
|
|
580
|
+
if ('FORCE_COLOR' in env) {
|
|
581
|
+
if (env.FORCE_COLOR === 'true') {
|
|
582
|
+
return 1;
|
|
583
|
+
}
|
|
616
584
|
|
|
617
|
-
|
|
585
|
+
if (env.FORCE_COLOR === 'false') {
|
|
586
|
+
return 0;
|
|
587
|
+
}
|
|
618
588
|
|
|
619
|
-
|
|
589
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
620
592
|
|
|
621
|
-
|
|
593
|
+
function translateLevel(level) {
|
|
594
|
+
if (level === 0) {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
622
597
|
|
|
623
|
-
|
|
598
|
+
return {
|
|
599
|
+
level,
|
|
600
|
+
hasBasic: true,
|
|
601
|
+
has256: level >= 2,
|
|
602
|
+
has16m: level >= 3,
|
|
603
|
+
};
|
|
604
|
+
}
|
|
624
605
|
|
|
625
|
-
|
|
606
|
+
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
|
|
607
|
+
const noFlagForceColor = envForceColor();
|
|
608
|
+
if (noFlagForceColor !== undefined) {
|
|
609
|
+
flagForceColor = noFlagForceColor;
|
|
610
|
+
}
|
|
626
611
|
|
|
627
|
-
|
|
612
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
628
613
|
|
|
629
|
-
|
|
614
|
+
if (forceColor === 0) {
|
|
615
|
+
return 0;
|
|
616
|
+
}
|
|
630
617
|
|
|
631
|
-
|
|
618
|
+
if (sniffFlags) {
|
|
619
|
+
if (hasFlag('color=16m')
|
|
620
|
+
|| hasFlag('color=full')
|
|
621
|
+
|| hasFlag('color=truecolor')) {
|
|
622
|
+
return 3;
|
|
623
|
+
}
|
|
632
624
|
|
|
633
|
-
|
|
625
|
+
if (hasFlag('color=256')) {
|
|
626
|
+
return 2;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
634
629
|
|
|
635
|
-
|
|
630
|
+
// Check for Azure DevOps pipelines.
|
|
631
|
+
// Has to be above the `!streamIsTTY` check.
|
|
632
|
+
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
|
633
|
+
return 1;
|
|
634
|
+
}
|
|
636
635
|
|
|
637
|
-
|
|
636
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
637
|
+
return 0;
|
|
638
|
+
}
|
|
638
639
|
|
|
639
|
-
|
|
640
|
+
const min = forceColor || 0;
|
|
640
641
|
|
|
641
|
-
|
|
642
|
+
if (env.TERM === 'dumb') {
|
|
643
|
+
return min;
|
|
644
|
+
}
|
|
642
645
|
|
|
643
|
-
|
|
644
|
-
|
|
646
|
+
if (process$1.platform === 'win32') {
|
|
647
|
+
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
648
|
+
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
649
|
+
const osRelease = os.release().split('.');
|
|
650
|
+
if (
|
|
651
|
+
Number(osRelease[0]) >= 10
|
|
652
|
+
&& Number(osRelease[2]) >= 10_586
|
|
653
|
+
) {
|
|
654
|
+
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
|
655
|
+
}
|
|
645
656
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|
|
649
|
-
|| globalThis.process?.platform === 'darwin';
|
|
657
|
+
return 1;
|
|
658
|
+
}
|
|
650
659
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
660
|
+
if ('CI' in env) {
|
|
661
|
+
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
|
|
662
|
+
return 3;
|
|
663
|
+
}
|
|
654
664
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|| globalThis.process?.platform === 'linux';
|
|
665
|
+
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
666
|
+
return 1;
|
|
667
|
+
}
|
|
659
668
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|
|
663
|
-
|| globalThis.process?.platform === 'android';
|
|
669
|
+
return min;
|
|
670
|
+
}
|
|
664
671
|
|
|
665
|
-
|
|
672
|
+
if ('TEAMCITY_VERSION' in env) {
|
|
673
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
674
|
+
}
|
|
666
675
|
|
|
667
|
-
|
|
668
|
-
|
|
676
|
+
if (env.COLORTERM === 'truecolor') {
|
|
677
|
+
return 3;
|
|
678
|
+
}
|
|
669
679
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}
|
|
680
|
+
if (env.TERM === 'xterm-kitty') {
|
|
681
|
+
return 3;
|
|
682
|
+
}
|
|
673
683
|
|
|
674
|
-
|
|
684
|
+
if ('TERM_PROGRAM' in env) {
|
|
685
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
675
686
|
|
|
676
|
-
|
|
687
|
+
switch (env.TERM_PROGRAM) {
|
|
688
|
+
case 'iTerm.app': {
|
|
689
|
+
return version >= 3 ? 3 : 2;
|
|
690
|
+
}
|
|
677
691
|
|
|
678
|
-
|
|
679
|
-
|
|
692
|
+
case 'Apple_Terminal': {
|
|
693
|
+
return 2;
|
|
694
|
+
}
|
|
695
|
+
// No default
|
|
696
|
+
}
|
|
697
|
+
}
|
|
680
698
|
|
|
681
|
-
|
|
682
|
-
|
|
699
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
700
|
+
return 2;
|
|
683
701
|
}
|
|
684
702
|
|
|
685
|
-
if (
|
|
686
|
-
|
|
703
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
704
|
+
return 1;
|
|
687
705
|
}
|
|
688
706
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
const eraseScreen = ESC + '2J';
|
|
693
|
-
|
|
694
|
-
const clearTerminal = isWindows$3
|
|
695
|
-
? `${eraseScreen}${ESC}0f`
|
|
696
|
-
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
697
|
-
// 2. Erases the whole screen including scrollback buffer
|
|
698
|
-
// 3. Moves cursor to the top-left position
|
|
699
|
-
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
700
|
-
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
701
|
-
|
|
702
|
-
/*
|
|
703
|
-
* see also https://github.com/vadimdemedes/ink
|
|
704
|
-
*/
|
|
707
|
+
if ('COLORTERM' in env) {
|
|
708
|
+
return 1;
|
|
709
|
+
}
|
|
705
710
|
|
|
711
|
+
return min;
|
|
712
|
+
}
|
|
706
713
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
} = {}) => {
|
|
713
|
-
const { columns = 80, rows = 24 } = stream;
|
|
714
|
-
const dynamicLog = {
|
|
715
|
-
destroyed: false,
|
|
716
|
-
onVerticalOverflow,
|
|
717
|
-
onWriteFromOutside,
|
|
718
|
-
};
|
|
714
|
+
function createSupportsColor(stream, options = {}) {
|
|
715
|
+
const level = _supportsColor(stream, {
|
|
716
|
+
streamIsTTY: stream && stream.isTTY,
|
|
717
|
+
...options,
|
|
718
|
+
});
|
|
719
719
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
let clearAttemptResult;
|
|
723
|
-
let writing = false;
|
|
720
|
+
return translateLevel(level);
|
|
721
|
+
}
|
|
724
722
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
}
|
|
730
|
-
if (clearAttemptResult !== undefined) {
|
|
731
|
-
return "";
|
|
732
|
-
}
|
|
723
|
+
const supportsColor = {
|
|
724
|
+
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
|
725
|
+
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
|
726
|
+
};
|
|
733
727
|
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
const width = stringWidth(logLine);
|
|
738
|
-
if (width === 0) {
|
|
739
|
-
visualLineCount++;
|
|
740
|
-
} else {
|
|
741
|
-
visualLineCount += Math.ceil(width / columns);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
728
|
+
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
729
|
+
// https://stackoverflow.com/a/75985833/2634179
|
|
730
|
+
const RESET = "\x1b[0m";
|
|
744
731
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
return
|
|
758
|
-
|
|
732
|
+
const createAnsi = ({ supported }) => {
|
|
733
|
+
const ANSI = {
|
|
734
|
+
supported,
|
|
735
|
+
|
|
736
|
+
RED: "\x1b[31m",
|
|
737
|
+
GREEN: "\x1b[32m",
|
|
738
|
+
YELLOW: "\x1b[33m",
|
|
739
|
+
BLUE: "\x1b[34m",
|
|
740
|
+
MAGENTA: "\x1b[35m",
|
|
741
|
+
CYAN: "\x1b[36m",
|
|
742
|
+
GREY: "\x1b[90m",
|
|
743
|
+
color: (text, ANSI_COLOR) => {
|
|
744
|
+
return ANSI.supported && ANSI_COLOR
|
|
745
|
+
? `${ANSI_COLOR}${text}${RESET}`
|
|
746
|
+
: text;
|
|
747
|
+
},
|
|
759
748
|
|
|
760
|
-
|
|
761
|
-
|
|
749
|
+
BOLD: "\x1b[1m",
|
|
750
|
+
UNDERLINE: "\x1b[4m",
|
|
751
|
+
STRIKE: "\x1b[9m",
|
|
752
|
+
effect: (text, ANSI_EFFECT) => {
|
|
753
|
+
return ANSI.supported && ANSI_EFFECT
|
|
754
|
+
? `${ANSI_EFFECT}${text}${RESET}`
|
|
755
|
+
: text;
|
|
756
|
+
},
|
|
762
757
|
};
|
|
763
758
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
throw new Error("Cannot write log after destroy");
|
|
767
|
-
}
|
|
768
|
-
let stringToWrite = string;
|
|
769
|
-
if (lastOutput) {
|
|
770
|
-
if (lastOutputFromOutside) {
|
|
771
|
-
// We don't want to clear logs written by other code,
|
|
772
|
-
// it makes output unreadable and might erase precious information
|
|
773
|
-
// To detect this we put a spy on the stream.
|
|
774
|
-
// The spy is required only if we actually wrote something in the stream
|
|
775
|
-
// something else than this code has written in the stream
|
|
776
|
-
// so we just write without clearing (append instead of replacing)
|
|
777
|
-
lastOutput = "";
|
|
778
|
-
lastOutputFromOutside = "";
|
|
779
|
-
} else {
|
|
780
|
-
stringToWrite = `${getErasePreviousOutput()}${string}`;
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
writing = true;
|
|
784
|
-
stream.write(stringToWrite);
|
|
785
|
-
lastOutput = string;
|
|
786
|
-
writing = false;
|
|
787
|
-
clearAttemptResult = undefined;
|
|
788
|
-
};
|
|
759
|
+
return ANSI;
|
|
760
|
+
};
|
|
789
761
|
|
|
790
|
-
|
|
791
|
-
callback,
|
|
792
|
-
ouputAfterCallback = lastOutput,
|
|
793
|
-
) => {
|
|
794
|
-
// 1. Erase the current log
|
|
795
|
-
// 2. Call callback (expect to write something on stdout)
|
|
796
|
-
// 3. Restore the current log
|
|
797
|
-
// During step 2. we expect a "write from outside" so we uninstall
|
|
798
|
-
// the stream spy during function call
|
|
799
|
-
update("");
|
|
762
|
+
const processSupportsBasicColor = createSupportsColor(process.stdout).hasBasic;
|
|
800
763
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
764
|
+
const ANSI = createAnsi({
|
|
765
|
+
supported:
|
|
766
|
+
processSupportsBasicColor ||
|
|
767
|
+
// GitHub workflow does support ANSI but "supports-color" returns false
|
|
768
|
+
// because stream.isTTY returns false, see https://github.com/actions/runner/issues/241
|
|
769
|
+
process.env.GITHUB_WORKFLOW,
|
|
770
|
+
});
|
|
804
771
|
|
|
805
|
-
|
|
806
|
-
|
|
772
|
+
function isUnicodeSupported() {
|
|
773
|
+
if (process$1.platform !== 'win32') {
|
|
774
|
+
return process$1.env.TERM !== 'linux'; // Linux console (kernel)
|
|
775
|
+
}
|
|
807
776
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
lastOutputFromOutside = value;
|
|
818
|
-
dynamicLog.onWriteFromOutside(value);
|
|
819
|
-
};
|
|
777
|
+
return Boolean(process$1.env.WT_SESSION) // Windows Terminal
|
|
778
|
+
|| Boolean(process$1.env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
|
|
779
|
+
|| process$1.env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
|
|
780
|
+
|| process$1.env.TERM_PROGRAM === 'Terminus-Sublime'
|
|
781
|
+
|| process$1.env.TERM_PROGRAM === 'vscode'
|
|
782
|
+
|| process$1.env.TERM === 'xterm-256color'
|
|
783
|
+
|| process$1.env.TERM === 'alacritty'
|
|
784
|
+
|| process$1.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
|
|
785
|
+
}
|
|
820
786
|
|
|
821
|
-
|
|
822
|
-
if (stream === process.stdout) {
|
|
823
|
-
const removeStdoutSpy = spyStreamOutput(
|
|
824
|
-
process.stdout,
|
|
825
|
-
writeFromOutsideEffect,
|
|
826
|
-
);
|
|
827
|
-
const removeStderrSpy = spyStreamOutput(
|
|
828
|
-
process.stderr,
|
|
829
|
-
writeFromOutsideEffect,
|
|
830
|
-
);
|
|
831
|
-
removeStreamSpy = () => {
|
|
832
|
-
removeStdoutSpy();
|
|
833
|
-
removeStderrSpy();
|
|
834
|
-
};
|
|
835
|
-
} else {
|
|
836
|
-
removeStreamSpy = spyStreamOutput(stream, writeFromOutsideEffect);
|
|
837
|
-
}
|
|
787
|
+
// see also https://github.com/sindresorhus/figures
|
|
838
788
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
789
|
+
const createUnicode = ({ supported, ANSI }) => {
|
|
790
|
+
const UNICODE = {
|
|
791
|
+
supported,
|
|
792
|
+
get COMMAND_RAW() {
|
|
793
|
+
return UNICODE.supported ? `❯` : `>`;
|
|
794
|
+
},
|
|
795
|
+
get OK_RAW() {
|
|
796
|
+
return UNICODE.supported ? `✔` : `√`;
|
|
797
|
+
},
|
|
798
|
+
get FAILURE_RAW() {
|
|
799
|
+
return UNICODE.supported ? `✖` : `×`;
|
|
800
|
+
},
|
|
801
|
+
get DEBUG_RAW() {
|
|
802
|
+
return UNICODE.supported ? `◆` : `♦`;
|
|
803
|
+
},
|
|
804
|
+
get INFO_RAW() {
|
|
805
|
+
return UNICODE.supported ? `ℹ` : `i`;
|
|
806
|
+
},
|
|
807
|
+
get WARNING_RAW() {
|
|
808
|
+
return UNICODE.supported ? `⚠` : `‼`;
|
|
809
|
+
},
|
|
810
|
+
get CIRCLE_CROSS_RAW() {
|
|
811
|
+
return UNICODE.supported ? `ⓧ` : `(×)`;
|
|
812
|
+
},
|
|
813
|
+
get COMMAND() {
|
|
814
|
+
return ANSI.color(UNICODE.COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
|
|
815
|
+
},
|
|
816
|
+
get OK() {
|
|
817
|
+
return ANSI.color(UNICODE.OK_RAW, ANSI.GREEN);
|
|
818
|
+
},
|
|
819
|
+
get FAILURE() {
|
|
820
|
+
return ANSI.color(UNICODE.FAILURE_RAW, ANSI.RED);
|
|
821
|
+
},
|
|
822
|
+
get DEBUG() {
|
|
823
|
+
return ANSI.color(UNICODE.DEBUG_RAW, ANSI.GREY);
|
|
824
|
+
},
|
|
825
|
+
get INFO() {
|
|
826
|
+
return ANSI.color(UNICODE.INFO_RAW, ANSI.BLUE);
|
|
827
|
+
},
|
|
828
|
+
get WARNING() {
|
|
829
|
+
return ANSI.color(UNICODE.WARNING_RAW, ANSI.YELLOW);
|
|
830
|
+
},
|
|
831
|
+
get CIRCLE_CROSS() {
|
|
832
|
+
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
833
|
+
},
|
|
834
|
+
get ELLIPSIS() {
|
|
835
|
+
return UNICODE.supported ? `…` : `...`;
|
|
836
|
+
},
|
|
847
837
|
};
|
|
848
|
-
|
|
849
|
-
Object.assign(dynamicLog, {
|
|
850
|
-
update,
|
|
851
|
-
destroy,
|
|
852
|
-
stream,
|
|
853
|
-
clearDuringFunctionCall,
|
|
854
|
-
});
|
|
855
|
-
return dynamicLog;
|
|
838
|
+
return UNICODE;
|
|
856
839
|
};
|
|
857
840
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const spyStreamOutput = (stream, callback) => {
|
|
863
|
-
const originalWrite = stream.write;
|
|
864
|
-
|
|
865
|
-
let output = "";
|
|
866
|
-
let installed = true;
|
|
867
|
-
|
|
868
|
-
stream.write = function (...args /* chunk, encoding, callback */) {
|
|
869
|
-
output += args;
|
|
870
|
-
callback(output);
|
|
871
|
-
return originalWrite.call(stream, ...args);
|
|
872
|
-
};
|
|
841
|
+
const UNICODE = createUnicode({
|
|
842
|
+
supported: isUnicodeSupported(),
|
|
843
|
+
ANSI,
|
|
844
|
+
});
|
|
873
845
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
846
|
+
const setRoundedPrecision = (
|
|
847
|
+
number,
|
|
848
|
+
{ decimals = 1, decimalsWhenSmall = decimals } = {},
|
|
849
|
+
) => {
|
|
850
|
+
return setDecimalsPrecision(number, {
|
|
851
|
+
decimals,
|
|
852
|
+
decimalsWhenSmall,
|
|
853
|
+
transform: Math.round,
|
|
854
|
+
});
|
|
855
|
+
};
|
|
881
856
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
892
|
-
const position = argv.indexOf(prefix + flag);
|
|
893
|
-
const terminatorPosition = argv.indexOf('--');
|
|
894
|
-
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
const {env} = process$1;
|
|
898
|
-
|
|
899
|
-
let flagForceColor;
|
|
900
|
-
if (
|
|
901
|
-
hasFlag('no-color')
|
|
902
|
-
|| hasFlag('no-colors')
|
|
903
|
-
|| hasFlag('color=false')
|
|
904
|
-
|| hasFlag('color=never')
|
|
905
|
-
) {
|
|
906
|
-
flagForceColor = 0;
|
|
907
|
-
} else if (
|
|
908
|
-
hasFlag('color')
|
|
909
|
-
|| hasFlag('colors')
|
|
910
|
-
|| hasFlag('color=true')
|
|
911
|
-
|| hasFlag('color=always')
|
|
912
|
-
) {
|
|
913
|
-
flagForceColor = 1;
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
function envForceColor() {
|
|
917
|
-
if ('FORCE_COLOR' in env) {
|
|
918
|
-
if (env.FORCE_COLOR === 'true') {
|
|
919
|
-
return 1;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
if (env.FORCE_COLOR === 'false') {
|
|
923
|
-
return 0;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
function translateLevel(level) {
|
|
931
|
-
if (level === 0) {
|
|
932
|
-
return false;
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
return {
|
|
936
|
-
level,
|
|
937
|
-
hasBasic: true,
|
|
938
|
-
has256: level >= 2,
|
|
939
|
-
has16m: level >= 3,
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
|
|
944
|
-
const noFlagForceColor = envForceColor();
|
|
945
|
-
if (noFlagForceColor !== undefined) {
|
|
946
|
-
flagForceColor = noFlagForceColor;
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
950
|
-
|
|
951
|
-
if (forceColor === 0) {
|
|
952
|
-
return 0;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
if (sniffFlags) {
|
|
956
|
-
if (hasFlag('color=16m')
|
|
957
|
-
|| hasFlag('color=full')
|
|
958
|
-
|| hasFlag('color=truecolor')) {
|
|
959
|
-
return 3;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
if (hasFlag('color=256')) {
|
|
963
|
-
return 2;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
// Check for Azure DevOps pipelines.
|
|
968
|
-
// Has to be above the `!streamIsTTY` check.
|
|
969
|
-
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
|
970
|
-
return 1;
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
974
|
-
return 0;
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
const min = forceColor || 0;
|
|
978
|
-
|
|
979
|
-
if (env.TERM === 'dumb') {
|
|
980
|
-
return min;
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
if (process$1.platform === 'win32') {
|
|
984
|
-
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
985
|
-
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
986
|
-
const osRelease = os.release().split('.');
|
|
987
|
-
if (
|
|
988
|
-
Number(osRelease[0]) >= 10
|
|
989
|
-
&& Number(osRelease[2]) >= 10_586
|
|
990
|
-
) {
|
|
991
|
-
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
return 1;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
if ('CI' in env) {
|
|
998
|
-
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
|
|
999
|
-
return 3;
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
1003
|
-
return 1;
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
return min;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
if ('TEAMCITY_VERSION' in env) {
|
|
1010
|
-
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
if (env.COLORTERM === 'truecolor') {
|
|
1014
|
-
return 3;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
if (env.TERM === 'xterm-kitty') {
|
|
1018
|
-
return 3;
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
if ('TERM_PROGRAM' in env) {
|
|
1022
|
-
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
1023
|
-
|
|
1024
|
-
switch (env.TERM_PROGRAM) {
|
|
1025
|
-
case 'iTerm.app': {
|
|
1026
|
-
return version >= 3 ? 3 : 2;
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
case 'Apple_Terminal': {
|
|
1030
|
-
return 2;
|
|
1031
|
-
}
|
|
1032
|
-
// No default
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
if (/-256(color)?$/i.test(env.TERM)) {
|
|
1037
|
-
return 2;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
1041
|
-
return 1;
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
if ('COLORTERM' in env) {
|
|
1045
|
-
return 1;
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
return min;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
function createSupportsColor(stream, options = {}) {
|
|
1052
|
-
const level = _supportsColor(stream, {
|
|
1053
|
-
streamIsTTY: stream && stream.isTTY,
|
|
1054
|
-
...options,
|
|
1055
|
-
});
|
|
1056
|
-
|
|
1057
|
-
return translateLevel(level);
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
const supportsColor = {
|
|
1061
|
-
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
|
1062
|
-
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
|
1063
|
-
};
|
|
1064
|
-
|
|
1065
|
-
const processSupportsBasicColor = createSupportsColor(process.stdout).hasBasic;
|
|
1066
|
-
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
1067
|
-
// https://stackoverflow.com/a/75985833/2634179
|
|
1068
|
-
const RESET = "\x1b[0m";
|
|
1069
|
-
|
|
1070
|
-
const ANSI = {
|
|
1071
|
-
supported: processSupportsBasicColor,
|
|
1072
|
-
|
|
1073
|
-
RED: "\x1b[31m",
|
|
1074
|
-
GREEN: "\x1b[32m",
|
|
1075
|
-
YELLOW: "\x1b[33m",
|
|
1076
|
-
BLUE: "\x1b[34m",
|
|
1077
|
-
MAGENTA: "\x1b[35m",
|
|
1078
|
-
CYAN: "\x1b[36m",
|
|
1079
|
-
GREY: "\x1b[90m",
|
|
1080
|
-
color: (text, ANSI_COLOR) => {
|
|
1081
|
-
return ANSI.supported && ANSI_COLOR ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
1082
|
-
},
|
|
1083
|
-
|
|
1084
|
-
BOLD: "\x1b[1m",
|
|
1085
|
-
UNDERLINE: "\x1b[4m",
|
|
1086
|
-
STRIKE: "\x1b[9m",
|
|
1087
|
-
effect: (text, ANSI_EFFECT) => {
|
|
1088
|
-
return ANSI.supported && ANSI_EFFECT
|
|
1089
|
-
? `${ANSI_EFFECT}${text}${RESET}`
|
|
1090
|
-
: text;
|
|
1091
|
-
},
|
|
1092
|
-
};
|
|
1093
|
-
|
|
1094
|
-
// GitHub workflow does support ANSI but "supports-color" returns false
|
|
1095
|
-
// because stream.isTTY returns false, see https://github.com/actions/runner/issues/241
|
|
1096
|
-
if (
|
|
1097
|
-
process.env.GITHUB_WORKFLOW &&
|
|
1098
|
-
// Check on FORCE_COLOR is to ensure it is prio over GitHub workflow check
|
|
1099
|
-
// in unit test we use process.env.FORCE_COLOR = 'false' to fake
|
|
1100
|
-
// that colors are not supported. Let it have priority
|
|
1101
|
-
process.env.FORCE_COLOR !== "false"
|
|
1102
|
-
) {
|
|
1103
|
-
ANSI.supported = true;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
const setRoundedPrecision = (
|
|
1107
|
-
number,
|
|
1108
|
-
{ decimals = 1, decimalsWhenSmall = decimals } = {},
|
|
1109
|
-
) => {
|
|
1110
|
-
return setDecimalsPrecision(number, {
|
|
1111
|
-
decimals,
|
|
1112
|
-
decimalsWhenSmall,
|
|
1113
|
-
transform: Math.round,
|
|
1114
|
-
});
|
|
1115
|
-
};
|
|
1116
|
-
|
|
1117
|
-
const setPrecision = (
|
|
1118
|
-
number,
|
|
1119
|
-
{ decimals = 1, decimalsWhenSmall = decimals } = {},
|
|
1120
|
-
) => {
|
|
1121
|
-
return setDecimalsPrecision(number, {
|
|
1122
|
-
decimals,
|
|
1123
|
-
decimalsWhenSmall,
|
|
1124
|
-
transform: parseInt,
|
|
1125
|
-
});
|
|
857
|
+
const setPrecision = (
|
|
858
|
+
number,
|
|
859
|
+
{ decimals = 1, decimalsWhenSmall = decimals } = {},
|
|
860
|
+
) => {
|
|
861
|
+
return setDecimalsPrecision(number, {
|
|
862
|
+
decimals,
|
|
863
|
+
decimalsWhenSmall,
|
|
864
|
+
transform: parseInt,
|
|
865
|
+
});
|
|
1126
866
|
};
|
|
1127
867
|
|
|
1128
868
|
const setDecimalsPrecision = (
|
|
@@ -1292,99 +1032,13 @@ const parseMs = (ms) => {
|
|
|
1292
1032
|
};
|
|
1293
1033
|
};
|
|
1294
1034
|
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
return process$1.env.TERM !== 'linux'; // Linux console (kernel)
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
return Boolean(process$1.env.WT_SESSION) // Windows Terminal
|
|
1301
|
-
|| Boolean(process$1.env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
|
|
1302
|
-
|| process$1.env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
|
|
1303
|
-
|| process$1.env.TERM_PROGRAM === 'Terminus-Sublime'
|
|
1304
|
-
|| process$1.env.TERM_PROGRAM === 'vscode'
|
|
1305
|
-
|| process$1.env.TERM === 'xterm-256color'
|
|
1306
|
-
|| process$1.env.TERM === 'alacritty'
|
|
1307
|
-
|| process$1.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
// see also https://github.com/sindresorhus/figures
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
const UNICODE = {
|
|
1314
|
-
supported: isUnicodeSupported(),
|
|
1315
|
-
|
|
1316
|
-
get COMMAND_RAW() {
|
|
1317
|
-
return UNICODE.supported ? `❯` : `>`;
|
|
1318
|
-
},
|
|
1319
|
-
get OK_RAW() {
|
|
1320
|
-
return UNICODE.supported ? `✔` : `√`;
|
|
1321
|
-
},
|
|
1322
|
-
get FAILURE_RAW() {
|
|
1323
|
-
return UNICODE.supported ? `✖` : `×`;
|
|
1324
|
-
},
|
|
1325
|
-
get DEBUG_RAW() {
|
|
1326
|
-
return UNICODE.supported ? `◆` : `♦`;
|
|
1327
|
-
},
|
|
1328
|
-
get INFO_RAW() {
|
|
1329
|
-
return UNICODE.supported ? `ℹ` : `i`;
|
|
1330
|
-
},
|
|
1331
|
-
get WARNING_RAW() {
|
|
1332
|
-
return UNICODE.supported ? `⚠` : `‼`;
|
|
1333
|
-
},
|
|
1334
|
-
get CIRCLE_CROSS_RAW() {
|
|
1335
|
-
return UNICODE.supported ? `ⓧ` : `(×)`;
|
|
1336
|
-
},
|
|
1337
|
-
get COMMAND() {
|
|
1338
|
-
return ANSI.color(UNICODE.COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
|
|
1339
|
-
},
|
|
1340
|
-
get OK() {
|
|
1341
|
-
return ANSI.color(UNICODE.OK_RAW, ANSI.GREEN);
|
|
1342
|
-
},
|
|
1343
|
-
get FAILURE() {
|
|
1344
|
-
return ANSI.color(UNICODE.FAILURE_RAW, ANSI.RED);
|
|
1345
|
-
},
|
|
1346
|
-
get DEBUG() {
|
|
1347
|
-
return ANSI.color(UNICODE.DEBUG_RAW, ANSI.GREY);
|
|
1348
|
-
},
|
|
1349
|
-
get INFO() {
|
|
1350
|
-
return ANSI.color(UNICODE.INFO_RAW, ANSI.BLUE);
|
|
1351
|
-
},
|
|
1352
|
-
get WARNING() {
|
|
1353
|
-
return ANSI.color(UNICODE.WARNING_RAW, ANSI.YELLOW);
|
|
1354
|
-
},
|
|
1355
|
-
get CIRCLE_CROSS() {
|
|
1356
|
-
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
1357
|
-
},
|
|
1358
|
-
get ELLIPSIS() {
|
|
1359
|
-
return UNICODE.supported ? `…` : `...`;
|
|
1360
|
-
},
|
|
1035
|
+
const humanizeFileSize = (numberOfBytes, { decimals, short } = {}) => {
|
|
1036
|
+
return inspectBytes(numberOfBytes, { decimals, short });
|
|
1361
1037
|
};
|
|
1362
1038
|
|
|
1363
|
-
const
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
Object.keys(details).forEach((key) => {
|
|
1367
|
-
const value = details[key];
|
|
1368
|
-
string += `
|
|
1369
|
-
--- ${key} ---
|
|
1370
|
-
${
|
|
1371
|
-
Array.isArray(value)
|
|
1372
|
-
? value.join(`
|
|
1373
|
-
`)
|
|
1374
|
-
: value
|
|
1375
|
-
}`;
|
|
1376
|
-
});
|
|
1377
|
-
|
|
1378
|
-
return string;
|
|
1379
|
-
};
|
|
1380
|
-
|
|
1381
|
-
const humanizeFileSize = (numberOfBytes, { decimals, short } = {}) => {
|
|
1382
|
-
return inspectBytes(numberOfBytes, { decimals, short });
|
|
1383
|
-
};
|
|
1384
|
-
|
|
1385
|
-
const humanizeMemory = (metricValue, { decimals, short } = {}) => {
|
|
1386
|
-
return inspectBytes(metricValue, { decimals, fixedDecimals: true, short });
|
|
1387
|
-
};
|
|
1039
|
+
const humanizeMemory = (metricValue, { decimals, short } = {}) => {
|
|
1040
|
+
return inspectBytes(metricValue, { decimals, fixedDecimals: true, short });
|
|
1041
|
+
};
|
|
1388
1042
|
|
|
1389
1043
|
const inspectBytes = (
|
|
1390
1044
|
number,
|
|
@@ -1579,6 +1233,361 @@ const fillLeft$1 = (value, biggestValue, char = " ") => {
|
|
|
1579
1233
|
return padded;
|
|
1580
1234
|
};
|
|
1581
1235
|
|
|
1236
|
+
const LOG_LEVEL_OFF = "off";
|
|
1237
|
+
|
|
1238
|
+
const LOG_LEVEL_DEBUG = "debug";
|
|
1239
|
+
|
|
1240
|
+
const LOG_LEVEL_INFO = "info";
|
|
1241
|
+
|
|
1242
|
+
const LOG_LEVEL_WARN = "warn";
|
|
1243
|
+
|
|
1244
|
+
const LOG_LEVEL_ERROR = "error";
|
|
1245
|
+
|
|
1246
|
+
const createLogger = ({ logLevel = LOG_LEVEL_INFO } = {}) => {
|
|
1247
|
+
if (logLevel === LOG_LEVEL_DEBUG) {
|
|
1248
|
+
return {
|
|
1249
|
+
level: "debug",
|
|
1250
|
+
levels: { debug: true, info: true, warn: true, error: true },
|
|
1251
|
+
debug,
|
|
1252
|
+
info,
|
|
1253
|
+
warn,
|
|
1254
|
+
error,
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
if (logLevel === LOG_LEVEL_INFO) {
|
|
1258
|
+
return {
|
|
1259
|
+
level: "info",
|
|
1260
|
+
levels: { debug: false, info: true, warn: true, error: true },
|
|
1261
|
+
debug: debugDisabled,
|
|
1262
|
+
info,
|
|
1263
|
+
warn,
|
|
1264
|
+
error,
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
if (logLevel === LOG_LEVEL_WARN) {
|
|
1268
|
+
return {
|
|
1269
|
+
level: "warn",
|
|
1270
|
+
levels: { debug: false, info: false, warn: true, error: true },
|
|
1271
|
+
debug: debugDisabled,
|
|
1272
|
+
info: infoDisabled,
|
|
1273
|
+
warn,
|
|
1274
|
+
error,
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
if (logLevel === LOG_LEVEL_ERROR) {
|
|
1278
|
+
return {
|
|
1279
|
+
level: "error",
|
|
1280
|
+
levels: { debug: false, info: false, warn: false, error: true },
|
|
1281
|
+
debug: debugDisabled,
|
|
1282
|
+
info: infoDisabled,
|
|
1283
|
+
warn: warnDisabled,
|
|
1284
|
+
error,
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
if (logLevel === LOG_LEVEL_OFF) {
|
|
1288
|
+
return {
|
|
1289
|
+
level: "off",
|
|
1290
|
+
levels: { debug: false, info: false, warn: false, error: false },
|
|
1291
|
+
debug: debugDisabled,
|
|
1292
|
+
info: infoDisabled,
|
|
1293
|
+
warn: warnDisabled,
|
|
1294
|
+
error: errorDisabled,
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
throw new Error(`unexpected logLevel.
|
|
1298
|
+
--- logLevel ---
|
|
1299
|
+
${logLevel}
|
|
1300
|
+
--- allowed log levels ---
|
|
1301
|
+
${LOG_LEVEL_OFF}
|
|
1302
|
+
${LOG_LEVEL_ERROR}
|
|
1303
|
+
${LOG_LEVEL_WARN}
|
|
1304
|
+
${LOG_LEVEL_INFO}
|
|
1305
|
+
${LOG_LEVEL_DEBUG}`);
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
const debug = (...args) => console.debug(...args);
|
|
1309
|
+
|
|
1310
|
+
const debugDisabled = () => {};
|
|
1311
|
+
|
|
1312
|
+
const info = (...args) => console.info(...args);
|
|
1313
|
+
|
|
1314
|
+
const infoDisabled = () => {};
|
|
1315
|
+
|
|
1316
|
+
const warn = (...args) => console.warn(...args);
|
|
1317
|
+
|
|
1318
|
+
const warnDisabled = () => {};
|
|
1319
|
+
|
|
1320
|
+
const error = (...args) => console.error(...args);
|
|
1321
|
+
|
|
1322
|
+
const errorDisabled = () => {};
|
|
1323
|
+
|
|
1324
|
+
/* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
|
|
1325
|
+
|
|
1326
|
+
const isBrowser = globalThis.window?.document !== undefined;
|
|
1327
|
+
|
|
1328
|
+
globalThis.process?.versions?.node !== undefined;
|
|
1329
|
+
|
|
1330
|
+
globalThis.process?.versions?.bun !== undefined;
|
|
1331
|
+
|
|
1332
|
+
globalThis.Deno?.version?.deno !== undefined;
|
|
1333
|
+
|
|
1334
|
+
globalThis.process?.versions?.electron !== undefined;
|
|
1335
|
+
|
|
1336
|
+
globalThis.navigator?.userAgent?.includes('jsdom') === true;
|
|
1337
|
+
|
|
1338
|
+
typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
|
|
1339
|
+
|
|
1340
|
+
typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
1341
|
+
|
|
1342
|
+
typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
|
|
1343
|
+
|
|
1344
|
+
typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
|
|
1345
|
+
|
|
1346
|
+
// Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
|
|
1347
|
+
const platform = globalThis.navigator?.userAgentData?.platform;
|
|
1348
|
+
|
|
1349
|
+
platform === 'macOS'
|
|
1350
|
+
|| globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
|
|
1351
|
+
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|
|
1352
|
+
|| globalThis.process?.platform === 'darwin';
|
|
1353
|
+
|
|
1354
|
+
platform === 'Windows'
|
|
1355
|
+
|| globalThis.navigator?.platform === 'Win32'
|
|
1356
|
+
|| globalThis.process?.platform === 'win32';
|
|
1357
|
+
|
|
1358
|
+
platform === 'Linux'
|
|
1359
|
+
|| globalThis.navigator?.platform?.startsWith('Linux') === true
|
|
1360
|
+
|| globalThis.navigator?.userAgent?.includes(' Linux ') === true
|
|
1361
|
+
|| globalThis.process?.platform === 'linux';
|
|
1362
|
+
|
|
1363
|
+
platform === 'Android'
|
|
1364
|
+
|| globalThis.navigator?.platform === 'Android'
|
|
1365
|
+
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|
|
1366
|
+
|| globalThis.process?.platform === 'android';
|
|
1367
|
+
|
|
1368
|
+
const ESC = '\u001B[';
|
|
1369
|
+
|
|
1370
|
+
!isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
1371
|
+
const isWindows$3 = !isBrowser && process$1.platform === 'win32';
|
|
1372
|
+
|
|
1373
|
+
isBrowser ? () => {
|
|
1374
|
+
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
1375
|
+
} : process$1.cwd;
|
|
1376
|
+
|
|
1377
|
+
const cursorUp = (count = 1) => ESC + count + 'A';
|
|
1378
|
+
|
|
1379
|
+
const cursorLeft = ESC + 'G';
|
|
1380
|
+
|
|
1381
|
+
const eraseLines = count => {
|
|
1382
|
+
let clear = '';
|
|
1383
|
+
|
|
1384
|
+
for (let i = 0; i < count; i++) {
|
|
1385
|
+
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
if (count) {
|
|
1389
|
+
clear += cursorLeft;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
return clear;
|
|
1393
|
+
};
|
|
1394
|
+
const eraseLine = ESC + '2K';
|
|
1395
|
+
const eraseScreen = ESC + '2J';
|
|
1396
|
+
|
|
1397
|
+
const clearTerminal = isWindows$3
|
|
1398
|
+
? `${eraseScreen}${ESC}0f`
|
|
1399
|
+
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
1400
|
+
// 2. Erases the whole screen including scrollback buffer
|
|
1401
|
+
// 3. Moves cursor to the top-left position
|
|
1402
|
+
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
1403
|
+
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
1404
|
+
|
|
1405
|
+
/*
|
|
1406
|
+
* see also https://github.com/vadimdemedes/ink
|
|
1407
|
+
*/
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
const createDynamicLog = ({
|
|
1411
|
+
stream = process.stdout,
|
|
1412
|
+
clearTerminalAllowed,
|
|
1413
|
+
onVerticalOverflow = () => {},
|
|
1414
|
+
onWriteFromOutside = () => {},
|
|
1415
|
+
} = {}) => {
|
|
1416
|
+
const { columns = 80, rows = 24 } = stream;
|
|
1417
|
+
const dynamicLog = {
|
|
1418
|
+
destroyed: false,
|
|
1419
|
+
onVerticalOverflow,
|
|
1420
|
+
onWriteFromOutside,
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
let lastOutput = "";
|
|
1424
|
+
let lastOutputFromOutside = "";
|
|
1425
|
+
let clearAttemptResult;
|
|
1426
|
+
let writing = false;
|
|
1427
|
+
|
|
1428
|
+
const getErasePreviousOutput = () => {
|
|
1429
|
+
// nothing to clear
|
|
1430
|
+
if (!lastOutput) {
|
|
1431
|
+
return "";
|
|
1432
|
+
}
|
|
1433
|
+
if (clearAttemptResult !== undefined) {
|
|
1434
|
+
return "";
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
const logLines = lastOutput.split(/\r\n|\r|\n/);
|
|
1438
|
+
let visualLineCount = 0;
|
|
1439
|
+
for (const logLine of logLines) {
|
|
1440
|
+
const width = stringWidth(logLine);
|
|
1441
|
+
if (width === 0) {
|
|
1442
|
+
visualLineCount++;
|
|
1443
|
+
} else {
|
|
1444
|
+
visualLineCount += Math.ceil(width / columns);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
if (visualLineCount > rows) {
|
|
1449
|
+
if (clearTerminalAllowed) {
|
|
1450
|
+
clearAttemptResult = true;
|
|
1451
|
+
return clearTerminal;
|
|
1452
|
+
}
|
|
1453
|
+
// the whole log cannot be cleared because it's vertically to long
|
|
1454
|
+
// (longer than terminal height)
|
|
1455
|
+
// readline.moveCursor cannot move cursor higher than screen height
|
|
1456
|
+
// it means we would only clear the visible part of the log
|
|
1457
|
+
// better keep the log untouched
|
|
1458
|
+
clearAttemptResult = false;
|
|
1459
|
+
dynamicLog.onVerticalOverflow();
|
|
1460
|
+
return "";
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
clearAttemptResult = true;
|
|
1464
|
+
return eraseLines(visualLineCount);
|
|
1465
|
+
};
|
|
1466
|
+
|
|
1467
|
+
const update = (string) => {
|
|
1468
|
+
if (dynamicLog.destroyed) {
|
|
1469
|
+
throw new Error("Cannot write log after destroy");
|
|
1470
|
+
}
|
|
1471
|
+
let stringToWrite = string;
|
|
1472
|
+
if (lastOutput) {
|
|
1473
|
+
if (lastOutputFromOutside) {
|
|
1474
|
+
// We don't want to clear logs written by other code,
|
|
1475
|
+
// it makes output unreadable and might erase precious information
|
|
1476
|
+
// To detect this we put a spy on the stream.
|
|
1477
|
+
// The spy is required only if we actually wrote something in the stream
|
|
1478
|
+
// something else than this code has written in the stream
|
|
1479
|
+
// so we just write without clearing (append instead of replacing)
|
|
1480
|
+
lastOutput = "";
|
|
1481
|
+
lastOutputFromOutside = "";
|
|
1482
|
+
} else {
|
|
1483
|
+
stringToWrite = `${getErasePreviousOutput()}${string}`;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
writing = true;
|
|
1487
|
+
stream.write(stringToWrite);
|
|
1488
|
+
lastOutput = string;
|
|
1489
|
+
writing = false;
|
|
1490
|
+
clearAttemptResult = undefined;
|
|
1491
|
+
};
|
|
1492
|
+
|
|
1493
|
+
const clearDuringFunctionCall = (
|
|
1494
|
+
callback,
|
|
1495
|
+
ouputAfterCallback = lastOutput,
|
|
1496
|
+
) => {
|
|
1497
|
+
// 1. Erase the current log
|
|
1498
|
+
// 2. Call callback (expect to write something on stdout)
|
|
1499
|
+
// 3. Restore the current log
|
|
1500
|
+
// During step 2. we expect a "write from outside" so we uninstall
|
|
1501
|
+
// the stream spy during function call
|
|
1502
|
+
update("");
|
|
1503
|
+
|
|
1504
|
+
writing = true;
|
|
1505
|
+
callback();
|
|
1506
|
+
writing = false;
|
|
1507
|
+
|
|
1508
|
+
update(ouputAfterCallback);
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1511
|
+
const writeFromOutsideEffect = (value) => {
|
|
1512
|
+
if (!lastOutput) {
|
|
1513
|
+
// we don't care if the log never wrote anything
|
|
1514
|
+
// or if last update() wrote an empty string
|
|
1515
|
+
return;
|
|
1516
|
+
}
|
|
1517
|
+
if (writing) {
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1520
|
+
lastOutputFromOutside = value;
|
|
1521
|
+
dynamicLog.onWriteFromOutside(value);
|
|
1522
|
+
};
|
|
1523
|
+
|
|
1524
|
+
let removeStreamSpy;
|
|
1525
|
+
if (stream === process.stdout) {
|
|
1526
|
+
const removeStdoutSpy = spyStreamOutput(
|
|
1527
|
+
process.stdout,
|
|
1528
|
+
writeFromOutsideEffect,
|
|
1529
|
+
);
|
|
1530
|
+
const removeStderrSpy = spyStreamOutput(
|
|
1531
|
+
process.stderr,
|
|
1532
|
+
writeFromOutsideEffect,
|
|
1533
|
+
);
|
|
1534
|
+
removeStreamSpy = () => {
|
|
1535
|
+
removeStdoutSpy();
|
|
1536
|
+
removeStderrSpy();
|
|
1537
|
+
};
|
|
1538
|
+
} else {
|
|
1539
|
+
removeStreamSpy = spyStreamOutput(stream, writeFromOutsideEffect);
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
const destroy = () => {
|
|
1543
|
+
dynamicLog.destroyed = true;
|
|
1544
|
+
if (removeStreamSpy) {
|
|
1545
|
+
removeStreamSpy();
|
|
1546
|
+
removeStreamSpy = null;
|
|
1547
|
+
lastOutput = "";
|
|
1548
|
+
lastOutputFromOutside = "";
|
|
1549
|
+
}
|
|
1550
|
+
};
|
|
1551
|
+
|
|
1552
|
+
Object.assign(dynamicLog, {
|
|
1553
|
+
update,
|
|
1554
|
+
destroy,
|
|
1555
|
+
stream,
|
|
1556
|
+
clearDuringFunctionCall,
|
|
1557
|
+
});
|
|
1558
|
+
return dynamicLog;
|
|
1559
|
+
};
|
|
1560
|
+
|
|
1561
|
+
// maybe https://github.com/gajus/output-interceptor/tree/v3.0.0 ?
|
|
1562
|
+
// the problem with listening data on stdout
|
|
1563
|
+
// is that node.js will later throw error if stream gets closed
|
|
1564
|
+
// while something listening data on it
|
|
1565
|
+
const spyStreamOutput = (stream, callback) => {
|
|
1566
|
+
const originalWrite = stream.write;
|
|
1567
|
+
|
|
1568
|
+
let output = "";
|
|
1569
|
+
let installed = true;
|
|
1570
|
+
|
|
1571
|
+
stream.write = function (...args /* chunk, encoding, callback */) {
|
|
1572
|
+
output += args;
|
|
1573
|
+
callback(output);
|
|
1574
|
+
return originalWrite.call(stream, ...args);
|
|
1575
|
+
};
|
|
1576
|
+
|
|
1577
|
+
const uninstall = () => {
|
|
1578
|
+
if (!installed) {
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
stream.write = originalWrite;
|
|
1582
|
+
installed = false;
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
return () => {
|
|
1586
|
+
uninstall();
|
|
1587
|
+
return output;
|
|
1588
|
+
};
|
|
1589
|
+
};
|
|
1590
|
+
|
|
1582
1591
|
const urlToScheme = (url) => {
|
|
1583
1592
|
const urlString = String(url);
|
|
1584
1593
|
const colonIndex = urlString.indexOf(":");
|
|
@@ -7800,7 +7809,11 @@ const nodeChildProcess = ({
|
|
|
7800
7809
|
env = {
|
|
7801
7810
|
...env,
|
|
7802
7811
|
JSENV: true,
|
|
7803
|
-
FORCE_COLOR:
|
|
7812
|
+
FORCE_COLOR:
|
|
7813
|
+
supportsColor.stdout ||
|
|
7814
|
+
// GitHub workflow does support ANSI but "supports-color" returns false
|
|
7815
|
+
// because stream.isTTY returns false, see https://github.com/actions/runner/issues/241
|
|
7816
|
+
process.env.GITHUB_WORKFLOW,
|
|
7804
7817
|
};
|
|
7805
7818
|
|
|
7806
7819
|
return {
|
|
@@ -8275,7 +8288,11 @@ const nodeWorkerThread = ({
|
|
|
8275
8288
|
env = {
|
|
8276
8289
|
...env,
|
|
8277
8290
|
JSENV: true,
|
|
8278
|
-
FORCE_COLOR:
|
|
8291
|
+
FORCE_COLOR:
|
|
8292
|
+
supportsColor.stdout ||
|
|
8293
|
+
// GitHub workflow does support ANSI but "supports-color" returns false
|
|
8294
|
+
// because stream.isTTY returns false, see https://github.com/actions/runner/issues/241
|
|
8295
|
+
process.env.GITHUB_WORKFLOW,
|
|
8279
8296
|
};
|
|
8280
8297
|
|
|
8281
8298
|
return {
|