@jsenv/core
Version:
Tool to develop, test and build js projects
709 lines (625 loc) • 17.1 kB
JavaScript
import process from "node:process";
import os from "node:os";
import tty from "node:tty";
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
const position = argv.indexOf(prefix + flag);
const terminatorPosition = argv.indexOf('--');
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
const {env} = process;
let flagForceColor;
if (
hasFlag('no-color')
|| hasFlag('no-colors')
|| hasFlag('color=false')
|| hasFlag('color=never')
) {
flagForceColor = 0;
} else if (
hasFlag('color')
|| hasFlag('colors')
|| hasFlag('color=true')
|| hasFlag('color=always')
) {
flagForceColor = 1;
}
function envForceColor() {
if (!('FORCE_COLOR' in env)) {
return;
}
if (env.FORCE_COLOR === 'true') {
return 1;
}
if (env.FORCE_COLOR === 'false') {
return 0;
}
if (env.FORCE_COLOR.length === 0) {
return 1;
}
const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
if (![0, 1, 2, 3].includes(level)) {
return;
}
return level;
}
function translateLevel(level) {
if (level === 0) {
return false;
}
return {
level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3,
};
}
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
const noFlagForceColor = envForceColor();
if (noFlagForceColor !== undefined) {
flagForceColor = noFlagForceColor;
}
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
if (forceColor === 0) {
return 0;
}
if (sniffFlags) {
if (hasFlag('color=16m')
|| hasFlag('color=full')
|| hasFlag('color=truecolor')) {
return 3;
}
if (hasFlag('color=256')) {
return 2;
}
}
// Check for Azure DevOps pipelines.
// Has to be above the `!streamIsTTY` check.
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
return 1;
}
if (haveStream && !streamIsTTY && forceColor === undefined) {
return 0;
}
const min = forceColor || 0;
if (env.TERM === 'dumb') {
return min;
}
if (process.platform === 'win32') {
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
const osRelease = os.release().split('.');
if (
Number(osRelease[0]) >= 10
&& Number(osRelease[2]) >= 10_586
) {
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
}
return 1;
}
if ('CI' in env) {
if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
return 3;
}
if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
return 1;
}
return min;
}
if ('TEAMCITY_VERSION' in env) {
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
}
if (env.COLORTERM === 'truecolor') {
return 3;
}
if (env.TERM === 'xterm-kitty') {
return 3;
}
if ('TERM_PROGRAM' in env) {
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
switch (env.TERM_PROGRAM) {
case 'iTerm.app': {
return version >= 3 ? 3 : 2;
}
case 'Apple_Terminal': {
return 2;
}
// No default
}
}
if (/-256(color)?$/i.test(env.TERM)) {
return 2;
}
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
return 1;
}
if ('COLORTERM' in env) {
return 1;
}
return min;
}
function createSupportsColor(stream, options = {}) {
const level = _supportsColor(stream, {
streamIsTTY: stream && stream.isTTY,
...options,
});
return translateLevel(level);
}
({
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
});
function isUnicodeSupported() {
const {env} = process;
const {TERM, TERM_PROGRAM} = env;
if (process.platform !== 'win32') {
return TERM !== 'linux'; // Linux console (kernel)
}
return Boolean(env.WT_SESSION) // Windows Terminal
|| Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
|| env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
|| TERM_PROGRAM === 'Terminus-Sublime'
|| TERM_PROGRAM === 'vscode'
|| TERM === 'xterm-256color'
|| TERM === 'alacritty'
|| TERM === 'rxvt-unicode'
|| TERM === 'rxvt-unicode-256color'
|| env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
}
function ansiRegex({onlyFirst = false} = {}) {
// Valid string terminator sequences are BEL, ESC\, and 0x9c
const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
const pattern = [
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}
const regex = ansiRegex();
function stripAnsi(string) {
if (typeof string !== 'string') {
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
}
// Even though the regex is global, we don't need to reset the `.lastIndex`
// because unlike `.exec()` and `.test()`, `.replace()` does it automatically
// and doing it manually has a performance penalty.
return string.replace(regex, '');
}
const r = String.raw,
e = r`\p{Emoji}(?:\p{EMod}|[\u{E0020}-\u{E007E}]+\u{E007F}|\uFE0F?\u20E3?)`;
const emojiRegex = () => new RegExp(r`\p{RI}{2}|(?)${e}(?:\u200D${e})*`, 'gu');
// Generated code.
function isAmbiguous(x) {
return x === 0xA1
|| x === 0xA4
|| x === 0xA7
|| x === 0xA8
|| x === 0xAA
|| x === 0xAD
|| x === 0xAE
|| x >= 0xB0 && x <= 0xB4
|| x >= 0xB6 && x <= 0xBA
|| x >= 0xBC && x <= 0xBF
|| x === 0xC6
|| x === 0xD0
|| x === 0xD7
|| x === 0xD8
|| x >= 0xDE && x <= 0xE1
|| x === 0xE6
|| x >= 0xE8 && x <= 0xEA
|| x === 0xEC
|| x === 0xED
|| x === 0xF0
|| x === 0xF2
|| x === 0xF3
|| x >= 0xF7 && x <= 0xFA
|| x === 0xFC
|| x === 0xFE
|| x === 0x101
|| x === 0x111
|| x === 0x113
|| x === 0x11B
|| x === 0x126
|| x === 0x127
|| x === 0x12B
|| x >= 0x131 && x <= 0x133
|| x === 0x138
|| x >= 0x13F && x <= 0x142
|| x === 0x144
|| x >= 0x148 && x <= 0x14B
|| x === 0x14D
|| x === 0x152
|| x === 0x153
|| x === 0x166
|| x === 0x167
|| x === 0x16B
|| x === 0x1CE
|| x === 0x1D0
|| x === 0x1D2
|| x === 0x1D4
|| x === 0x1D6
|| x === 0x1D8
|| x === 0x1DA
|| x === 0x1DC
|| x === 0x251
|| x === 0x261
|| x === 0x2C4
|| x === 0x2C7
|| x >= 0x2C9 && x <= 0x2CB
|| x === 0x2CD
|| x === 0x2D0
|| x >= 0x2D8 && x <= 0x2DB
|| x === 0x2DD
|| x === 0x2DF
|| x >= 0x300 && x <= 0x36F
|| x >= 0x391 && x <= 0x3A1
|| x >= 0x3A3 && x <= 0x3A9
|| x >= 0x3B1 && x <= 0x3C1
|| x >= 0x3C3 && x <= 0x3C9
|| x === 0x401
|| x >= 0x410 && x <= 0x44F
|| x === 0x451
|| x === 0x2010
|| x >= 0x2013 && x <= 0x2016
|| x === 0x2018
|| x === 0x2019
|| x === 0x201C
|| x === 0x201D
|| x >= 0x2020 && x <= 0x2022
|| x >= 0x2024 && x <= 0x2027
|| x === 0x2030
|| x === 0x2032
|| x === 0x2033
|| x === 0x2035
|| x === 0x203B
|| x === 0x203E
|| x === 0x2074
|| x === 0x207F
|| x >= 0x2081 && x <= 0x2084
|| x === 0x20AC
|| x === 0x2103
|| x === 0x2105
|| x === 0x2109
|| x === 0x2113
|| x === 0x2116
|| x === 0x2121
|| x === 0x2122
|| x === 0x2126
|| x === 0x212B
|| x === 0x2153
|| x === 0x2154
|| x >= 0x215B && x <= 0x215E
|| x >= 0x2160 && x <= 0x216B
|| x >= 0x2170 && x <= 0x2179
|| x === 0x2189
|| x >= 0x2190 && x <= 0x2199
|| x === 0x21B8
|| x === 0x21B9
|| x === 0x21D2
|| x === 0x21D4
|| x === 0x21E7
|| x === 0x2200
|| x === 0x2202
|| x === 0x2203
|| x === 0x2207
|| x === 0x2208
|| x === 0x220B
|| x === 0x220F
|| x === 0x2211
|| x === 0x2215
|| x === 0x221A
|| x >= 0x221D && x <= 0x2220
|| x === 0x2223
|| x === 0x2225
|| x >= 0x2227 && x <= 0x222C
|| x === 0x222E
|| x >= 0x2234 && x <= 0x2237
|| x === 0x223C
|| x === 0x223D
|| x === 0x2248
|| x === 0x224C
|| x === 0x2252
|| x === 0x2260
|| x === 0x2261
|| x >= 0x2264 && x <= 0x2267
|| x === 0x226A
|| x === 0x226B
|| x === 0x226E
|| x === 0x226F
|| x === 0x2282
|| x === 0x2283
|| x === 0x2286
|| x === 0x2287
|| x === 0x2295
|| x === 0x2299
|| x === 0x22A5
|| x === 0x22BF
|| x === 0x2312
|| x >= 0x2460 && x <= 0x24E9
|| x >= 0x24EB && x <= 0x254B
|| x >= 0x2550 && x <= 0x2573
|| x >= 0x2580 && x <= 0x258F
|| x >= 0x2592 && x <= 0x2595
|| x === 0x25A0
|| x === 0x25A1
|| x >= 0x25A3 && x <= 0x25A9
|| x === 0x25B2
|| x === 0x25B3
|| x === 0x25B6
|| x === 0x25B7
|| x === 0x25BC
|| x === 0x25BD
|| x === 0x25C0
|| x === 0x25C1
|| x >= 0x25C6 && x <= 0x25C8
|| x === 0x25CB
|| x >= 0x25CE && x <= 0x25D1
|| x >= 0x25E2 && x <= 0x25E5
|| x === 0x25EF
|| x === 0x2605
|| x === 0x2606
|| x === 0x2609
|| x === 0x260E
|| x === 0x260F
|| x === 0x261C
|| x === 0x261E
|| x === 0x2640
|| x === 0x2642
|| x === 0x2660
|| x === 0x2661
|| x >= 0x2663 && x <= 0x2665
|| x >= 0x2667 && x <= 0x266A
|| x === 0x266C
|| x === 0x266D
|| x === 0x266F
|| x === 0x269E
|| x === 0x269F
|| x === 0x26BF
|| x >= 0x26C6 && x <= 0x26CD
|| x >= 0x26CF && x <= 0x26D3
|| x >= 0x26D5 && x <= 0x26E1
|| x === 0x26E3
|| x === 0x26E8
|| x === 0x26E9
|| x >= 0x26EB && x <= 0x26F1
|| x === 0x26F4
|| x >= 0x26F6 && x <= 0x26F9
|| x === 0x26FB
|| x === 0x26FC
|| x === 0x26FE
|| x === 0x26FF
|| x === 0x273D
|| x >= 0x2776 && x <= 0x277F
|| x >= 0x2B56 && x <= 0x2B59
|| x >= 0x3248 && x <= 0x324F
|| x >= 0xE000 && x <= 0xF8FF
|| x >= 0xFE00 && x <= 0xFE0F
|| x === 0xFFFD
|| x >= 0x1F100 && x <= 0x1F10A
|| x >= 0x1F110 && x <= 0x1F12D
|| x >= 0x1F130 && x <= 0x1F169
|| x >= 0x1F170 && x <= 0x1F18D
|| x === 0x1F18F
|| x === 0x1F190
|| x >= 0x1F19B && x <= 0x1F1AC
|| x >= 0xE0100 && x <= 0xE01EF
|| x >= 0xF0000 && x <= 0xFFFFD
|| x >= 0x100000 && x <= 0x10FFFD;
}
function isFullWidth(x) {
return x === 0x3000
|| x >= 0xFF01 && x <= 0xFF60
|| x >= 0xFFE0 && x <= 0xFFE6;
}
function isWide(x) {
return x >= 0x1100 && x <= 0x115F
|| x === 0x231A
|| x === 0x231B
|| x === 0x2329
|| x === 0x232A
|| x >= 0x23E9 && x <= 0x23EC
|| x === 0x23F0
|| x === 0x23F3
|| x === 0x25FD
|| x === 0x25FE
|| x === 0x2614
|| x === 0x2615
|| x >= 0x2630 && x <= 0x2637
|| x >= 0x2648 && x <= 0x2653
|| x === 0x267F
|| x >= 0x268A && x <= 0x268F
|| x === 0x2693
|| x === 0x26A1
|| x === 0x26AA
|| x === 0x26AB
|| x === 0x26BD
|| x === 0x26BE
|| x === 0x26C4
|| x === 0x26C5
|| x === 0x26CE
|| x === 0x26D4
|| x === 0x26EA
|| x === 0x26F2
|| x === 0x26F3
|| x === 0x26F5
|| x === 0x26FA
|| x === 0x26FD
|| x === 0x2705
|| x === 0x270A
|| x === 0x270B
|| x === 0x2728
|| x === 0x274C
|| x === 0x274E
|| x >= 0x2753 && x <= 0x2755
|| x === 0x2757
|| x >= 0x2795 && x <= 0x2797
|| x === 0x27B0
|| x === 0x27BF
|| x === 0x2B1B
|| x === 0x2B1C
|| x === 0x2B50
|| x === 0x2B55
|| x >= 0x2E80 && x <= 0x2E99
|| x >= 0x2E9B && x <= 0x2EF3
|| x >= 0x2F00 && x <= 0x2FD5
|| x >= 0x2FF0 && x <= 0x2FFF
|| x >= 0x3001 && x <= 0x303E
|| x >= 0x3041 && x <= 0x3096
|| x >= 0x3099 && x <= 0x30FF
|| x >= 0x3105 && x <= 0x312F
|| x >= 0x3131 && x <= 0x318E
|| x >= 0x3190 && x <= 0x31E5
|| x >= 0x31EF && x <= 0x321E
|| x >= 0x3220 && x <= 0x3247
|| x >= 0x3250 && x <= 0xA48C
|| x >= 0xA490 && x <= 0xA4C6
|| x >= 0xA960 && x <= 0xA97C
|| x >= 0xAC00 && x <= 0xD7A3
|| x >= 0xF900 && x <= 0xFAFF
|| x >= 0xFE10 && x <= 0xFE19
|| x >= 0xFE30 && x <= 0xFE52
|| x >= 0xFE54 && x <= 0xFE66
|| x >= 0xFE68 && x <= 0xFE6B
|| x >= 0x16FE0 && x <= 0x16FE4
|| x === 0x16FF0
|| x === 0x16FF1
|| x >= 0x17000 && x <= 0x187F7
|| x >= 0x18800 && x <= 0x18CD5
|| x >= 0x18CFF && x <= 0x18D08
|| x >= 0x1AFF0 && x <= 0x1AFF3
|| x >= 0x1AFF5 && x <= 0x1AFFB
|| x === 0x1AFFD
|| x === 0x1AFFE
|| x >= 0x1B000 && x <= 0x1B122
|| x === 0x1B132
|| x >= 0x1B150 && x <= 0x1B152
|| x === 0x1B155
|| x >= 0x1B164 && x <= 0x1B167
|| x >= 0x1B170 && x <= 0x1B2FB
|| x >= 0x1D300 && x <= 0x1D356
|| x >= 0x1D360 && x <= 0x1D376
|| x === 0x1F004
|| x === 0x1F0CF
|| x === 0x1F18E
|| x >= 0x1F191 && x <= 0x1F19A
|| x >= 0x1F200 && x <= 0x1F202
|| x >= 0x1F210 && x <= 0x1F23B
|| x >= 0x1F240 && x <= 0x1F248
|| x === 0x1F250
|| x === 0x1F251
|| x >= 0x1F260 && x <= 0x1F265
|| x >= 0x1F300 && x <= 0x1F320
|| x >= 0x1F32D && x <= 0x1F335
|| x >= 0x1F337 && x <= 0x1F37C
|| x >= 0x1F37E && x <= 0x1F393
|| x >= 0x1F3A0 && x <= 0x1F3CA
|| x >= 0x1F3CF && x <= 0x1F3D3
|| x >= 0x1F3E0 && x <= 0x1F3F0
|| x === 0x1F3F4
|| x >= 0x1F3F8 && x <= 0x1F43E
|| x === 0x1F440
|| x >= 0x1F442 && x <= 0x1F4FC
|| x >= 0x1F4FF && x <= 0x1F53D
|| x >= 0x1F54B && x <= 0x1F54E
|| x >= 0x1F550 && x <= 0x1F567
|| x === 0x1F57A
|| x === 0x1F595
|| x === 0x1F596
|| x === 0x1F5A4
|| x >= 0x1F5FB && x <= 0x1F64F
|| x >= 0x1F680 && x <= 0x1F6C5
|| x === 0x1F6CC
|| x >= 0x1F6D0 && x <= 0x1F6D2
|| x >= 0x1F6D5 && x <= 0x1F6D7
|| x >= 0x1F6DC && x <= 0x1F6DF
|| x === 0x1F6EB
|| x === 0x1F6EC
|| x >= 0x1F6F4 && x <= 0x1F6FC
|| x >= 0x1F7E0 && x <= 0x1F7EB
|| x === 0x1F7F0
|| x >= 0x1F90C && x <= 0x1F93A
|| x >= 0x1F93C && x <= 0x1F945
|| x >= 0x1F947 && x <= 0x1F9FF
|| x >= 0x1FA70 && x <= 0x1FA7C
|| x >= 0x1FA80 && x <= 0x1FA89
|| x >= 0x1FA8F && x <= 0x1FAC6
|| x >= 0x1FACE && x <= 0x1FADC
|| x >= 0x1FADF && x <= 0x1FAE9
|| x >= 0x1FAF0 && x <= 0x1FAF8
|| x >= 0x20000 && x <= 0x2FFFD
|| x >= 0x30000 && x <= 0x3FFFD;
}
function validate(codePoint) {
if (!Number.isSafeInteger(codePoint)) {
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
}
}
function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {
validate(codePoint);
if (
isFullWidth(codePoint)
|| isWide(codePoint)
|| (ambiguousAsWide && isAmbiguous(codePoint))
) {
return 2;
}
return 1;
}
/* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
const isBrowser = globalThis.window?.document !== undefined;
globalThis.process?.versions?.node !== undefined;
globalThis.process?.versions?.bun !== undefined;
globalThis.Deno?.version?.deno !== undefined;
globalThis.process?.versions?.electron !== undefined;
globalThis.navigator?.userAgent?.includes('jsdom') === true;
typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
// Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
const platform = globalThis.navigator?.userAgentData?.platform;
platform === 'macOS'
|| globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|| globalThis.process?.platform === 'darwin';
platform === 'Windows'
|| globalThis.navigator?.platform === 'Win32'
|| globalThis.process?.platform === 'win32';
platform === 'Linux'
|| globalThis.navigator?.platform?.startsWith('Linux') === true
|| globalThis.navigator?.userAgent?.includes(' Linux ') === true
|| globalThis.process?.platform === 'linux';
platform === 'Android'
|| globalThis.navigator?.platform === 'Android'
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|| globalThis.process?.platform === 'android';
const ESC = '\u001B[';
!isBrowser && process.env.TERM_PROGRAM === 'Apple_Terminal';
const isWindows = !isBrowser && process.platform === 'win32';
isBrowser ? () => {
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
} : process.cwd;
const cursorUp = (count = 1) => ESC + count + 'A';
const cursorLeft = ESC + 'G';
const eraseLines = count => {
let clear = '';
for (let i = 0; i < count; i++) {
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
}
if (count) {
clear += cursorLeft;
}
return clear;
};
const eraseLine = ESC + '2K';
const eraseScreen = ESC + '2J';
const clearTerminal = isWindows
? `${eraseScreen}${ESC}0f`
// 1. Erases the screen (Only done in case `2` is not supported)
// 2. Erases the whole screen including scrollback buffer
// 3. Moves cursor to the top-left position
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
: `${eraseScreen}${ESC}3J${ESC}H`;
export { clearTerminal, createSupportsColor, eastAsianWidth, emojiRegex, eraseLines, isUnicodeSupported, stripAnsi };