UNPKG

@serpent/common-cli

Version:

通用的 cli 相关的函数

220 lines (209 loc) 6.85 kB
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 };