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.
@@ -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();
@@ -118,7 +118,8 @@ function sanitizeFilename(filename) {
118
118
  */
119
119
  function sanitizeTypeName(name) {
120
120
  if (!name)
121
- return name;
121
+ return 'AnonymousType';
122
122
  const replaced = name.replace(/[^a-zA-Z0-9_]/g, '_');
123
- return toPascalCase(replaced);
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;