@yunzai-ng/cli 0.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.
Files changed (60) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +34 -0
  3. package/dist/args.d.ts +44 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +116 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/bin.d.ts +3 -0
  8. package/dist/bin.d.ts.map +1 -0
  9. package/dist/bin.js +40 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +16 -0
  12. package/dist/commands/doctor.d.ts.map +1 -0
  13. package/dist/commands/doctor.js +181 -0
  14. package/dist/commands/doctor.js.map +1 -0
  15. package/dist/commands/init.d.ts +12 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +61 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/plugin.d.ts +14 -0
  20. package/dist/commands/plugin.d.ts.map +1 -0
  21. package/dist/commands/plugin.js +115 -0
  22. package/dist/commands/plugin.js.map +1 -0
  23. package/dist/commands/start.d.ts +19 -0
  24. package/dist/commands/start.d.ts.map +1 -0
  25. package/dist/commands/start.js +102 -0
  26. package/dist/commands/start.js.map +1 -0
  27. package/dist/help.d.ts +6 -0
  28. package/dist/help.d.ts.map +1 -0
  29. package/dist/help.js +42 -0
  30. package/dist/help.js.map +1 -0
  31. package/dist/index.d.ts +17 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +17 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/link.d.ts +16 -0
  36. package/dist/link.d.ts.map +1 -0
  37. package/dist/link.js +103 -0
  38. package/dist/link.js.map +1 -0
  39. package/dist/run.d.ts +7 -0
  40. package/dist/run.d.ts.map +1 -0
  41. package/dist/run.js +115 -0
  42. package/dist/run.js.map +1 -0
  43. package/dist/terminal.d.ts +43 -0
  44. package/dist/terminal.d.ts.map +1 -0
  45. package/dist/terminal.js +94 -0
  46. package/dist/terminal.js.map +1 -0
  47. package/package.json +31 -0
  48. package/src/args.test.ts +52 -0
  49. package/src/args.ts +132 -0
  50. package/src/bin.ts +40 -0
  51. package/src/commands/doctor.ts +205 -0
  52. package/src/commands/init.ts +65 -0
  53. package/src/commands/plugin.ts +133 -0
  54. package/src/commands/start.ts +121 -0
  55. package/src/help.ts +42 -0
  56. package/src/index.ts +16 -0
  57. package/src/link.test.ts +53 -0
  58. package/src/link.ts +117 -0
  59. package/src/run.ts +124 -0
  60. package/src/terminal.ts +102 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * 模块职责:终端输出 —— 换行、缩进、颜色与表格对齐
3
+ * 依赖方向:仅依赖 node:process,不涉及内核
4
+ * 生命周期:无状态,颜色开关于模块加载时确定一次
5
+ * 注意事项:**刻意不使用 `console`,而是直接写入 `process.stdout`。** 理由有二:
6
+ * 1) CLI 的输出是**程序结果**,而非日志。日志具有级别与 scope 并需落盘,
7
+ * 应经由 `loggerHub`;而 `yzng doctor` 输出的表格不应被写入 yunzai.log,
8
+ * 亦不应因日志级别被调整为 warn 而消失。
9
+ * 2) 仓库的 eslint 规则禁用了 `console`(仅保留 `console.error`),其目的在于
10
+ * 使插件必须经由 `ctx.logger` 输出。CLI 自身不应为此开设例外 —— 直接写入
11
+ * stdout 既满足该规则,亦更准确地表达了"此为命令的输出流"。
12
+ */
13
+ import process from "node:process"
14
+
15
+ /** ANSI 转义引导符。写作转义序列而非字面控制字符:后者会被部分编辑器与补丁工具丢弃 */
16
+ const ESC = "\u001b"
17
+
18
+ /** 是否启用 ANSI 颜色:非 TTY(输出被管道接收)或已设置 NO_COLOR 时一律关闭 */
19
+ const COLOR = process.stdout.isTTY === true && process.env["NO_COLOR"] === undefined
20
+
21
+ /**
22
+ * 为文本附加 ANSI 颜色
23
+ * @param code SGR 参数
24
+ * @param text 文本
25
+ * @returns 着色后的文本;未启用颜色时原样返回
26
+ */
27
+ function paint(code: string, text: string): string {
28
+ return COLOR ? `${ESC}[${code}m${text}${ESC}[0m` : text
29
+ }
30
+
31
+ /** 加粗 */
32
+ export const bold = (text: string): string => paint("1", text)
33
+ /** 变暗,用于次要信息 */
34
+ export const dim = (text: string): string => paint("2", text)
35
+ /** 红色,用于错误 */
36
+ export const red = (text: string): string => paint("31", text)
37
+ /** 绿色,用于成功 */
38
+ export const green = (text: string): string => paint("32", text)
39
+ /** 黄色,用于警告 */
40
+ export const yellow = (text: string): string => paint("33", text)
41
+ /** 青色,用于路径与命令 */
42
+ export const cyan = (text: string): string => paint("36", text)
43
+
44
+ /**
45
+ * 向标准输出写入一行
46
+ * @param text 文本,缺省为空行
47
+ */
48
+ export function print(text = ""): void {
49
+ process.stdout.write(`${text}\n`)
50
+ }
51
+
52
+ /**
53
+ * 向标准错误写入一行
54
+ *
55
+ * 分流的目的在于使 `yzng doctor > report.txt` 之类的重定向仍能在终端观察到错误信息。
56
+ * @param text 文本
57
+ */
58
+ export function printErr(text: string): void {
59
+ process.stderr.write(`${text}\n`)
60
+ }
61
+
62
+ /**
63
+ * 估算字符串在等宽终端中占用的列数
64
+ *
65
+ * 仅区分"宽字符"与"窄字符"两档,不处理组合字符与 emoji 变体选择符 ——
66
+ * CLI 中出现的仅为中文标签与 ASCII 取值,更高的精度并无收益。
67
+ * @param text 文本
68
+ * @returns 列数
69
+ */
70
+ export function displayWidth(text: string): number {
71
+ let width = 0
72
+ for (const ch of text) {
73
+ const code = ch.codePointAt(0) ?? 0
74
+ const wide =
75
+ (code >= 0x1100 && code <= 0x115f) ||
76
+ (code >= 0x2e80 && code <= 0xa4cf) ||
77
+ (code >= 0xac00 && code <= 0xd7a3) ||
78
+ (code >= 0xf900 && code <= 0xfaff) ||
79
+ (code >= 0xfe30 && code <= 0xfe6f) ||
80
+ (code >= 0xff00 && code <= 0xff60) ||
81
+ (code >= 0xffe0 && code <= 0xffe6) ||
82
+ (code >= 0x20000 && code <= 0x3fffd)
83
+ width += wide ? 2 : 1
84
+ }
85
+ return width
86
+ }
87
+
88
+ /**
89
+ * 输出一组"标签 值",标签按显示宽度在右侧补齐
90
+ *
91
+ * 使用 `displayWidth` 而非 `str.length` 度量宽度:标签为中文,中文在等宽字体中
92
+ * 占两列 —— 按 UTF-16 码元数补空格会使整张表格错位。
93
+ * @param rows 标签与值
94
+ * @param indent 每行前缀空格数
95
+ */
96
+ export function printRows(rows: readonly (readonly [string, string])[], indent = 2): void {
97
+ const width = Math.max(0, ...rows.map(([label]) => displayWidth(label)))
98
+ const pad = " ".repeat(indent)
99
+ for (const [label, value] of rows) {
100
+ print(`${pad}${dim(label)}${" ".repeat(width - displayWidth(label) + 1)}${value}`)
101
+ }
102
+ }