@cloudglab/yapi-cli 0.0.1
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.
- package/CHANGELOG.md +5 -0
- package/README.md +131 -0
- package/dist/bin/yapi.d.ts +2 -0
- package/dist/bin/yapi.js +8 -0
- package/dist/bin/yapi.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +203 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/changelog.d.ts +17 -0
- package/dist/core/changelog.js +117 -0
- package/dist/core/changelog.js.map +1 -0
- package/dist/core/cli-output.d.ts +13 -0
- package/dist/core/cli-output.js +65 -0
- package/dist/core/cli-output.js.map +1 -0
- package/dist/core/cli-registry.d.ts +38 -0
- package/dist/core/cli-registry.js +189 -0
- package/dist/core/cli-registry.js.map +1 -0
- package/dist/core/completion.d.ts +3 -0
- package/dist/core/completion.js +94 -0
- package/dist/core/completion.js.map +1 -0
- package/dist/core/doctor.d.ts +13 -0
- package/dist/core/doctor.js +124 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/errors.d.ts +38 -0
- package/dist/core/errors.js +74 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/output.d.ts +27 -0
- package/dist/core/output.js +208 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/update-probe.d.ts +14 -0
- package/dist/core/update-probe.js +67 -0
- package/dist/core/update-probe.js.map +1 -0
- package/dist/core/write-guard.d.ts +25 -0
- package/dist/core/write-guard.js +36 -0
- package/dist/core/write-guard.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +13 -0
- package/dist/install.js +201 -0
- package/dist/install.js.map +1 -0
- package/dist/services/yapi/api.d.ts +696 -0
- package/dist/services/yapi/api.js +700 -0
- package/dist/services/yapi/api.js.map +1 -0
- package/dist/services/yapi/auth.d.ts +37 -0
- package/dist/services/yapi/auth.js +143 -0
- package/dist/services/yapi/auth.js.map +1 -0
- package/dist/services/yapi/authCache.d.ts +25 -0
- package/dist/services/yapi/authCache.js +80 -0
- package/dist/services/yapi/authCache.js.map +1 -0
- package/dist/services/yapi/cache.d.ts +27 -0
- package/dist/services/yapi/cache.js +88 -0
- package/dist/services/yapi/cache.js.map +1 -0
- package/dist/services/yapi/config.d.ts +12 -0
- package/dist/services/yapi/config.js +66 -0
- package/dist/services/yapi/config.js.map +1 -0
- package/dist/services/yapi/index.d.ts +6 -0
- package/dist/services/yapi/index.js +6 -0
- package/dist/services/yapi/index.js.map +1 -0
- package/dist/services/yapi/logger.d.ts +6 -0
- package/dist/services/yapi/logger.js +36 -0
- package/dist/services/yapi/logger.js.map +1 -0
- package/dist/services/yapi/types.d.ts +176 -0
- package/dist/services/yapi/types.js +2 -0
- package/dist/services/yapi/types.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/shared.d.ts +33 -0
- package/dist/tools/shared.js +46 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/yapi/docs-sync.d.ts +29 -0
- package/dist/tools/yapi/docs-sync.js +243 -0
- package/dist/tools/yapi/docs-sync.js.map +1 -0
- package/dist/tools/yapi/index.d.ts +6 -0
- package/dist/tools/yapi/index.js +7 -0
- package/dist/tools/yapi/index.js.map +1 -0
- package/dist/tools/yapi/register-auth.d.ts +2 -0
- package/dist/tools/yapi/register-auth.js +182 -0
- package/dist/tools/yapi/register-auth.js.map +1 -0
- package/dist/tools/yapi/register-group.d.ts +2 -0
- package/dist/tools/yapi/register-group.js +178 -0
- package/dist/tools/yapi/register-group.js.map +1 -0
- package/dist/tools/yapi/register-interface.d.ts +2 -0
- package/dist/tools/yapi/register-interface.js +359 -0
- package/dist/tools/yapi/register-interface.js.map +1 -0
- package/dist/tools/yapi/register-project.d.ts +2 -0
- package/dist/tools/yapi/register-project.js +300 -0
- package/dist/tools/yapi/register-project.js.map +1 -0
- package/dist/tools/yapi/register-test.d.ts +2 -0
- package/dist/tools/yapi/register-test.js +267 -0
- package/dist/tools/yapi/register-test.js.map +1 -0
- package/dist/tools/yapi/register-util.d.ts +2 -0
- package/dist/tools/yapi/register-util.js +565 -0
- package/dist/tools/yapi/register-util.js.map +1 -0
- package/dist/tools/yapi/register.d.ts +6 -0
- package/dist/tools/yapi/register.js +19 -0
- package/dist/tools/yapi/register.js.map +1 -0
- package/dist/tools/yapi/utils.d.ts +11 -0
- package/dist/tools/yapi/utils.js +28 -0
- package/dist/tools/yapi/utils.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +38 -0
- package/skills/yapi-cli/SKILL.md +126 -0
- package/skills/yapi-cli/reference/auth.md +106 -0
- package/skills/yapi-cli/reference/cli.md +60 -0
- package/skills/yapi-cli/reference/commands.md +152 -0
- package/skills/yapi-cli/reference/group.md +77 -0
- package/skills/yapi-cli/reference/install.md +82 -0
- package/skills/yapi-cli/reference/interface.md +185 -0
- package/skills/yapi-cli/reference/overview.md +52 -0
- package/skills/yapi-cli/reference/project.md +115 -0
- package/skills/yapi-cli/reference/test.md +130 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export class InMemoryCliRegistry {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.commands = new Map();
|
|
5
|
+
}
|
|
6
|
+
tool(name, schema, handler, description, metadata) {
|
|
7
|
+
if (this.commands.has(name)) {
|
|
8
|
+
throw new Error(`重复命令: ${name}`);
|
|
9
|
+
}
|
|
10
|
+
this.commands.set(name, {
|
|
11
|
+
name,
|
|
12
|
+
schema,
|
|
13
|
+
handler,
|
|
14
|
+
description,
|
|
15
|
+
metadata,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
getCommand(name) {
|
|
19
|
+
return this.commands.get(name);
|
|
20
|
+
}
|
|
21
|
+
listCommands() {
|
|
22
|
+
return [...this.commands.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function unwrapSchema(schema) {
|
|
26
|
+
let current = schema;
|
|
27
|
+
while (true) {
|
|
28
|
+
const typeName = current._def.typeName;
|
|
29
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodOptional || typeName === z.ZodFirstPartyTypeKind.ZodNullable || typeName === z.ZodFirstPartyTypeKind.ZodDefault) {
|
|
30
|
+
current = current._def.innerType;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodEffects) {
|
|
34
|
+
current = current._def.schema;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
return current;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function isPlainObject(value) {
|
|
41
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
42
|
+
}
|
|
43
|
+
function parseBoolean(value) {
|
|
44
|
+
const normalized = value.trim().toLowerCase();
|
|
45
|
+
if (['1', 'true', 'yes', 'on'].includes(normalized))
|
|
46
|
+
return true;
|
|
47
|
+
if (['0', 'false', 'no', 'off'].includes(normalized))
|
|
48
|
+
return false;
|
|
49
|
+
throw new Error(`无法解析布尔值: ${value}`);
|
|
50
|
+
}
|
|
51
|
+
function parseArrayValue(rawValue, itemSchema) {
|
|
52
|
+
const trimmed = rawValue.trim();
|
|
53
|
+
const parsed = trimmed.startsWith('[') ? JSON.parse(trimmed) : trimmed.includes(',') ? trimmed.split(',').map((item) => item.trim()).filter(Boolean) : [trimmed];
|
|
54
|
+
if (!Array.isArray(parsed)) {
|
|
55
|
+
throw new Error(`数组参数格式错误: ${rawValue}`);
|
|
56
|
+
}
|
|
57
|
+
return parsed.map((item) => coerceValue(itemSchema, item));
|
|
58
|
+
}
|
|
59
|
+
function coerceValue(schema, rawValue) {
|
|
60
|
+
const resolved = unwrapSchema(schema);
|
|
61
|
+
const typeName = resolved._def.typeName;
|
|
62
|
+
if (rawValue === undefined) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodString || typeName === z.ZodFirstPartyTypeKind.ZodEnum || typeName === z.ZodFirstPartyTypeKind.ZodNativeEnum || typeName === z.ZodFirstPartyTypeKind.ZodLiteral) {
|
|
66
|
+
return String(rawValue);
|
|
67
|
+
}
|
|
68
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodNumber) {
|
|
69
|
+
const numberValue = typeof rawValue === 'number' ? rawValue : Number(rawValue);
|
|
70
|
+
if (Number.isNaN(numberValue)) {
|
|
71
|
+
throw new Error(`无法解析数字: ${rawValue}`);
|
|
72
|
+
}
|
|
73
|
+
return numberValue;
|
|
74
|
+
}
|
|
75
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodBoolean) {
|
|
76
|
+
if (typeof rawValue === 'boolean')
|
|
77
|
+
return rawValue;
|
|
78
|
+
return parseBoolean(String(rawValue));
|
|
79
|
+
}
|
|
80
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodArray) {
|
|
81
|
+
const arraySchema = resolved;
|
|
82
|
+
const itemSchema = arraySchema.element;
|
|
83
|
+
if (Array.isArray(rawValue)) {
|
|
84
|
+
return rawValue.map((item) => coerceValue(itemSchema, item));
|
|
85
|
+
}
|
|
86
|
+
return parseArrayValue(String(rawValue), itemSchema);
|
|
87
|
+
}
|
|
88
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodObject) {
|
|
89
|
+
if (isPlainObject(rawValue))
|
|
90
|
+
return rawValue;
|
|
91
|
+
return JSON.parse(String(rawValue));
|
|
92
|
+
}
|
|
93
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodUnion) {
|
|
94
|
+
return rawValue;
|
|
95
|
+
}
|
|
96
|
+
return rawValue;
|
|
97
|
+
}
|
|
98
|
+
function takeFlagValue(values) {
|
|
99
|
+
if (values.length === 0) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (values.length === 1) {
|
|
103
|
+
return values[0];
|
|
104
|
+
}
|
|
105
|
+
return values;
|
|
106
|
+
}
|
|
107
|
+
function toCamelCase(key) {
|
|
108
|
+
return key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
109
|
+
}
|
|
110
|
+
function collectFlags(args) {
|
|
111
|
+
const flags = new Map();
|
|
112
|
+
let index = 0;
|
|
113
|
+
while (index < args.length) {
|
|
114
|
+
const token = args[index];
|
|
115
|
+
if (!token.startsWith('-')) {
|
|
116
|
+
throw new Error(`不支持的位置参数: ${token}`);
|
|
117
|
+
}
|
|
118
|
+
if (token === '--') {
|
|
119
|
+
throw new Error('不支持 -- 之后的位置参数');
|
|
120
|
+
}
|
|
121
|
+
const raw = token.replace(/^-+/, '');
|
|
122
|
+
const equalsIndex = raw.indexOf('=');
|
|
123
|
+
const key = toCamelCase(equalsIndex >= 0 ? raw.slice(0, equalsIndex) : raw);
|
|
124
|
+
if (equalsIndex >= 0) {
|
|
125
|
+
const value = raw.slice(equalsIndex + 1);
|
|
126
|
+
flags.set(key, [...(flags.get(key) ?? []), value]);
|
|
127
|
+
index += 1;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const next = args[index + 1];
|
|
131
|
+
if (next !== undefined && !next.startsWith('-')) {
|
|
132
|
+
flags.set(key, [...(flags.get(key) ?? []), next]);
|
|
133
|
+
index += 2;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
flags.set(key, [...(flags.get(key) ?? []), '']);
|
|
137
|
+
index += 1;
|
|
138
|
+
}
|
|
139
|
+
return flags;
|
|
140
|
+
}
|
|
141
|
+
export function describeSchema(schema) {
|
|
142
|
+
return Object.entries(schema).map(([name, fieldSchema]) => {
|
|
143
|
+
const resolved = unwrapSchema(fieldSchema);
|
|
144
|
+
const typeName = resolved._def.typeName;
|
|
145
|
+
const required = fieldSchema._def.typeName !== z.ZodFirstPartyTypeKind.ZodOptional && fieldSchema._def.typeName !== z.ZodFirstPartyTypeKind.ZodDefault;
|
|
146
|
+
let type = 'string';
|
|
147
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodNumber)
|
|
148
|
+
type = 'number';
|
|
149
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodBoolean)
|
|
150
|
+
type = 'boolean';
|
|
151
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodArray)
|
|
152
|
+
type = 'array';
|
|
153
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodObject)
|
|
154
|
+
type = 'object';
|
|
155
|
+
if (typeName === z.ZodFirstPartyTypeKind.ZodEnum || typeName === z.ZodFirstPartyTypeKind.ZodNativeEnum || typeName === z.ZodFirstPartyTypeKind.ZodLiteral)
|
|
156
|
+
type = 'enum';
|
|
157
|
+
return {
|
|
158
|
+
name,
|
|
159
|
+
required,
|
|
160
|
+
type,
|
|
161
|
+
description: fieldSchema.description,
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
export function parseCommandInput(schema, args) {
|
|
166
|
+
const flags = collectFlags(args);
|
|
167
|
+
const input = {};
|
|
168
|
+
const allowedNames = new Set(Object.keys(schema));
|
|
169
|
+
for (const key of flags.keys()) {
|
|
170
|
+
if (!allowedNames.has(key)) {
|
|
171
|
+
throw new Error(`未知参数: --${key}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
for (const [name, fieldSchema] of Object.entries(schema)) {
|
|
175
|
+
const values = flags.get(name);
|
|
176
|
+
if (values === undefined)
|
|
177
|
+
continue;
|
|
178
|
+
const resolved = unwrapSchema(fieldSchema);
|
|
179
|
+
const isArrayField = resolved._def.typeName === z.ZodFirstPartyTypeKind.ZodArray;
|
|
180
|
+
const rawValue = isArrayField ? values : values[values.length - 1];
|
|
181
|
+
const coerced = coerceValue(fieldSchema, rawValue);
|
|
182
|
+
if (coerced !== undefined) {
|
|
183
|
+
input[name] = coerced;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const parsedSchema = z.object(schema).strict();
|
|
187
|
+
return parsedSchema.parse(input);
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=cli-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-registry.js","sourceRoot":"","sources":["../../src/core/cli-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
function detectShellType(shellArg) {
|
|
2
|
+
if (shellArg === 'zsh')
|
|
3
|
+
return 'zsh';
|
|
4
|
+
if (shellArg === 'fish')
|
|
5
|
+
return 'fish';
|
|
6
|
+
return 'bash';
|
|
7
|
+
}
|
|
8
|
+
/** 生成 bash/zsh/fish 补全脚本 */
|
|
9
|
+
export function generateCompletionScript(commands, appName, shellArg) {
|
|
10
|
+
const shell = detectShellType(shellArg);
|
|
11
|
+
const commandNames = commands.map((c) => c.name).sort();
|
|
12
|
+
if (shell === 'zsh') {
|
|
13
|
+
return generateZshCompletion(commandNames, appName);
|
|
14
|
+
}
|
|
15
|
+
if (shell === 'fish') {
|
|
16
|
+
return generateFishCompletion(commandNames, appName);
|
|
17
|
+
}
|
|
18
|
+
return generateBashCompletion(commandNames, appName);
|
|
19
|
+
}
|
|
20
|
+
function generateBashCompletion(commandNames, appName) {
|
|
21
|
+
const builtins = ['help', 'list', 'version', 'install', 'update', 'uninstall', 'remove', 'doctor', 'changelog'];
|
|
22
|
+
const all = [...builtins, ...commandNames];
|
|
23
|
+
const wordList = all.join(' ');
|
|
24
|
+
const script = [
|
|
25
|
+
`# ${appName} bash completion`,
|
|
26
|
+
`# 安装: source <(${appName} completion bash)`,
|
|
27
|
+
'# 或添加到 ~/.bashrc',
|
|
28
|
+
'',
|
|
29
|
+
`_${appName}() {`,
|
|
30
|
+
' local cur="${COMP_WORDS[COMP_CWORD]}"',
|
|
31
|
+
' local prev="${COMP_WORDS[COMP_CWORD-1]}"',
|
|
32
|
+
'',
|
|
33
|
+
' # 二级补全:help 后补命令名',
|
|
34
|
+
' if [[ COMP_CWORD -eq 2 && "${COMP_WORDS[1]}" == "help" ]]; then',
|
|
35
|
+
` COMPREPLY=($(compgen -W "${wordList}" -- "\${cur}"))`,
|
|
36
|
+
' return 0',
|
|
37
|
+
' fi',
|
|
38
|
+
'',
|
|
39
|
+
' if [[ COMP_CWORD -eq 1 ]]; then',
|
|
40
|
+
` COMPREPLY=($(compgen -W "${wordList}" -- "\${cur}"))`,
|
|
41
|
+
' return 0',
|
|
42
|
+
' fi',
|
|
43
|
+
'',
|
|
44
|
+
' # -- 补全',
|
|
45
|
+
' if [[ "${cur}" == --* ]]; then',
|
|
46
|
+
' COMPREPLY=($(compgen -W "--help" -- "${cur}"))',
|
|
47
|
+
' return 0',
|
|
48
|
+
' fi',
|
|
49
|
+
'}',
|
|
50
|
+
'',
|
|
51
|
+
`complete -F _${appName} ${appName}`,
|
|
52
|
+
'',
|
|
53
|
+
];
|
|
54
|
+
return script.join('\n');
|
|
55
|
+
}
|
|
56
|
+
function generateZshCompletion(commandNames, appName) {
|
|
57
|
+
const builtins = ['help:显示帮助信息', 'list:列出所有命令', 'version:显示版本号', 'install:安装 CLI(配置 + skill)', 'update:更新 CLI', 'uninstall:卸载 CLI', 'remove:卸载 CLI', 'doctor:系统自检', 'changelog:查看版本变更'];
|
|
58
|
+
const cmds = builtins.concat(commandNames.map((name) => `${name}:`));
|
|
59
|
+
return `# ${appName} zsh completion
|
|
60
|
+
# 安装: source <(${appName} completion zsh)
|
|
61
|
+
# 或添加到 ~/.zshrc
|
|
62
|
+
|
|
63
|
+
_${appName}() {
|
|
64
|
+
local -a commands
|
|
65
|
+
commands=(
|
|
66
|
+
${cmds.map((c) => `"${c}"`).join('\n ')}
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
_describe -t commands "${appName} commands" commands
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
compdef _${appName} ${appName}
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
function generateFishCompletion(commandNames, appName) {
|
|
76
|
+
const builtins = ['help', 'list', 'version', 'install', 'update', 'uninstall', 'remove', 'doctor', 'changelog'];
|
|
77
|
+
const all = [...builtins, ...commandNames];
|
|
78
|
+
return `# ${appName} fish completion
|
|
79
|
+
# 安装: source <(${appName} completion fish)
|
|
80
|
+
# 或添加到 ~/.config/fish/completions/${appName}.fish
|
|
81
|
+
|
|
82
|
+
complete -c ${appName} -f -a "help" -d "显示帮助信息"
|
|
83
|
+
complete -c ${appName} -f -a "list" -d "列出所有命令"
|
|
84
|
+
complete -c ${appName} -f -a "version" -d "显示版本号"
|
|
85
|
+
complete -c ${appName} -f -a "install" -d "安装 CLI(配置 + skill)"
|
|
86
|
+
complete -c ${appName} -f -a "update" -d "更新 CLI"
|
|
87
|
+
complete -c ${appName} -f -a "uninstall" -d "卸载 CLI"
|
|
88
|
+
complete -c ${appName} -f -a "remove" -d "卸载 CLI"
|
|
89
|
+
complete -c ${appName} -f -a "doctor" -d "系统自检"
|
|
90
|
+
complete -c ${appName} -f -a "changelog" -d "查看版本变更"
|
|
91
|
+
${commandNames.map((name) => `complete -c ${appName} -f -a "${name}" -d ""`).join('\n')}
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/core/completion.ts"],"names":[],"mappings":"AAIA,SAAS,eAAe,CAAC,QAA4B;IACnD,IAAI,QAAQ,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACvC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,wBAAwB,CACtC,QAAgC,EAChC,OAAe,EACf,QAAiB;IAEjB,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAExD,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACpB,OAAO,qBAAqB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,sBAAsB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,sBAAsB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAsB,EAAE,OAAe;IACrE,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAChH,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,YAAY,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,MAAM,GAAG;QACb,KAAK,OAAO,kBAAkB;QAC9B,kBAAkB,OAAO,mBAAmB;QAC5C,kBAAkB;QAClB,EAAE;QACF,IAAI,OAAO,MAAM;QACjB,yCAAyC;QACzC,4CAA4C;QAC5C,EAAE;QACF,qBAAqB;QACrB,mEAAmE;QACnE,gCAAgC,QAAQ,kBAAkB;QAC1D,cAAc;QACd,MAAM;QACN,EAAE;QACF,mCAAmC;QACnC,gCAAgC,QAAQ,kBAAkB;QAC1D,cAAc;QACd,MAAM;QACN,EAAE;QACF,WAAW;QACX,kCAAkC;QAClC,oDAAoD;QACpD,cAAc;QACd,MAAM;QACN,GAAG;QACH,EAAE;QACF,gBAAgB,OAAO,IAAI,OAAO,EAAE;QACpC,EAAE;KACH,CAAC;IAEF,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,qBAAqB,CAAC,YAAsB,EAAE,OAAe;IACpE,MAAM,QAAQ,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,4BAA4B,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC;IACxL,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;IAErE,OAAO,KAAK,OAAO;iBACJ,OAAO;;;GAGrB,OAAO;;;MAGJ,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;;;2BAGnB,OAAO;;;WAGvB,OAAO,IAAI,OAAO;CAC5B,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAsB,EAAE,OAAe;IACrE,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAChH,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,YAAY,CAAC,CAAC;IAE3C,OAAO,KAAK,OAAO;iBACJ,OAAO;oCACY,OAAO;;cAE7B,OAAO;cACP,OAAO;cACP,OAAO;cACP,OAAO;cACP,OAAO;cACP,OAAO;cACP,OAAO;cACP,OAAO;cACP,OAAO;EACnB,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,OAAO,WAAW,IAAI,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;CACtF,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface CheckResult {
|
|
2
|
+
name: string;
|
|
3
|
+
status: 'pass' | 'warn' | 'fail' | 'skip';
|
|
4
|
+
message: string;
|
|
5
|
+
detail?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DoctorReport {
|
|
8
|
+
timestamp: string;
|
|
9
|
+
nodeVersion: string;
|
|
10
|
+
platform: string;
|
|
11
|
+
checks: CheckResult[];
|
|
12
|
+
}
|
|
13
|
+
export declare function runDoctor(args: string[]): Promise<DoctorReport>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { loadConfig } from '../services/yapi/config.js';
|
|
5
|
+
function collectBasicChecks() {
|
|
6
|
+
const checks = [];
|
|
7
|
+
// Node 版本检查
|
|
8
|
+
const nodeVersion = process.versions.node;
|
|
9
|
+
const major = Number(nodeVersion.split('.')[0]);
|
|
10
|
+
if (major >= 18) {
|
|
11
|
+
checks.push({ name: 'Node.js 版本', status: 'pass', message: `v${nodeVersion}(>= 18)` });
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
checks.push({ name: 'Node.js 版本', status: 'fail', message: `v${nodeVersion}(需要 >= 18)` });
|
|
15
|
+
}
|
|
16
|
+
// npm/pnpm 是否可用
|
|
17
|
+
const packageManager = process.env.npm_config_user_agent || '未知';
|
|
18
|
+
checks.push({ name: '包管理器', status: 'pass', message: packageManager });
|
|
19
|
+
return checks;
|
|
20
|
+
}
|
|
21
|
+
function collectConfigChecks() {
|
|
22
|
+
const checks = [];
|
|
23
|
+
const configDir = join(homedir(), '.yapi');
|
|
24
|
+
if (!existsSync(configDir)) {
|
|
25
|
+
checks.push({ name: '配置目录 ~/.yapi', status: 'fail', message: '不存在', detail: '请运行 `yapi config-init` 或 `yapi install --server <url>`' });
|
|
26
|
+
return checks;
|
|
27
|
+
}
|
|
28
|
+
checks.push({ name: '配置目录 ~/.yapi', status: 'pass', message: '已创建' });
|
|
29
|
+
const config = loadConfig();
|
|
30
|
+
if (!config) {
|
|
31
|
+
checks.push({ name: '配置文件 config.json', status: 'fail', message: '不存在或无法解析' });
|
|
32
|
+
return checks;
|
|
33
|
+
}
|
|
34
|
+
checks.push({ name: '配置文件 config.json', status: 'pass', message: '已加载' });
|
|
35
|
+
checks.push({ name: '服务器地址', status: 'pass', message: config.serverUrl });
|
|
36
|
+
if (config.token) {
|
|
37
|
+
checks.push({ name: 'API Token', status: 'pass', message: '已设置' });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
checks.push({ name: 'API Token', status: 'warn', message: '未设置', detail: '部分功能需要 token' });
|
|
41
|
+
}
|
|
42
|
+
if (config.projectId) {
|
|
43
|
+
checks.push({ name: '默认项目 ID', status: 'pass', message: String(config.projectId) });
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
checks.push({ name: '默认项目 ID', status: 'warn', message: '未设置', detail: '可通过 --project-id 参数指定' });
|
|
47
|
+
}
|
|
48
|
+
return checks;
|
|
49
|
+
}
|
|
50
|
+
async function collectNetworkChecks() {
|
|
51
|
+
const checks = [];
|
|
52
|
+
const config = loadConfig();
|
|
53
|
+
if (!config?.serverUrl) {
|
|
54
|
+
checks.push({ name: '网络连通性', status: 'skip', message: '未配置服务器地址' });
|
|
55
|
+
return checks;
|
|
56
|
+
}
|
|
57
|
+
const url = config.serverUrl.replace(/\/+$/, '');
|
|
58
|
+
try {
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
const timer = setTimeout(() => controller.abort(), 5000);
|
|
61
|
+
const response = await fetch(`${url}/api/user/status`, { signal: controller.signal });
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
if (response.ok) {
|
|
64
|
+
checks.push({ name: '网络连通性', status: 'pass', message: `${url}/api/user/status → ${response.status}` });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
checks.push({
|
|
68
|
+
name: '网络连通性',
|
|
69
|
+
status: 'warn',
|
|
70
|
+
message: `${url}/api/user/status → ${response.status}`,
|
|
71
|
+
detail: `服务器响应 ${response.status},请检查 URL 或网络`,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
77
|
+
checks.push({ name: '网络连通性', status: 'fail', message, detail: '请检查网络连接或服务器地址' });
|
|
78
|
+
}
|
|
79
|
+
return checks;
|
|
80
|
+
}
|
|
81
|
+
export async function runDoctor(args) {
|
|
82
|
+
const isVerbose = args.includes('--verbose');
|
|
83
|
+
const isJson = args.includes('--json');
|
|
84
|
+
const report = {
|
|
85
|
+
timestamp: new Date().toISOString(),
|
|
86
|
+
nodeVersion: process.versions.node,
|
|
87
|
+
platform: `${process.platform}/${process.arch}`,
|
|
88
|
+
checks: [
|
|
89
|
+
...collectBasicChecks(),
|
|
90
|
+
...collectConfigChecks(),
|
|
91
|
+
...(isVerbose ? await collectNetworkChecks() : []),
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
if (isJson) {
|
|
95
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
96
|
+
return report;
|
|
97
|
+
}
|
|
98
|
+
const lines = [];
|
|
99
|
+
const total = report.checks.length;
|
|
100
|
+
const passed = report.checks.filter((c) => c.status === 'pass').length;
|
|
101
|
+
const warnings = report.checks.filter((c) => c.status === 'warn').length;
|
|
102
|
+
const failed = report.checks.filter((c) => c.status === 'fail').length;
|
|
103
|
+
lines.push('🔍 YApi CLI 自检报告');
|
|
104
|
+
lines.push(` 时间: ${report.timestamp}`);
|
|
105
|
+
lines.push(` 系统: ${report.platform}`);
|
|
106
|
+
lines.push(` Node: v${report.nodeVersion}`);
|
|
107
|
+
lines.push('');
|
|
108
|
+
for (const check of report.checks) {
|
|
109
|
+
const icon = check.status === 'pass' ? '✅' : check.status === 'warn' ? '⚠️' : check.status === 'fail' ? '❌' : '➖';
|
|
110
|
+
lines.push(` ${icon} ${check.name}: ${check.message}`);
|
|
111
|
+
if (check.detail) {
|
|
112
|
+
lines.push(` ${check.detail}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
lines.push('');
|
|
116
|
+
lines.push(` 结果: ${passed} 通过, ${warnings} 警告, ${failed} 失败, 共 ${total} 项`);
|
|
117
|
+
if (!isVerbose) {
|
|
118
|
+
lines.push('');
|
|
119
|
+
lines.push('提示: 使用 --verbose 可包含网络连通性检查');
|
|
120
|
+
}
|
|
121
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
122
|
+
return report;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 错误类层次。
|
|
3
|
+
* 每个错误携带机器可读 code + 可读 hint + 语义 exitCode,
|
|
4
|
+
* 供 cli.ts 集中捕获并设置 process.exitCode。
|
|
5
|
+
*/
|
|
6
|
+
export declare class CliError extends Error {
|
|
7
|
+
readonly exitCode: number;
|
|
8
|
+
readonly code?: string | undefined;
|
|
9
|
+
readonly hint?: string | undefined;
|
|
10
|
+
constructor(message: string, exitCode?: number, code?: string | undefined, hint?: string | undefined);
|
|
11
|
+
}
|
|
12
|
+
/** 参数验证错误(如缺少必填参数、类型不对) */
|
|
13
|
+
export declare class CliValidationError extends CliError {
|
|
14
|
+
constructor(message?: string, hint?: string);
|
|
15
|
+
}
|
|
16
|
+
/** 认证失败(如 token 过期、未登录) */
|
|
17
|
+
export declare class CliAuthError extends CliError {
|
|
18
|
+
constructor(message?: string, hint?: string);
|
|
19
|
+
}
|
|
20
|
+
/** 资源未找到 */
|
|
21
|
+
export declare class CliNotFoundError extends CliError {
|
|
22
|
+
constructor(message?: string, hint?: string);
|
|
23
|
+
}
|
|
24
|
+
/** 配置错误(如未初始化) */
|
|
25
|
+
export declare class CliConfigError extends CliError {
|
|
26
|
+
constructor(message?: string, hint?: string);
|
|
27
|
+
}
|
|
28
|
+
/** 网络错误 */
|
|
29
|
+
export declare class CliNetworkError extends CliError {
|
|
30
|
+
constructor(message?: string, hint?: string);
|
|
31
|
+
}
|
|
32
|
+
/** 业务逻辑错误(来自 API 的错误响应) */
|
|
33
|
+
export declare class CliApiError extends CliError {
|
|
34
|
+
readonly apiErrCode?: number | undefined;
|
|
35
|
+
constructor(message: string, apiErrCode?: number | undefined, hint?: string);
|
|
36
|
+
}
|
|
37
|
+
/** 检查错误是否为 CliError 并设置 exitCode。返回 human 消息 */
|
|
38
|
+
export declare function handleCliError(err: unknown): string;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 错误类层次。
|
|
3
|
+
* 每个错误携带机器可读 code + 可读 hint + 语义 exitCode,
|
|
4
|
+
* 供 cli.ts 集中捕获并设置 process.exitCode。
|
|
5
|
+
*/
|
|
6
|
+
export class CliError extends Error {
|
|
7
|
+
constructor(message, exitCode = 1, code, hint) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.exitCode = exitCode;
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.hint = hint;
|
|
12
|
+
this.name = 'CliError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** 参数验证错误(如缺少必填参数、类型不对) */
|
|
16
|
+
export class CliValidationError extends CliError {
|
|
17
|
+
constructor(message = '参数错误', hint) {
|
|
18
|
+
super(message, 9, 'VALIDATION_ERROR', hint);
|
|
19
|
+
this.name = 'CliValidationError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** 认证失败(如 token 过期、未登录) */
|
|
23
|
+
export class CliAuthError extends CliError {
|
|
24
|
+
constructor(message = '认证失败,请重新登录', hint) {
|
|
25
|
+
super(message, 10, 'AUTH_FAILED', hint);
|
|
26
|
+
this.name = 'CliAuthError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** 资源未找到 */
|
|
30
|
+
export class CliNotFoundError extends CliError {
|
|
31
|
+
constructor(message = '未找到', hint) {
|
|
32
|
+
super(message, 11, 'NOT_FOUND', hint);
|
|
33
|
+
this.name = 'CliNotFoundError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** 配置错误(如未初始化) */
|
|
37
|
+
export class CliConfigError extends CliError {
|
|
38
|
+
constructor(message = '配置错误', hint) {
|
|
39
|
+
super(message, 12, 'CONFIG_ERROR', hint);
|
|
40
|
+
this.name = 'CliConfigError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** 网络错误 */
|
|
44
|
+
export class CliNetworkError extends CliError {
|
|
45
|
+
constructor(message = '网络错误', hint) {
|
|
46
|
+
super(message, 13, 'NETWORK_ERROR', hint);
|
|
47
|
+
this.name = 'CliNetworkError';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** 业务逻辑错误(来自 API 的错误响应) */
|
|
51
|
+
export class CliApiError extends CliError {
|
|
52
|
+
constructor(message, apiErrCode, hint) {
|
|
53
|
+
super(message, 14, 'API_ERROR', hint);
|
|
54
|
+
this.apiErrCode = apiErrCode;
|
|
55
|
+
this.name = 'CliApiError';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** 检查错误是否为 CliError 并设置 exitCode。返回 human 消息 */
|
|
59
|
+
export function handleCliError(err) {
|
|
60
|
+
if (err instanceof CliError) {
|
|
61
|
+
process.exitCode = err.exitCode;
|
|
62
|
+
let msg = err.message;
|
|
63
|
+
if (err.hint)
|
|
64
|
+
msg += `\n提示: ${err.hint}`;
|
|
65
|
+
return msg;
|
|
66
|
+
}
|
|
67
|
+
if (err instanceof Error) {
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
return err.message;
|
|
70
|
+
}
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return String(err);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,YACE,OAAe,EACN,WAAmB,CAAC,EACpB,IAAa,EACb,IAAa;QAEtB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,aAAQ,GAAR,QAAQ,CAAY;QACpB,SAAI,GAAJ,IAAI,CAAS;QACb,SAAI,GAAJ,IAAI,CAAS;QAGtB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,2BAA2B;AAC3B,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC9C,YAAY,OAAO,GAAG,MAAM,EAAE,IAAa;QACzC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,2BAA2B;AAC3B,MAAM,OAAO,YAAa,SAAQ,QAAQ;IACxC,YAAY,OAAO,GAAG,YAAY,EAAE,IAAa;QAC/C,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,YAAY;AACZ,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAC5C,YAAY,OAAO,GAAG,KAAK,EAAE,IAAa;QACxC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,kBAAkB;AAClB,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAC1C,YAAY,OAAO,GAAG,MAAM,EAAE,IAAa;QACzC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,WAAW;AACX,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,OAAO,GAAG,MAAM,EAAE,IAAa;QACzC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,2BAA2B;AAC3B,MAAM,OAAO,WAAY,SAAQ,QAAQ;IACvC,YAAY,OAAe,EAAW,UAAmB,EAAE,IAAa;QACtE,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QADF,eAAU,GAAV,UAAU,CAAS;QAEvD,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,gDAAgD;AAChD,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;QAChC,IAAI,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;QACtB,IAAI,GAAG,CAAC,IAAI;YAAE,GAAG,IAAI,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一输出渲染。
|
|
3
|
+
*
|
|
4
|
+
* 支持两种模式:
|
|
5
|
+
* json — 纯 JSON 输出(默认,MCP 协议兼容)
|
|
6
|
+
* pretty — 人类友好格式(列表、表格、颜色标记)
|
|
7
|
+
*
|
|
8
|
+
* 所有命令 handler 统一通过 `output.result(data)` 返回,
|
|
9
|
+
* 由 OutputFormatter 根据格式模式渲染。
|
|
10
|
+
*/
|
|
11
|
+
import type { JsonContentResult } from './cli-registry.js';
|
|
12
|
+
export type OutputFormat = 'json' | 'pretty';
|
|
13
|
+
export declare class OutputFormatter {
|
|
14
|
+
readonly format: OutputFormat;
|
|
15
|
+
private readonly appName;
|
|
16
|
+
constructor(format?: OutputFormat, appName?: string);
|
|
17
|
+
/** 将数据包装为 MCP-compatible 结果 */
|
|
18
|
+
result(data: unknown): JsonContentResult;
|
|
19
|
+
/** 格式化错误信息(输出到 stderr),返回人类可读的消息 */
|
|
20
|
+
printError(err: unknown): string;
|
|
21
|
+
/** 打印帮助或状态信息到 stdout */
|
|
22
|
+
printMessage(msg: string): void;
|
|
23
|
+
/** 将数据格式化为字符串 */
|
|
24
|
+
private formatData;
|
|
25
|
+
private renderTable;
|
|
26
|
+
private renderObject;
|
|
27
|
+
}
|