@serpent/common-cli
Version:
通用的 cli 相关的函数
220 lines (209 loc) • 6.85 kB
JavaScript
import { a as isWin$1 } from './supportColor-2e661db8.mjs';
import { _ as _stripAnsi } from './format-e8a6577a.mjs';
export { f as format } from './format-e8a6577a.mjs';
import { a as table$1, _ as _cliTextSize } from './table-75b962e9.mjs';
import { parseVersion } from './version.mjs';
import { execFileSync } from 'node:child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import 'os';
import './_commonjsHelpers-7d1333e8.mjs';
import 'util';
import './satisfies-144b0f35.mjs';
/**
* 判断是否是 window 系统
*/
var isWin = isWin$1;
/**
* 去掉字符串中的 ansi escape 字符
*/
function stripAnsi(str) {
// 直接使用 mora-scripts 的函数,要确保 mora-scripts 经常更新
// 因为 mora-scripts 内部很多功能都用了这个
return _stripAnsi(str);
}
/**
* ansi code 的正则
*/
var GLOBAL_ANSI_REGEXP = _stripAnsi.gre;
/**
* 将一个二维的字符串数组,转化成一个 table 格式的字符串,方便在终端上显示,主要特点有:
*
* 1. 精确计算字符的宽度,自动换行:很多老外写的类似的库都采用 str.length 来得到字符串在终端上的显示长度,
* 但是,中文在终端上一般占用两个字符,而且不同系统上字符长度也会不一样
* 2. 自动重置颜色:当一个 cell 中有颜色时,如果不重置色值,它是会影响后面 cell 的
* 3. 判断是否超出屏幕大小:如果超出,自动截断最宽的一行
*
* @param rows table 中每个 cell 中的字符串,是个二维的字符串数组
* @return table 化的字符串
*
* @example
*
* ```
* table([
* ['a', 'b', 'c'],
* ['d', 'ee', 'f']
* ])
*
* // ab c
* // deef
* ```
*
* @see {@link https://github.com/qiu8310/tty-wrap/tree/0.1.0 tty-wrap@0.1.0}
*/
function table(arr) {
return table$1(arr);
}
/*
A hyperlink is opened upon encountering an OSC 8 escape sequence with the target URI. The syntax is
OSC 8 ; params ; URI BEL|ST
Following this, all subsequent cells that are painted are hyperlinks to this target. A hyperlink is closed with the same escape sequence, omitting the parameters and the URI but keeping the separators:
OSC 8 ; ; BEL|ST
const ST = '\u001B\\';
*/
var OSC = '\u001B]';
var BEL = '\u0007';
var SEP = ';';
/**
* 终端上输出带下划线的链接,参考 terminal-link 模块实现
*/
function termLink(text, uri, options) {
if (options === void 0) { options = {}; }
if (supportTermLink(options.target)) {
return hyperlink(text, uri);
}
if (options.fallback) {
return options.fallback(text, uri);
}
return "".concat(text, " (\u200B").concat(uri, "\u200B)");
}
/**
* 判断是否支持在终端上显示 hyperlink,基于 supports-hyperlinks 模块
*/
function supportTermLink(stream) {
var _a;
if (stream === void 0) { stream = process.stdout; }
var env = process.env;
// Netlify does not run a TTY, it does not need `supportsColor` check
if ('NETLIFY' in env)
return true;
if (stream && !stream.isTTY)
return false;
if (process.platform === 'win32')
return false;
if ('CI' in env)
return false;
if ('TEAMCITY_VERSION' in env)
return false;
if ('TERM_PROGRAM' in env) {
var version = parseVersion((_a = env.TERM_PROGRAM_VERSION) !== null && _a !== void 0 ? _a : '');
if (version) {
switch (env.TERM_PROGRAM) {
case 'iTerm.app':
if (version.major === 3)
return version.minor >= 1;
return version.major > 3;
case 'vscode':
return version.major > 1 || version.major === 1 && version.minor >= 72;
}
}
}
return false;
}
function hyperlink(text, uri) {
return [
OSC,
'8',
SEP,
'',
SEP,
uri,
BEL,
text,
OSC,
'8',
SEP,
SEP,
BEL,
].join('');
}
/**
* 返回终端的宽高
* @see 参考 {@link https://github.com/sindresorhus/term-size/ term-size}
*/
function termSize() {
var env = process.env, stdout = process.stdout, stderr = process.stderr, platform = process.platform;
for (var _i = 0, _a = [stdout, stderr]; _i < _a.length; _i++) {
var std = _a[_i];
if (std && std.columns && std.rows) {
return size(std.columns, std.rows);
}
if (std && std.getWindowSize) {
var _b = std.getWindowSize(), w = _b[0], h = _b[1];
if (w && h)
return size(w, h);
}
}
if (env.COLUMNS && env.LINES) {
return size(env.COLUMNS, env.LINES);
}
if (platform === 'darwin') {
try {
// Binary: https://github.com/sindresorhus/macos-term-size
var out = execNative('vendor/mac-term-size', true);
if (out.length === 2)
return size(out[0], out[1]);
}
catch (_c) { }
}
// `resize` is preferred as it works even when all file descriptors are redirected
// https://linux.die.net/man/1/resize
try {
var out = exec('resize', ['-u']).match(/\d+/g);
if (out && out.length === 2)
return size(out[0], out[1]);
}
catch (_d) { }
if (env.TERM) {
try {
var columns = exec('tput', ['cols']);
var rows = exec('tput', ['lines']);
if (columns && rows)
return size(columns, rows);
}
catch (_e) { }
}
return size(80, 35, true); // 返回兜底值
}
function size(width, height, fallback) {
var n = function (s) { return typeof s === 'string' ? parseInt(s, 10) : s; };
return { width: n(width), height: n(height), fallback: fallback };
}
function execNative(file, shell) {
var root = path.resolve(fileURLToPath(import.meta.url), '..', '..', '..');
return exec(path.join(root, file), [], shell).split(/\r?\n/);
}
function exec(cmd, args, shell) {
return execFileSync(cmd, args, { encoding: 'utf8', shell: shell, stdio: ['ignore', 'pipe', 'ignore'] }).trim();
}
/**
* 计算 Unicode 字符串在终端上的长度
*
* 注意:
* - \t => 固定返回 6,主要因为 \t 在 Mac 的 iTerm 上占了 6 个字符
* - \r, \v, \f, \n => 固定返回 0,如果存在,最好提前处理好
*
* @param str 将会显示在终端上的字符串
*
* @example
* cliTextSize('中国') // => 4
* cliTextSize('ab') // => 2
* cliTextSize('\n') // => 0
*
*
* @see {@link https://github.com/qiu8310/tty-text-size/tree/1.0.0 tty-text-size@1.0.0}
*/
function textWidth(str) {
return _cliTextSize(str);
}
export { GLOBAL_ANSI_REGEXP, isWin, stripAnsi, supportTermLink, table, termLink, termSize, textWidth };