swagger2api-v3 1.1.9 → 1.1.11
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 +5 -3
- package/dist/.swagger2api.schema.json +6 -2
- package/dist/cli/index.js +22 -21
- package/dist/config/validator.js +94 -9
- package/dist/core/generator.d.ts +83 -11
- package/dist/core/generator.js +295 -94
- package/dist/core/parser.d.ts +20 -16
- package/dist/core/parser.js +72 -103
- package/dist/core/query-parameter-generator.d.ts +26 -0
- package/dist/core/query-parameter-generator.js +114 -0
- package/dist/core/type-generator.d.ts +73 -0
- package/dist/core/type-generator.js +215 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -21
- package/dist/types/index.d.ts +31 -6
- package/dist/utils/comment.d.ts +4 -1
- package/dist/utils/comment.js +6 -2
- package/dist/utils/file.d.ts +10 -3
- package/dist/utils/file.js +49 -19
- 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/naming.js +3 -2
- package/dist/utils/schema.d.ts +79 -0
- package/dist/utils/schema.js +536 -0
- package/dist/utils/type.d.ts +7 -25
- package/dist/utils/type.js +29 -241
- package/package.json +21 -19
|
@@ -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/naming.js
CHANGED
|
@@ -118,7 +118,8 @@ function sanitizeFilename(filename) {
|
|
|
118
118
|
*/
|
|
119
119
|
function sanitizeTypeName(name) {
|
|
120
120
|
if (!name)
|
|
121
|
-
return
|
|
121
|
+
return 'AnonymousType';
|
|
122
122
|
const replaced = name.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
123
|
-
|
|
123
|
+
const typeName = toPascalCase(replaced) || 'AnonymousType';
|
|
124
|
+
return /^\d/.test(typeName) ? `_${typeName}` : typeName;
|
|
124
125
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { SwaggerSchema } from '../types';
|
|
2
|
+
/** Schema 的使用场景 */
|
|
3
|
+
export type SchemaUsage = 'neutral' | 'request' | 'response';
|
|
4
|
+
/** 对象属性类型覆盖 */
|
|
5
|
+
export type SchemaPropertyOverrides = Record<string, string>;
|
|
6
|
+
/**
|
|
7
|
+
* 判断字符串是否为合法 TypeScript 标识符
|
|
8
|
+
* @param name 属性名
|
|
9
|
+
* @returns 是否为合法标识符
|
|
10
|
+
*/
|
|
11
|
+
export declare function isValidIdentifier(name: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* 格式化 TypeScript 属性名
|
|
14
|
+
* @param name 属性名
|
|
15
|
+
* @returns 可用于类型声明的属性名
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatTsPropertyName(name: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* 转义 JSDoc 文本
|
|
20
|
+
* @param text 原始文本
|
|
21
|
+
* @returns 可安全写入单行 JSDoc 的文本
|
|
22
|
+
*/
|
|
23
|
+
export declare function escapeJSDocText(text: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* 移除联合类型中的顶层 null 类型
|
|
26
|
+
* @param typeStr 类型字符串
|
|
27
|
+
* @returns 移除 null 后的类型字符串
|
|
28
|
+
*/
|
|
29
|
+
export declare function stripNullFromUnion(typeStr: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* 判断 Schema 是否应按对象处理
|
|
32
|
+
* @param schema OpenAPI Schema
|
|
33
|
+
* @returns 是否为对象 Schema
|
|
34
|
+
*/
|
|
35
|
+
export declare function isObjectSchema(schema: SwaggerSchema): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* 判断 Schema 是否为项目约定的泛型响应容器
|
|
38
|
+
* @param schema OpenAPI Schema
|
|
39
|
+
* @returns 是否为泛型响应容器
|
|
40
|
+
*/
|
|
41
|
+
export declare function isGenericResponseSchema(schema: SwaggerSchema): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* 获取当前使用场景可见的对象属性
|
|
44
|
+
* @param schema OpenAPI Schema
|
|
45
|
+
* @param usage Schema 使用场景
|
|
46
|
+
* @returns 可见属性数组
|
|
47
|
+
*/
|
|
48
|
+
export declare function getVisibleSchemaProperties(schema: SwaggerSchema, usage?: SchemaUsage): Array<[string, SwaggerSchema]>;
|
|
49
|
+
/**
|
|
50
|
+
* 判断 Schema 在指定场景下是否需要独立类型
|
|
51
|
+
* @param schema OpenAPI Schema
|
|
52
|
+
* @param schemas 全部组件 Schema
|
|
53
|
+
* @param usage Schema 使用场景
|
|
54
|
+
* @returns 是否需要独立类型
|
|
55
|
+
*/
|
|
56
|
+
export declare function schemaNeedsUsageVariant(schema: SwaggerSchema, schemas: Record<string, SwaggerSchema>, usage: Exclude<SchemaUsage, 'neutral'>): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* 渲染对象类型成员
|
|
59
|
+
* @param schema OpenAPI Schema
|
|
60
|
+
* @param schemas 全部组件 Schema
|
|
61
|
+
* @param usage Schema 使用场景
|
|
62
|
+
* @param overrides 属性类型覆盖
|
|
63
|
+
* @returns 对象成员代码
|
|
64
|
+
*/
|
|
65
|
+
export declare function renderObjectMembers(schema: SwaggerSchema, schemas?: Record<string, SwaggerSchema>, usage?: SchemaUsage, overrides?: SchemaPropertyOverrides): string;
|
|
66
|
+
/**
|
|
67
|
+
* 将 OpenAPI Schema 转换为 TypeScript 类型
|
|
68
|
+
* @param schema OpenAPI Schema
|
|
69
|
+
* @param schemas 全部组件 Schema
|
|
70
|
+
* @param usage Schema 使用场景
|
|
71
|
+
* @returns TypeScript 类型字符串
|
|
72
|
+
*/
|
|
73
|
+
export declare function swaggerTypeToTsType(schema: SwaggerSchema | undefined | null, schemas?: Record<string, SwaggerSchema>, usage?: SchemaUsage): string;
|
|
74
|
+
/**
|
|
75
|
+
* 从 $ref 字符串中提取并解码引用名称
|
|
76
|
+
* @param ref OpenAPI $ref 字符串
|
|
77
|
+
* @returns 引用名称
|
|
78
|
+
*/
|
|
79
|
+
export declare function getRefName(ref: string): string;
|