swagger2api-v3 1.1.8 → 1.1.10
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/README.md +6 -4
- package/dist/.swagger2api.schema.json +4 -0
- package/dist/cli/index.js +20 -19
- package/dist/config/validator.js +2 -0
- package/dist/core/generator.d.ts +18 -0
- package/dist/core/generator.js +73 -25
- package/dist/core/parser.d.ts +14 -0
- package/dist/core/parser.js +76 -54
- package/dist/index.js +22 -19
- package/dist/types/index.d.ts +8 -0
- package/dist/utils/comment.d.ts +18 -3
- package/dist/utils/comment.js +1 -1
- package/dist/utils/file.js +4 -3
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/logger.d.ts +115 -0
- package/dist/utils/logger.js +261 -0
- package/dist/utils/type.d.ts +25 -11
- package/dist/utils/type.js +37 -45
- package/package.json +23 -21
package/dist/index.js
CHANGED
|
@@ -62,32 +62,36 @@ class Swagger2API {
|
|
|
62
62
|
*/
|
|
63
63
|
async generate() {
|
|
64
64
|
try {
|
|
65
|
-
|
|
65
|
+
utils_1.logger.banner('🚀 swagger2api-v3', '开始生成 API 接口文件');
|
|
66
|
+
utils_1.logger.setTotalSteps(4);
|
|
66
67
|
// 1. 加载Swagger文档
|
|
67
|
-
|
|
68
|
+
utils_1.logger.stepTitle('📖', '加载 Swagger 文档');
|
|
68
69
|
const document = await (0, utils_1.loadSwaggerDocument)(this.config.input);
|
|
69
|
-
|
|
70
|
+
utils_1.logger.success(`文档加载成功: ${document.info.title} v${document.info.version}`);
|
|
70
71
|
// 2. 解析文档
|
|
71
|
-
|
|
72
|
+
utils_1.logger.stepTitle('🔍', '解析 API 接口');
|
|
72
73
|
const parser = new parser_1.SwaggerParser(document, this.config);
|
|
73
74
|
const apis = this.filterApis(parser.parseApis());
|
|
74
75
|
const types = parser.parseTypes();
|
|
75
76
|
const groupedApis = parser.groupApisByTags(apis);
|
|
76
|
-
|
|
77
|
+
utils_1.logger.success(`解析完成: ${apis.length} 个接口, ${types.length} 个类型`);
|
|
77
78
|
if (this.config.groupByTags) {
|
|
78
|
-
|
|
79
|
+
utils_1.logger.info(`按标签分组: ${groupedApis.size} 个分组`);
|
|
79
80
|
for (const [tag, tagApis] of groupedApis) {
|
|
80
|
-
|
|
81
|
+
utils_1.logger.listItem(tag, `${tagApis.length} 个接口`);
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
// 3. 生成代码
|
|
84
|
-
|
|
85
|
+
utils_1.logger.stepTitle('⚡', '生成代码文件');
|
|
85
86
|
const generator = new generator_1.CodeGenerator(this.config);
|
|
86
87
|
await generator.generateAll(apis, types, groupedApis);
|
|
87
|
-
|
|
88
|
+
// 4. 完成
|
|
89
|
+
utils_1.logger.stepTitle('📦', '生成完成');
|
|
90
|
+
utils_1.logger.path('输出目录', this.config.output);
|
|
91
|
+
utils_1.logger.done('API 接口文件生成完成');
|
|
88
92
|
}
|
|
89
93
|
catch (error) {
|
|
90
|
-
|
|
94
|
+
utils_1.logger.error('生成失败', error);
|
|
91
95
|
throw error;
|
|
92
96
|
}
|
|
93
97
|
}
|
|
@@ -97,8 +101,7 @@ class Swagger2API {
|
|
|
97
101
|
validateConfig() {
|
|
98
102
|
const errors = (0, validator_1.validateSwaggerConfig)(this.config);
|
|
99
103
|
if (errors.length > 0) {
|
|
100
|
-
|
|
101
|
-
errors.forEach((error) => console.error(` - ${error}`));
|
|
104
|
+
utils_1.logger.errorList('配置验证失败:', errors);
|
|
102
105
|
return false;
|
|
103
106
|
}
|
|
104
107
|
return true;
|
|
@@ -134,9 +137,9 @@ async function generateFromConfig(configPath) {
|
|
|
134
137
|
let config;
|
|
135
138
|
// 读取并解析 JSON 配置文件
|
|
136
139
|
if (!fs.existsSync(fullPath)) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
+
utils_1.logger.error(`找不到配置文件: ${fullPath}`);
|
|
141
|
+
utils_1.logger.error('请确保配置文件存在并且路径正确');
|
|
142
|
+
utils_1.logger.error('提示: 运行 swagger2api-v3 init 来创建配置文件');
|
|
140
143
|
process.exit(1);
|
|
141
144
|
}
|
|
142
145
|
const configContent = fs.readFileSync(fullPath, 'utf-8');
|
|
@@ -149,12 +152,12 @@ async function generateFromConfig(configPath) {
|
|
|
149
152
|
}
|
|
150
153
|
catch (error) {
|
|
151
154
|
if (error instanceof SyntaxError) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
utils_1.logger.error(`配置文件 JSON 格式错误: ${fullPath}`);
|
|
156
|
+
utils_1.logger.error('请检查 JSON 语法是否正确');
|
|
157
|
+
utils_1.logger.error(`错误详情: ${error.message}`);
|
|
155
158
|
}
|
|
156
159
|
else {
|
|
157
|
-
|
|
160
|
+
utils_1.logger.error('加载配置文件失败', error);
|
|
158
161
|
}
|
|
159
162
|
process.exit(1);
|
|
160
163
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface SwaggerConfig {
|
|
|
15
15
|
generator: 'typescript' | 'javascript';
|
|
16
16
|
/** 按 tags 分组生成文件 */
|
|
17
17
|
groupByTags: boolean;
|
|
18
|
+
/** 多 tag 接口分组策略,first 只使用第一个 tag,all 将所有 tags 合成一个分组 */
|
|
19
|
+
multiTagStrategy?: 'first' | 'all';
|
|
18
20
|
/** 是否覆盖更新,默认为true。为true时会先删除输出目录下的所有文件 */
|
|
19
21
|
overwrite?: boolean;
|
|
20
22
|
/** 接口路径公共前缀,默认为空字符串 */
|
|
@@ -286,6 +288,10 @@ export interface SwaggerSchema {
|
|
|
286
288
|
externalDocs?: SwaggerExternalDocs;
|
|
287
289
|
nullable?: boolean;
|
|
288
290
|
deprecated?: boolean;
|
|
291
|
+
/** OpenAPI 扩展字段:枚举变量名 */
|
|
292
|
+
'x-enum-varnames'?: string[];
|
|
293
|
+
/** OpenAPI 扩展字段:枚举名称 */
|
|
294
|
+
'x-enumNames'?: string[];
|
|
289
295
|
}
|
|
290
296
|
/**
|
|
291
297
|
* Swagger项目
|
|
@@ -369,6 +375,8 @@ export interface ApiInfo {
|
|
|
369
375
|
description?: string;
|
|
370
376
|
/** 标签 */
|
|
371
377
|
tags: string[];
|
|
378
|
+
/** 是否废弃 */
|
|
379
|
+
deprecated?: boolean;
|
|
372
380
|
/** 参数 */
|
|
373
381
|
parameters: ParameterInfo[];
|
|
374
382
|
/** 响应类型 */
|
package/dist/utils/comment.d.ts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ParameterInfo } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* 注释生成需要的操作信息
|
|
4
|
+
*/
|
|
5
|
+
export interface ApiCommentOperation {
|
|
6
|
+
/** 接口摘要 */
|
|
7
|
+
summary?: string;
|
|
8
|
+
/** 接口描述 */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** 是否废弃 */
|
|
11
|
+
deprecated?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 注释生成需要的参数信息
|
|
15
|
+
*/
|
|
16
|
+
export type ApiCommentParameter = Pick<ParameterInfo, 'in' | 'description'>;
|
|
2
17
|
/**
|
|
3
18
|
* 生成接口注释
|
|
4
|
-
* @param operation
|
|
19
|
+
* @param operation 接口操作信息
|
|
5
20
|
* @param parameters 参数列表
|
|
6
21
|
* @returns 注释字符串
|
|
7
22
|
*/
|
|
8
|
-
export declare function generateApiComment(operation:
|
|
23
|
+
export declare function generateApiComment(operation: ApiCommentOperation, parameters: ApiCommentParameter[]): string;
|
package/dist/utils/comment.js
CHANGED
package/dist/utils/file.js
CHANGED
|
@@ -43,6 +43,7 @@ exports.writeFile = writeFile;
|
|
|
43
43
|
const fs = __importStar(require("fs"));
|
|
44
44
|
const path = __importStar(require("path"));
|
|
45
45
|
const axios_1 = __importDefault(require("axios"));
|
|
46
|
+
const logger_1 = require("./logger");
|
|
46
47
|
/**
|
|
47
48
|
* 确保目录存在,如果不存在则创建
|
|
48
49
|
* @param dirPath 目录路径
|
|
@@ -70,12 +71,12 @@ async function loadSwaggerDocument(input) {
|
|
|
70
71
|
try {
|
|
71
72
|
if (input.startsWith('http://') || input.startsWith('https://')) {
|
|
72
73
|
const { data } = await axios_1.default.get(input);
|
|
73
|
-
|
|
74
|
+
logger_1.logger.debug(`从 URL 加载: ${input}`);
|
|
74
75
|
if (data.components?.schemas) {
|
|
75
|
-
|
|
76
|
+
logger_1.logger.debugKV('schemas 数量', Object.keys(data.components.schemas).length);
|
|
76
77
|
}
|
|
77
78
|
else {
|
|
78
|
-
|
|
79
|
+
logger_1.logger.debug('加载的数据中未发现 schemas');
|
|
79
80
|
}
|
|
80
81
|
return data;
|
|
81
82
|
}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轻量级终端日志工具(零依赖,基于 ANSI 转义码)
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 日志工具类
|
|
6
|
+
*
|
|
7
|
+
* 提供统一的、带颜色的终端输出格式。
|
|
8
|
+
* error 方法不使用颜色码,确保 console.error 的参数为纯文本,
|
|
9
|
+
* 兼容测试中对 console.error 的 spy 断言。
|
|
10
|
+
*/
|
|
11
|
+
declare class Logger {
|
|
12
|
+
private step;
|
|
13
|
+
private totalSteps;
|
|
14
|
+
/**
|
|
15
|
+
* 写入标准输出
|
|
16
|
+
* @param message 输出内容
|
|
17
|
+
*/
|
|
18
|
+
private log;
|
|
19
|
+
/**
|
|
20
|
+
* 写入错误输出
|
|
21
|
+
* @param message 输出内容
|
|
22
|
+
*/
|
|
23
|
+
private fail;
|
|
24
|
+
/**
|
|
25
|
+
* 格式化未知错误
|
|
26
|
+
* @param error 错误对象
|
|
27
|
+
* @returns 错误文案
|
|
28
|
+
*/
|
|
29
|
+
private formatError;
|
|
30
|
+
/**
|
|
31
|
+
* 输出带图标的状态行
|
|
32
|
+
* @param symbol 状态图标
|
|
33
|
+
* @param message 消息内容
|
|
34
|
+
*/
|
|
35
|
+
private status;
|
|
36
|
+
/**
|
|
37
|
+
* 设置总步骤数
|
|
38
|
+
* @param n 步骤总数
|
|
39
|
+
*/
|
|
40
|
+
setTotalSteps(n: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* 输出步骤标题
|
|
43
|
+
* @param emoji 步骤图标
|
|
44
|
+
* @param title 步骤标题
|
|
45
|
+
*/
|
|
46
|
+
stepTitle(emoji: string, title: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* 输出成功信息
|
|
49
|
+
* @param message 消息内容
|
|
50
|
+
*/
|
|
51
|
+
success(message: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* 输出信息
|
|
54
|
+
* @param message 消息内容
|
|
55
|
+
*/
|
|
56
|
+
info(message: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* 输出文件/路径信息
|
|
59
|
+
* @param label 标签
|
|
60
|
+
* @param path 路径
|
|
61
|
+
*/
|
|
62
|
+
path(label: string, path: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* 输出警告信息
|
|
65
|
+
* @param message 消息内容
|
|
66
|
+
*/
|
|
67
|
+
warn(message: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* 输出错误信息(不使用颜色码,兼容测试断言)
|
|
70
|
+
* @param message 消息内容
|
|
71
|
+
* @param error 错误对象
|
|
72
|
+
*/
|
|
73
|
+
error(message: string, error?: unknown): void;
|
|
74
|
+
/**
|
|
75
|
+
* 输出错误列表
|
|
76
|
+
* @param title 错误标题
|
|
77
|
+
* @param items 错误项列表
|
|
78
|
+
*/
|
|
79
|
+
errorList(title: string, items: string[]): void;
|
|
80
|
+
/**
|
|
81
|
+
* 输出调试信息(灰色暗淡)
|
|
82
|
+
* @param message 消息内容
|
|
83
|
+
*/
|
|
84
|
+
debug(message: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* 输出调试键值对
|
|
87
|
+
* @param key 键名
|
|
88
|
+
* @param value 键值
|
|
89
|
+
*/
|
|
90
|
+
debugKV(key: string, value: string | number | boolean): void;
|
|
91
|
+
/**
|
|
92
|
+
* 输出列表项
|
|
93
|
+
* @param label 列表项标签
|
|
94
|
+
* @param detail 列表项详情
|
|
95
|
+
*/
|
|
96
|
+
listItem(label: string, detail: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* 输出分隔线
|
|
99
|
+
*/
|
|
100
|
+
divider(): void;
|
|
101
|
+
/**
|
|
102
|
+
* 输出横幅标题
|
|
103
|
+
* @param title 标题
|
|
104
|
+
* @param subtitle 副标题(可选)
|
|
105
|
+
*/
|
|
106
|
+
banner(title: string, subtitle?: string): void;
|
|
107
|
+
/**
|
|
108
|
+
* 输出完成横幅
|
|
109
|
+
* @param message 完成消息
|
|
110
|
+
*/
|
|
111
|
+
done(message: string): void;
|
|
112
|
+
}
|
|
113
|
+
/** 日志单例 */
|
|
114
|
+
export declare const logger: Logger;
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 轻量级终端日志工具(零依赖,基于 ANSI 转义码)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.logger = void 0;
|
|
7
|
+
/** 终端是否支持颜色输出 */
|
|
8
|
+
const supportsColor = process.stdout.isTTY &&
|
|
9
|
+
process.env.NODE_ENV !== 'test' &&
|
|
10
|
+
process.env.NO_COLOR === undefined;
|
|
11
|
+
/** 日志左侧缩进 */
|
|
12
|
+
const INDENT = ' ';
|
|
13
|
+
/** 列表标签默认宽度 */
|
|
14
|
+
const LIST_LABEL_WIDTH = 22;
|
|
15
|
+
/** 日志图标 */
|
|
16
|
+
const icon = {
|
|
17
|
+
success: '✅',
|
|
18
|
+
info: 'ℹ',
|
|
19
|
+
warn: '⚠',
|
|
20
|
+
error: '❌',
|
|
21
|
+
debug: '·',
|
|
22
|
+
path: '📂',
|
|
23
|
+
bullet: '•'
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* 包裹 ANSI 颜色码
|
|
27
|
+
* @param code ANSI 转义码
|
|
28
|
+
* @param text 文本内容
|
|
29
|
+
* @returns 带颜色的字符串(不支持颜色时返回原文)
|
|
30
|
+
*/
|
|
31
|
+
function wrap(code, text) {
|
|
32
|
+
return supportsColor ? `\x1b[${code}m${text}\x1b[0m` : text;
|
|
33
|
+
}
|
|
34
|
+
/** 颜色与样式快捷方法 */
|
|
35
|
+
const style = {
|
|
36
|
+
/**
|
|
37
|
+
* 加粗文本
|
|
38
|
+
* @param text 文本内容
|
|
39
|
+
* @returns 格式化后的文本
|
|
40
|
+
*/
|
|
41
|
+
bold(text) {
|
|
42
|
+
return wrap('1', text);
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* 弱化文本
|
|
46
|
+
* @param text 文本内容
|
|
47
|
+
* @returns 格式化后的文本
|
|
48
|
+
*/
|
|
49
|
+
dim(text) {
|
|
50
|
+
return wrap('2', text);
|
|
51
|
+
},
|
|
52
|
+
/**
|
|
53
|
+
* 绿色文本
|
|
54
|
+
* @param text 文本内容
|
|
55
|
+
* @returns 格式化后的文本
|
|
56
|
+
*/
|
|
57
|
+
green(text) {
|
|
58
|
+
return wrap('32', text);
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* 黄色文本
|
|
62
|
+
* @param text 文本内容
|
|
63
|
+
* @returns 格式化后的文本
|
|
64
|
+
*/
|
|
65
|
+
yellow(text) {
|
|
66
|
+
return wrap('33', text);
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* 紫色文本
|
|
70
|
+
* @param text 文本内容
|
|
71
|
+
* @returns 格式化后的文本
|
|
72
|
+
*/
|
|
73
|
+
magenta(text) {
|
|
74
|
+
return wrap('35', text);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* 青色文本
|
|
78
|
+
* @param text 文本内容
|
|
79
|
+
* @returns 格式化后的文本
|
|
80
|
+
*/
|
|
81
|
+
cyan(text) {
|
|
82
|
+
return wrap('36', text);
|
|
83
|
+
},
|
|
84
|
+
/**
|
|
85
|
+
* 灰色文本
|
|
86
|
+
* @param text 文本内容
|
|
87
|
+
* @returns 格式化后的文本
|
|
88
|
+
*/
|
|
89
|
+
gray(text) {
|
|
90
|
+
return wrap('90', text);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* 日志工具类
|
|
95
|
+
*
|
|
96
|
+
* 提供统一的、带颜色的终端输出格式。
|
|
97
|
+
* error 方法不使用颜色码,确保 console.error 的参数为纯文本,
|
|
98
|
+
* 兼容测试中对 console.error 的 spy 断言。
|
|
99
|
+
*/
|
|
100
|
+
class Logger {
|
|
101
|
+
constructor() {
|
|
102
|
+
this.step = 0;
|
|
103
|
+
this.totalSteps = 0;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 写入标准输出
|
|
107
|
+
* @param message 输出内容
|
|
108
|
+
*/
|
|
109
|
+
log(message = '') {
|
|
110
|
+
console.log(message);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 写入错误输出
|
|
114
|
+
* @param message 输出内容
|
|
115
|
+
*/
|
|
116
|
+
fail(message) {
|
|
117
|
+
console.error(message);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 格式化未知错误
|
|
121
|
+
* @param error 错误对象
|
|
122
|
+
* @returns 错误文案
|
|
123
|
+
*/
|
|
124
|
+
formatError(error) {
|
|
125
|
+
if (error instanceof Error) {
|
|
126
|
+
return error.message ? `${error.name}: ${error.message}` : error.name;
|
|
127
|
+
}
|
|
128
|
+
return String(error);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 输出带图标的状态行
|
|
132
|
+
* @param symbol 状态图标
|
|
133
|
+
* @param message 消息内容
|
|
134
|
+
*/
|
|
135
|
+
status(symbol, message) {
|
|
136
|
+
this.log(`${INDENT}${symbol} ${message}`);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 设置总步骤数
|
|
140
|
+
* @param n 步骤总数
|
|
141
|
+
*/
|
|
142
|
+
setTotalSteps(n) {
|
|
143
|
+
this.totalSteps = n;
|
|
144
|
+
this.step = 0;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 输出步骤标题
|
|
148
|
+
* @param emoji 步骤图标
|
|
149
|
+
* @param title 步骤标题
|
|
150
|
+
*/
|
|
151
|
+
stepTitle(emoji, title) {
|
|
152
|
+
this.step++;
|
|
153
|
+
const progress = this.totalSteps > 0
|
|
154
|
+
? style.dim(`[${this.step}/${this.totalSteps}] `)
|
|
155
|
+
: '';
|
|
156
|
+
this.log();
|
|
157
|
+
this.log(`${INDENT}${progress}${emoji} ${style.bold(title)}`);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 输出成功信息
|
|
161
|
+
* @param message 消息内容
|
|
162
|
+
*/
|
|
163
|
+
success(message) {
|
|
164
|
+
this.status(style.green(icon.success), message);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 输出信息
|
|
168
|
+
* @param message 消息内容
|
|
169
|
+
*/
|
|
170
|
+
info(message) {
|
|
171
|
+
this.status(style.cyan(icon.info), message);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 输出文件/路径信息
|
|
175
|
+
* @param label 标签
|
|
176
|
+
* @param path 路径
|
|
177
|
+
*/
|
|
178
|
+
path(label, path) {
|
|
179
|
+
this.status(icon.path, `${style.dim(label)}: ${style.bold(path)}`);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* 输出警告信息
|
|
183
|
+
* @param message 消息内容
|
|
184
|
+
*/
|
|
185
|
+
warn(message) {
|
|
186
|
+
this.status(style.yellow(icon.warn), message);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 输出错误信息(不使用颜色码,兼容测试断言)
|
|
190
|
+
* @param message 消息内容
|
|
191
|
+
* @param error 错误对象
|
|
192
|
+
*/
|
|
193
|
+
error(message, error) {
|
|
194
|
+
const detail = error === undefined ? message : `${message}: ${this.formatError(error)}`;
|
|
195
|
+
this.fail(`${icon.error} ${detail}`);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 输出错误列表
|
|
199
|
+
* @param title 错误标题
|
|
200
|
+
* @param items 错误项列表
|
|
201
|
+
*/
|
|
202
|
+
errorList(title, items) {
|
|
203
|
+
this.fail(`${icon.error} ${title}`);
|
|
204
|
+
items.forEach((item) => this.fail(`${INDENT} - ${item}`));
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* 输出调试信息(灰色暗淡)
|
|
208
|
+
* @param message 消息内容
|
|
209
|
+
*/
|
|
210
|
+
debug(message) {
|
|
211
|
+
this.status(style.gray(icon.debug), style.gray(message));
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 输出调试键值对
|
|
215
|
+
* @param key 键名
|
|
216
|
+
* @param value 键值
|
|
217
|
+
*/
|
|
218
|
+
debugKV(key, value) {
|
|
219
|
+
this.status(style.gray(icon.debug), `${style.gray(key)}: ${style.gray(String(value))}`);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* 输出列表项
|
|
223
|
+
* @param label 列表项标签
|
|
224
|
+
* @param detail 列表项详情
|
|
225
|
+
*/
|
|
226
|
+
listItem(label, detail) {
|
|
227
|
+
const paddedLabel = label.padEnd(LIST_LABEL_WIDTH, ' ');
|
|
228
|
+
this.log(`${INDENT} ${style.dim(icon.bullet)} ${style.cyan(paddedLabel)} ${style.dim(detail)}`);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* 输出分隔线
|
|
232
|
+
*/
|
|
233
|
+
divider() {
|
|
234
|
+
const line = '─'.repeat(48);
|
|
235
|
+
this.log(`${INDENT}${style.dim(line)}`);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* 输出横幅标题
|
|
239
|
+
* @param title 标题
|
|
240
|
+
* @param subtitle 副标题(可选)
|
|
241
|
+
*/
|
|
242
|
+
banner(title, subtitle) {
|
|
243
|
+
this.log();
|
|
244
|
+
this.log(`${INDENT}${style.bold(style.magenta(title))}`);
|
|
245
|
+
if (subtitle) {
|
|
246
|
+
this.log(`${INDENT}${style.dim(subtitle)}`);
|
|
247
|
+
}
|
|
248
|
+
this.log();
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* 输出完成横幅
|
|
252
|
+
* @param message 完成消息
|
|
253
|
+
*/
|
|
254
|
+
done(message) {
|
|
255
|
+
this.log();
|
|
256
|
+
this.log(`${INDENT}${style.green(icon.success)} ${style.bold(message)}`);
|
|
257
|
+
this.log();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/** 日志单例 */
|
|
261
|
+
exports.logger = new Logger();
|
package/dist/utils/type.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import { SwaggerParameter } from '../types';
|
|
1
|
+
import { SwaggerParameter, SwaggerSchema, SwaggerResponses } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* 判断字符串是否为合法 TypeScript 标识符
|
|
4
|
+
* @param name 属性名
|
|
5
|
+
* @returns 是否为合法标识符
|
|
6
|
+
*/
|
|
7
|
+
export declare function isValidIdentifier(name: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* 格式化 TypeScript 属性名
|
|
10
|
+
* @param name 属性名
|
|
11
|
+
* @returns 可用于类型声明的属性名
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatTsPropertyName(name: string): string;
|
|
2
14
|
/**
|
|
3
15
|
* 移除联合类型中的顶层 null 类型
|
|
4
16
|
* @param typeStr 类型字符串
|
|
@@ -11,29 +23,31 @@ export declare function stripNullFromUnion(typeStr: string): string;
|
|
|
11
23
|
* @param schemas 可选的 schemas 上下文,用于查找被引用的类型定义
|
|
12
24
|
* @returns TypeScript类型字符串
|
|
13
25
|
*/
|
|
14
|
-
export declare function swaggerTypeToTsType(schema:
|
|
26
|
+
export declare function swaggerTypeToTsType(schema: SwaggerSchema | undefined | null, schemas?: Record<string, SwaggerSchema>): string;
|
|
27
|
+
/**
|
|
28
|
+
* 从 $ref 字符串中提取引用名称
|
|
29
|
+
* @param ref OpenAPI $ref 字符串
|
|
30
|
+
* @returns 引用名称
|
|
31
|
+
*/
|
|
32
|
+
export declare function getRefName(ref: string): string;
|
|
15
33
|
/**
|
|
16
34
|
* 将 OpenAPI 参数转换为 schema 对象
|
|
17
35
|
* @param parameter OpenAPI 参数
|
|
18
36
|
* @returns 参数对应的 schema
|
|
19
37
|
*/
|
|
20
|
-
export declare function swaggerParameterToSchema(parameter: SwaggerParameter):
|
|
21
|
-
/**
|
|
22
|
-
* 从 OpenAPI 参数生成 TypeScript 参数类型
|
|
23
|
-
* @param parameters OpenAPI 参数数组
|
|
24
|
-
* @returns TypeScript参数类型定义
|
|
25
|
-
*/
|
|
26
|
-
export declare function generateParameterTypes(parameters: SwaggerParameter[]): string;
|
|
38
|
+
export declare function swaggerParameterToSchema(parameter: SwaggerParameter): SwaggerSchema;
|
|
27
39
|
/**
|
|
28
40
|
* 获取响应类型
|
|
29
41
|
* @param responses OpenAPI 响应对象
|
|
30
42
|
* @param schemas OpenAPI components.schemas
|
|
31
43
|
* @returns TypeScript类型字符串
|
|
32
44
|
*/
|
|
33
|
-
export declare function getResponseType(responses:
|
|
45
|
+
export declare function getResponseType(responses: SwaggerResponses, schemas?: Record<string, SwaggerSchema>): string;
|
|
34
46
|
/**
|
|
35
47
|
* 从 OpenAPI content 对象中获取最合适的 schema
|
|
36
48
|
* @param content OpenAPI content 对象
|
|
37
49
|
* @returns 匹配到的 schema
|
|
38
50
|
*/
|
|
39
|
-
export declare function getSchemaFromContent(content:
|
|
51
|
+
export declare function getSchemaFromContent(content: Record<string, {
|
|
52
|
+
schema?: SwaggerSchema;
|
|
53
|
+
}> | undefined): SwaggerSchema | undefined;
|