grf-cli 1.0.0 → 1.0.3

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 (104) hide show
  1. package/README.md +5 -5
  2. package/README.zh-CN.md +5 -5
  3. package/dist/cli.js +2 -14
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/add.d.ts +5 -0
  6. package/dist/commands/add.d.ts.map +1 -1
  7. package/dist/commands/add.js +15 -16
  8. package/dist/commands/add.js.map +1 -1
  9. package/dist/commands/clean.d.ts +5 -0
  10. package/dist/commands/clean.d.ts.map +1 -1
  11. package/dist/commands/clean.js +15 -33
  12. package/dist/commands/clean.js.map +1 -1
  13. package/dist/commands/config.d.ts +5 -0
  14. package/dist/commands/config.d.ts.map +1 -1
  15. package/dist/commands/config.js +19 -39
  16. package/dist/commands/config.js.map +1 -1
  17. package/dist/commands/index.d.ts +27 -0
  18. package/dist/commands/index.d.ts.map +1 -0
  19. package/dist/commands/index.js +52 -0
  20. package/dist/commands/index.js.map +1 -0
  21. package/dist/commands/list.d.ts +5 -0
  22. package/dist/commands/list.d.ts.map +1 -1
  23. package/dist/commands/list.js +27 -59
  24. package/dist/commands/list.js.map +1 -1
  25. package/dist/commands/load.d.ts +5 -0
  26. package/dist/commands/load.d.ts.map +1 -1
  27. package/dist/commands/load.js +23 -61
  28. package/dist/commands/load.js.map +1 -1
  29. package/dist/commands/unload.d.ts +6 -1
  30. package/dist/commands/unload.d.ts.map +1 -1
  31. package/dist/commands/unload.js +157 -162
  32. package/dist/commands/unload.js.map +1 -1
  33. package/dist/commands/update.d.ts +6 -1
  34. package/dist/commands/update.d.ts.map +1 -1
  35. package/dist/commands/update.js +66 -74
  36. package/dist/commands/update.js.map +1 -1
  37. package/dist/core/config-manager.d.ts +83 -0
  38. package/dist/core/config-manager.d.ts.map +1 -0
  39. package/dist/core/config-manager.js +170 -0
  40. package/dist/core/config-manager.js.map +1 -0
  41. package/dist/core/config.d.ts +22 -2
  42. package/dist/core/config.d.ts.map +1 -1
  43. package/dist/core/config.js +71 -35
  44. package/dist/core/config.js.map +1 -1
  45. package/dist/core/loading-state.d.ts +125 -0
  46. package/dist/core/loading-state.d.ts.map +1 -0
  47. package/dist/core/loading-state.js +212 -0
  48. package/dist/core/loading-state.js.map +1 -0
  49. package/dist/core/loading.d.ts +21 -26
  50. package/dist/core/loading.d.ts.map +1 -1
  51. package/dist/core/loading.js +124 -87
  52. package/dist/core/loading.js.map +1 -1
  53. package/dist/core/migration.d.ts +54 -0
  54. package/dist/core/migration.d.ts.map +1 -0
  55. package/dist/core/migration.js +279 -0
  56. package/dist/core/migration.js.map +1 -0
  57. package/dist/core/paths.d.ts +58 -0
  58. package/dist/core/paths.d.ts.map +1 -0
  59. package/dist/core/paths.js +103 -0
  60. package/dist/core/paths.js.map +1 -0
  61. package/dist/core/repos-index.d.ts +113 -0
  62. package/dist/core/repos-index.d.ts.map +1 -0
  63. package/dist/core/repos-index.js +206 -0
  64. package/dist/core/repos-index.js.map +1 -0
  65. package/dist/core/sync.d.ts.map +1 -1
  66. package/dist/core/sync.js +3 -3
  67. package/dist/core/sync.js.map +1 -1
  68. package/dist/ui/format.d.ts +159 -0
  69. package/dist/ui/format.d.ts.map +1 -0
  70. package/dist/ui/format.js +300 -0
  71. package/dist/ui/format.js.map +1 -0
  72. package/dist/ui/index.d.ts +9 -0
  73. package/dist/ui/index.d.ts.map +1 -0
  74. package/dist/ui/index.js +53 -0
  75. package/dist/ui/index.js.map +1 -0
  76. package/dist/ui/prompt.d.ts +94 -0
  77. package/dist/ui/prompt.d.ts.map +1 -0
  78. package/dist/ui/prompt.js +223 -0
  79. package/dist/ui/prompt.js.map +1 -0
  80. package/dist/ui/spinner.d.ts +99 -0
  81. package/dist/ui/spinner.d.ts.map +1 -0
  82. package/dist/ui/spinner.js +136 -0
  83. package/dist/ui/spinner.js.map +1 -0
  84. package/dist/ui/table.d.ts +142 -0
  85. package/dist/ui/table.d.ts.map +1 -0
  86. package/dist/ui/table.js +213 -0
  87. package/dist/ui/table.js.map +1 -0
  88. package/dist/utils/constants.d.ts +152 -0
  89. package/dist/utils/constants.d.ts.map +1 -0
  90. package/dist/utils/constants.js +160 -0
  91. package/dist/utils/constants.js.map +1 -0
  92. package/dist/utils/error.d.ts +109 -0
  93. package/dist/utils/error.d.ts.map +1 -0
  94. package/dist/utils/error.js +212 -0
  95. package/dist/utils/error.js.map +1 -0
  96. package/dist/utils/index.d.ts +8 -0
  97. package/dist/utils/index.d.ts.map +1 -0
  98. package/dist/utils/index.js +44 -0
  99. package/dist/utils/index.js.map +1 -0
  100. package/dist/utils/validation.d.ts +122 -0
  101. package/dist/utils/validation.d.ts.map +1 -0
  102. package/dist/utils/validation.js +248 -0
  103. package/dist/utils/validation.js.map +1 -0
  104. package/package.json +4 -4
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /**
3
+ * 用户交互提示模块
4
+ * 封装确认提示和用户输入功能
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ var __importDefault = (this && this.__importDefault) || function (mod) {
40
+ return (mod && mod.__esModule) ? mod : { "default": mod };
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.confirm = confirm;
44
+ exports.prompt = prompt;
45
+ exports.selectByNumber = selectByNumber;
46
+ exports.showCancelled = showCancelled;
47
+ exports.showWarning = showWarning;
48
+ exports.showInfo = showInfo;
49
+ exports.showSuccess = showSuccess;
50
+ const readline = __importStar(require("readline"));
51
+ const chalk_1 = __importDefault(require("chalk"));
52
+ /**
53
+ * 显示确认提示,等待用户输入 y/n
54
+ * @param message 提示消息
55
+ * @param options 配置选项
56
+ * @returns 用户是否确认
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // 默认为 No
61
+ * const confirmed = await confirm("Are you sure?");
62
+ *
63
+ * // 默认为 Yes
64
+ * const confirmed = await confirm("Continue?", { defaultValue: true });
65
+ * ```
66
+ */
67
+ async function confirm(message, options = {}) {
68
+ const { defaultValue = false, suffix } = options;
69
+ const rl = readline.createInterface({
70
+ input: process.stdin,
71
+ output: process.stdout,
72
+ });
73
+ // 根据默认值确定提示后缀
74
+ const promptSuffix = suffix ?? (defaultValue ? "(Y/n)" : "(y/N)");
75
+ return new Promise((resolve) => {
76
+ rl.question(`${message} ${promptSuffix} `, (answer) => {
77
+ rl.close();
78
+ const trimmedAnswer = answer.trim().toLowerCase();
79
+ // 如果用户直接按回车,使用默认值
80
+ if (trimmedAnswer === "") {
81
+ resolve(defaultValue);
82
+ return;
83
+ }
84
+ // 检查是否为肯定回答
85
+ resolve(trimmedAnswer === "y" || trimmedAnswer === "yes");
86
+ });
87
+ });
88
+ }
89
+ /**
90
+ * 显示输入提示,等待用户输入
91
+ * @param message 提示消息
92
+ * @param options 配置选项
93
+ * @returns 用户输入的内容
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const name = await prompt("Enter repository name:");
98
+ *
99
+ * const name = await prompt("Enter name:", {
100
+ * defaultValue: "default-name",
101
+ * validate: (input) => input.length > 0 || "Name cannot be empty"
102
+ * });
103
+ * ```
104
+ */
105
+ async function prompt(message, options = {}) {
106
+ const { defaultValue, allowEmpty = false, validate } = options;
107
+ const rl = readline.createInterface({
108
+ input: process.stdin,
109
+ output: process.stdout,
110
+ });
111
+ // 构建提示消息
112
+ let promptMessage = message;
113
+ if (defaultValue) {
114
+ promptMessage += chalk_1.default.gray(` (${defaultValue})`);
115
+ }
116
+ promptMessage += " ";
117
+ return new Promise((resolve) => {
118
+ const askQuestion = () => {
119
+ rl.question(promptMessage, (answer) => {
120
+ const trimmedAnswer = answer.trim();
121
+ // 如果用户直接按回车且有默认值,使用默认值
122
+ if (trimmedAnswer === "" && defaultValue !== undefined) {
123
+ rl.close();
124
+ resolve(defaultValue);
125
+ return;
126
+ }
127
+ // 检查是否允许空输入
128
+ if (trimmedAnswer === "" && !allowEmpty) {
129
+ console.log(chalk_1.default.red("Input cannot be empty. Please try again."));
130
+ askQuestion();
131
+ return;
132
+ }
133
+ // 执行验证
134
+ if (validate) {
135
+ const validationResult = validate(trimmedAnswer);
136
+ if (validationResult !== true) {
137
+ const errorMessage = typeof validationResult === "string"
138
+ ? validationResult
139
+ : "Invalid input. Please try again.";
140
+ console.log(chalk_1.default.red(errorMessage));
141
+ askQuestion();
142
+ return;
143
+ }
144
+ }
145
+ rl.close();
146
+ resolve(trimmedAnswer);
147
+ });
148
+ };
149
+ askQuestion();
150
+ });
151
+ }
152
+ /**
153
+ * 显示带有选项的选择提示
154
+ * @param message 提示消息
155
+ * @param choices 选项列表
156
+ * @returns 用户选择的选项索引
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const index = await select("Choose an option:", [
161
+ * "Option 1",
162
+ * "Option 2",
163
+ * "Option 3"
164
+ * ]);
165
+ * ```
166
+ */
167
+ async function selectByNumber(message, choices) {
168
+ console.log(message);
169
+ console.log();
170
+ // 显示选项
171
+ choices.forEach((choice, index) => {
172
+ console.log(` ${chalk_1.default.cyan(index + 1)}. ${choice}`);
173
+ });
174
+ console.log();
175
+ const rl = readline.createInterface({
176
+ input: process.stdin,
177
+ output: process.stdout,
178
+ });
179
+ return new Promise((resolve) => {
180
+ const askQuestion = () => {
181
+ rl.question(`Enter number (1-${choices.length}): `, (answer) => {
182
+ const num = parseInt(answer.trim(), 10);
183
+ if (isNaN(num) || num < 1 || num > choices.length) {
184
+ console.log(chalk_1.default.red(`Please enter a number between 1 and ${choices.length}.`));
185
+ askQuestion();
186
+ return;
187
+ }
188
+ rl.close();
189
+ resolve(num - 1);
190
+ });
191
+ };
192
+ askQuestion();
193
+ });
194
+ }
195
+ /**
196
+ * 显示操作取消消息
197
+ * @param message 可选的自定义消息
198
+ */
199
+ function showCancelled(message) {
200
+ console.log(chalk_1.default.yellow(message ?? "Operation cancelled."));
201
+ }
202
+ /**
203
+ * 显示警告消息
204
+ * @param message 警告消息
205
+ */
206
+ function showWarning(message) {
207
+ console.log(chalk_1.default.yellow(`⚠️ ${message}`));
208
+ }
209
+ /**
210
+ * 显示信息消息
211
+ * @param message 信息消息
212
+ */
213
+ function showInfo(message) {
214
+ console.log(chalk_1.default.blue(`ℹ️ ${message}`));
215
+ }
216
+ /**
217
+ * 显示成功消息
218
+ * @param message 成功消息
219
+ */
220
+ function showSuccess(message) {
221
+ console.log(chalk_1.default.green(`✓ ${message}`));
222
+ }
223
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/ui/prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Spinner 封装模块
3
+ * 提供统一的加载指示器接口
4
+ */
5
+ import { type Ora, type Options as OraOptions } from "ora";
6
+ /**
7
+ * Spinner 配置选项
8
+ */
9
+ export interface SpinnerOptions {
10
+ /** 初始文本 */
11
+ text?: string;
12
+ /** 是否立即启动 */
13
+ start?: boolean;
14
+ /** 颜色 */
15
+ color?: OraOptions["color"];
16
+ /** 前缀文本 */
17
+ prefixText?: string;
18
+ }
19
+ /**
20
+ * Spinner 实例类型
21
+ */
22
+ export type Spinner = Ora;
23
+ /**
24
+ * 创建一个新的 spinner 实例
25
+ * @param textOrOptions 文本或配置选项
26
+ * @returns Spinner 实例
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // 简单用法
31
+ * const spinner = createSpinner("Loading...");
32
+ * spinner.start();
33
+ * // ... 执行操作
34
+ * spinner.succeed("Done!");
35
+ *
36
+ * // 使用选项
37
+ * const spinner = createSpinner({
38
+ * text: "Processing...",
39
+ * color: "cyan",
40
+ * start: true
41
+ * });
42
+ * ```
43
+ */
44
+ export declare function createSpinner(textOrOptions?: string | SpinnerOptions): Spinner;
45
+ /**
46
+ * 创建并立即启动一个 spinner
47
+ * @param text 显示文本
48
+ * @returns 已启动的 Spinner 实例
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const spinner = startSpinner("Cloning repository...");
53
+ * // ... 执行操作
54
+ * spinner.succeed("Repository cloned!");
55
+ * ```
56
+ */
57
+ export declare function startSpinner(text: string): Spinner;
58
+ /**
59
+ * 带有成功/失败回调的 spinner 包装器
60
+ * @param text 初始文本
61
+ * @param task 要执行的异步任务
62
+ * @returns 任务结果
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const result = await withSpinner("Fetching data...", async (spinner) => {
67
+ * const data = await fetchData();
68
+ * spinner.text = "Processing data...";
69
+ * return processData(data);
70
+ * });
71
+ * ```
72
+ */
73
+ export declare function withSpinner<T>(text: string, task: (spinner: Spinner) => Promise<T>): Promise<T>;
74
+ /**
75
+ * 带有自定义成功/失败消息的 spinner 包装器
76
+ * @param options 配置选项
77
+ * @param task 要执行的异步任务
78
+ * @returns 任务结果
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const result = await withSpinnerMessages(
83
+ * {
84
+ * start: "Cloning repository...",
85
+ * success: "Repository cloned successfully!",
86
+ * fail: "Failed to clone repository"
87
+ * },
88
+ * async () => {
89
+ * return await cloneRepo(url);
90
+ * }
91
+ * );
92
+ * ```
93
+ */
94
+ export declare function withSpinnerMessages<T>(options: {
95
+ start: string;
96
+ success?: string;
97
+ fail?: string;
98
+ }, task: (spinner: Spinner) => Promise<T>): Promise<T>;
99
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAY,EAAE,KAAK,GAAG,EAAE,KAAK,OAAO,IAAI,UAAU,EAAE,MAAM,KAAK,CAAC;AAGhE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS;IACT,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC5B,WAAW;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,GAAG,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,cAAc,GACtC,OAAO,CAiBT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,EACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ /**
3
+ * Spinner 封装模块
4
+ * 提供统一的加载指示器接口
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createSpinner = createSpinner;
11
+ exports.startSpinner = startSpinner;
12
+ exports.withSpinner = withSpinner;
13
+ exports.withSpinnerMessages = withSpinnerMessages;
14
+ const ora_1 = __importDefault(require("ora"));
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ /**
17
+ * 创建一个新的 spinner 实例
18
+ * @param textOrOptions 文本或配置选项
19
+ * @returns Spinner 实例
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // 简单用法
24
+ * const spinner = createSpinner("Loading...");
25
+ * spinner.start();
26
+ * // ... 执行操作
27
+ * spinner.succeed("Done!");
28
+ *
29
+ * // 使用选项
30
+ * const spinner = createSpinner({
31
+ * text: "Processing...",
32
+ * color: "cyan",
33
+ * start: true
34
+ * });
35
+ * ```
36
+ */
37
+ function createSpinner(textOrOptions) {
38
+ if (typeof textOrOptions === "string") {
39
+ return (0, ora_1.default)(textOrOptions);
40
+ }
41
+ const options = textOrOptions ?? {};
42
+ const spinner = (0, ora_1.default)({
43
+ text: options.text,
44
+ color: options.color,
45
+ prefixText: options.prefixText,
46
+ });
47
+ if (options.start) {
48
+ spinner.start();
49
+ }
50
+ return spinner;
51
+ }
52
+ /**
53
+ * 创建并立即启动一个 spinner
54
+ * @param text 显示文本
55
+ * @returns 已启动的 Spinner 实例
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const spinner = startSpinner("Cloning repository...");
60
+ * // ... 执行操作
61
+ * spinner.succeed("Repository cloned!");
62
+ * ```
63
+ */
64
+ function startSpinner(text) {
65
+ return (0, ora_1.default)(text).start();
66
+ }
67
+ /**
68
+ * 带有成功/失败回调的 spinner 包装器
69
+ * @param text 初始文本
70
+ * @param task 要执行的异步任务
71
+ * @returns 任务结果
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const result = await withSpinner("Fetching data...", async (spinner) => {
76
+ * const data = await fetchData();
77
+ * spinner.text = "Processing data...";
78
+ * return processData(data);
79
+ * });
80
+ * ```
81
+ */
82
+ async function withSpinner(text, task) {
83
+ const spinner = (0, ora_1.default)(text).start();
84
+ try {
85
+ const result = await task(spinner);
86
+ spinner.succeed();
87
+ return result;
88
+ }
89
+ catch (error) {
90
+ spinner.fail();
91
+ throw error;
92
+ }
93
+ }
94
+ /**
95
+ * 带有自定义成功/失败消息的 spinner 包装器
96
+ * @param options 配置选项
97
+ * @param task 要执行的异步任务
98
+ * @returns 任务结果
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const result = await withSpinnerMessages(
103
+ * {
104
+ * start: "Cloning repository...",
105
+ * success: "Repository cloned successfully!",
106
+ * fail: "Failed to clone repository"
107
+ * },
108
+ * async () => {
109
+ * return await cloneRepo(url);
110
+ * }
111
+ * );
112
+ * ```
113
+ */
114
+ async function withSpinnerMessages(options, task) {
115
+ const spinner = (0, ora_1.default)(options.start).start();
116
+ try {
117
+ const result = await task(spinner);
118
+ if (options.success) {
119
+ spinner.succeed(chalk_1.default.green(options.success));
120
+ }
121
+ else {
122
+ spinner.succeed();
123
+ }
124
+ return result;
125
+ }
126
+ catch (error) {
127
+ if (options.fail) {
128
+ spinner.fail(chalk_1.default.red(options.fail));
129
+ }
130
+ else {
131
+ spinner.fail();
132
+ }
133
+ throw error;
134
+ }
135
+ }
136
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AA6CH,sCAmBC;AAcD,oCAEC;AAiBD,kCAcC;AAsBD,kDA0BC;AA7JD,8CAAgE;AAChE,kDAA0B;AAqB1B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,aAAa,CAC3B,aAAuC;IAEvC,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,IAAA,aAAG,EAAC,aAAa,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,IAAI,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,YAAY,CAAC,IAAY;IACvC,OAAO,IAAA,aAAG,EAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,IAAsC;IAEtC,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACI,KAAK,UAAU,mBAAmB,CACvC,OAIC,EACD,IAAsC;IAEtC,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAE3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * 表格输出模块
3
+ * 封装表格格式化和输出功能
4
+ */
5
+ /**
6
+ * 将字符串填充到指定宽度(右侧填充空格)
7
+ * @param str 原始字符串
8
+ * @param width 目标宽度
9
+ * @returns 填充后的字符串
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * padEnd("hello", 10); // "hello "
14
+ * padEnd("hello world", 5); // "hello world" (不截断)
15
+ * ```
16
+ */
17
+ export declare function padEnd(str: string, width: number): string;
18
+ /**
19
+ * 将字符串填充到指定宽度(左侧填充空格)
20
+ * @param str 原始字符串
21
+ * @param width 目标宽度
22
+ * @returns 填充后的字符串
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * padStart("42", 5); // " 42"
27
+ * ```
28
+ */
29
+ export declare function padStart(str: string, width: number): string;
30
+ /**
31
+ * 截断长字符串
32
+ * @param str 原始字符串
33
+ * @param maxLength 最大长度
34
+ * @param suffix 截断后缀,默认为 "..."
35
+ * @returns 截断后的字符串
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * truncate("hello world", 8); // "hello..."
40
+ * truncate("hello", 10); // "hello"
41
+ * ```
42
+ */
43
+ export declare function truncate(str: string, maxLength: number, suffix?: string): string;
44
+ /**
45
+ * 表格列定义
46
+ */
47
+ export interface TableColumn {
48
+ /** 列标题 */
49
+ header: string;
50
+ /** 列宽度 */
51
+ width: number;
52
+ /** 对齐方式 */
53
+ align?: "left" | "right" | "center";
54
+ }
55
+ /**
56
+ * 表格配置选项
57
+ */
58
+ export interface TableOptions {
59
+ /** 列定义 */
60
+ columns: TableColumn[];
61
+ /** 行前缀(缩进) */
62
+ indent?: string;
63
+ /** 是否显示表头 */
64
+ showHeader?: boolean;
65
+ /** 表头颜色 */
66
+ headerColor?: "gray" | "white" | "cyan" | "yellow";
67
+ }
68
+ /**
69
+ * 打印表格
70
+ * @param options 表格配置
71
+ * @param rows 数据行(每行是一个字符串数组)
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * printTable(
76
+ * {
77
+ * columns: [
78
+ * { header: "NAME", width: 20 },
79
+ * { header: "STATUS", width: 15 },
80
+ * { header: "COUNT", width: 10, align: "right" }
81
+ * ],
82
+ * indent: " ",
83
+ * showHeader: true
84
+ * },
85
+ * [
86
+ * ["repo1", "active", "42"],
87
+ * ["repo2", "inactive", "0"]
88
+ * ]
89
+ * );
90
+ * ```
91
+ */
92
+ export declare function printTable(options: TableOptions, rows: string[][]): void;
93
+ /**
94
+ * 打印简单的键值对列表
95
+ * @param items 键值对数组
96
+ * @param options 配置选项
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * printKeyValue([
101
+ * { key: "Name", value: "my-repo" },
102
+ * { key: "Path", value: "/path/to/repo" },
103
+ * { key: "Branch", value: "main" }
104
+ * ], { indent: " ", keyWidth: 10 });
105
+ * ```
106
+ */
107
+ export declare function printKeyValue(items: Array<{
108
+ key: string;
109
+ value: string;
110
+ }>, options?: {
111
+ indent?: string;
112
+ keyWidth?: number;
113
+ separator?: string;
114
+ }): void;
115
+ /**
116
+ * 打印分隔线
117
+ * @param length 分隔线长度
118
+ * @param char 分隔字符,默认为 "-"
119
+ */
120
+ export declare function printSeparator(length: number, char?: string): void;
121
+ /**
122
+ * 打印空行
123
+ * @param count 空行数量,默认为 1
124
+ */
125
+ export declare function printEmptyLine(count?: number): void;
126
+ /**
127
+ * 打印标题
128
+ * @param title 标题文本
129
+ * @param options 配置选项
130
+ */
131
+ export declare function printTitle(title: string, options?: {
132
+ bold?: boolean;
133
+ icon?: string;
134
+ }): void;
135
+ /**
136
+ * 打印统计信息
137
+ * @param total 总数
138
+ * @param unit 单位(单数形式)
139
+ * @param pluralUnit 单位(复数形式),默认为单数形式加 "s"
140
+ */
141
+ export declare function printTotal(total: number, unit: string, pluralUnit?: string): void;
142
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/ui/table.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAc,GACrB,MAAM,CAGR;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU;IACV,MAAM,EAAE,MAAM,CAAC;IACf,UAAU;IACV,KAAK,EAAE,MAAM,CAAC;IACd,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU;IACV,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;CACpD;AA0BD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAwBxE;AA0BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAC5C,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACvE,IAAI,CAON;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAY,GAAG,IAAI,CAEvE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAE,MAAU,GAAG,IAAI,CAItD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,IAAI,CAIN;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CAGN"}