swagger2api-v3 1.0.0

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,412 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CodeGenerator = void 0;
37
+ const path = __importStar(require("path"));
38
+ const utils_1 = require("../utils");
39
+ /**
40
+ * 代码生成器
41
+ */
42
+ class CodeGenerator {
43
+ constructor(config) {
44
+ this.config = config;
45
+ }
46
+ /**
47
+ * 生成所有文件
48
+ * @param apis API接口数组
49
+ * @param types 类型定义数组
50
+ * @param groupedApis 按标签分组的API
51
+ */
52
+ async generateAll(apis, types, groupedApis) {
53
+ // 根据overwrite配置决定是否清空目录
54
+ if (this.config.overwrite !== false) {
55
+ // 默认为true,清空输出目录
56
+ (0, utils_1.removeDirectory)(this.config.output);
57
+ }
58
+ // 确保输出目录存在
59
+ (0, utils_1.ensureDirectoryExists)(this.config.output);
60
+ // 生成类型文件
61
+ if (this.config.options?.generateModels !== false) {
62
+ await this.generateTypesFile(types);
63
+ }
64
+ // 生成API文件
65
+ if (this.config.options?.generateApis !== false) {
66
+ if (this.config.groupByTags) {
67
+ await this.generateApiFilesByTags(groupedApis, types);
68
+ }
69
+ else {
70
+ await this.generateSingleApiFile(apis, types);
71
+ }
72
+ }
73
+ // 生成入口文件
74
+ if (this.config.options?.generateIndex !== false) {
75
+ await this.generateIndexFile(groupedApis);
76
+ }
77
+ // 在所有文件生成完成后执行lint
78
+ if (this.config.lint) {
79
+ await this.runLintOnAllFiles();
80
+ }
81
+ }
82
+ /**
83
+ * 生成类型定义文件
84
+ * @param types 类型定义数组
85
+ */
86
+ async generateTypesFile(types) {
87
+ const content = this.generateTypesContent(types);
88
+ const filePath = path.join(this.config.output, 'types.ts');
89
+ (0, utils_1.writeFile)(filePath, content);
90
+ }
91
+ /**
92
+ * 生成类型文件内容
93
+ * @param types 类型定义数组
94
+ * @returns 类型文件内容
95
+ */
96
+ generateTypesContent(types) {
97
+ const header = [
98
+ '/**',
99
+ ' * API 类型定义',
100
+ ' * 此文件由 swagger2api 自动生成,请勿手动修改',
101
+ ' */',
102
+ ''
103
+ ].join('\n');
104
+ const typeDefinitions = types
105
+ .map(type => {
106
+ const comment = type.description
107
+ ? `/**\n * ${type.description}\n */\n`
108
+ : '';
109
+ return `${comment}${type.definition}`;
110
+ })
111
+ .join('\n\n');
112
+ return `${header}${typeDefinitions}\n`;
113
+ }
114
+ /**
115
+ * 按标签生成API文件
116
+ * @param groupedApis 按标签分组的API
117
+ * @param types 类型定义数组
118
+ */
119
+ async generateApiFilesByTags(groupedApis, types) {
120
+ for (const [tag, apis] of groupedApis) {
121
+ const folderName = this.getTagFileName(tag);
122
+ const tagFolderPath = path.join(this.config.output, folderName);
123
+ // 确保tag文件夹存在
124
+ (0, utils_1.ensureDirectoryExists)(tagFolderPath);
125
+ const filePath = path.join(tagFolderPath, 'index.ts');
126
+ const content = this.generateApiFileContent(apis, types, tag);
127
+ (0, utils_1.writeFile)(filePath, content);
128
+ }
129
+ }
130
+ /**
131
+ * 生成单个API文件
132
+ * @param apis API接口数组
133
+ * @param types 类型定义数组
134
+ */
135
+ async generateSingleApiFile(apis, types) {
136
+ const filePath = path.join(this.config.output, 'api.ts');
137
+ const content = this.generateApiFileContent(apis, types);
138
+ (0, utils_1.writeFile)(filePath, content);
139
+ }
140
+ /**
141
+ * 生成API文件内容
142
+ * @param apis API接口数组
143
+ * @param types 类型定义数组
144
+ * @param tag 标签名称(可选)
145
+ * @returns API文件内容
146
+ */
147
+ generateApiFileContent(apis, types, tag) {
148
+ const importTemplate = this.config.importTemplate || "import { request } from '@/utils'";
149
+ const header = [
150
+ '/**',
151
+ ` * ${tag ? `${tag} ` : ''}API 接口`,
152
+ ' * 此文件由 swagger2api 自动生成,请勿手动修改',
153
+ ' */',
154
+ '',
155
+ importTemplate + ';'
156
+ ];
157
+ // 收集当前文件实际使用的类型
158
+ const usedTypes = this.collectUsedTypes(apis);
159
+ // 添加类型导入
160
+ if (usedTypes.length > 0) {
161
+ const typeNames = usedTypes.join(', ');
162
+ const typesPath = tag ? '../types' : './types';
163
+ header.push(`import type { ${typeNames} } from '${typesPath}';`);
164
+ }
165
+ header.push('');
166
+ const apiImplementations = apis.map(api => this.generateApiFunction(api)).join('\n\n');
167
+ return `${header.join('\n')}${apiImplementations}\n`;
168
+ }
169
+ /**
170
+ * 生成单个API函数
171
+ * @param api API接口信息
172
+ * @returns API函数代码
173
+ */
174
+ generateApiFunction(api) {
175
+ const parts = [];
176
+ // 生成注释
177
+ if (this.config.options?.addComments !== false) {
178
+ const swaggerParams = api.parameters.map(p => ({
179
+ name: p.name,
180
+ in: p.in,
181
+ required: p.required,
182
+ type: p.type,
183
+ description: p.description
184
+ }));
185
+ const comment = (0, utils_1.generateApiComment)({ summary: api.description, deprecated: false }, swaggerParams);
186
+ parts.push(comment);
187
+ }
188
+ // 生成函数签名
189
+ const swaggerParameters = api.parameters.map(p => ({
190
+ name: p.name,
191
+ in: p.in,
192
+ required: p.required,
193
+ type: p.type,
194
+ schema: p.schema || { type: p.type }
195
+ }));
196
+ // 生成直接参数形式
197
+ const functionParams = this.generateDirectParameters(swaggerParameters);
198
+ const responseType = api.responseType || 'any';
199
+ const functionName = (0, utils_1.toCamelCase)(api.name);
200
+ parts.push(`export const ${functionName} = (${functionParams}) => {`);
201
+ // 生成请求配置
202
+ const requestConfig = this.generateRequestConfig(api);
203
+ parts.push(` return request.${api.method.toLowerCase()}<${responseType}>(${requestConfig});`);
204
+ parts.push('}');
205
+ return parts.join('\n');
206
+ }
207
+ /**
208
+ * 生成直接参数形式
209
+ * @param parameters Swagger参数数组
210
+ * @returns 函数参数字符串
211
+ */
212
+ generateDirectParameters(parameters) {
213
+ const params = [];
214
+ const queryParams = parameters.filter(p => p.in === 'query');
215
+ const pathParams = parameters.filter(p => p.in === 'path');
216
+ const bodyParams = parameters.filter(p => p.in === 'body');
217
+ const formParams = parameters.filter(p => p.in === 'formData');
218
+ // 合并路径参数和查询参数为一个params对象
219
+ const allParams = [...pathParams, ...queryParams];
220
+ if (allParams.length > 0) {
221
+ const paramType = allParams
222
+ .map(p => {
223
+ const optional = p.required ? '' : '?';
224
+ return `${p.name}${optional}: ${p.type}`;
225
+ })
226
+ .join(', ');
227
+ // 检查是否所有参数都是可选的
228
+ const allOptional = allParams.every(p => !p.required);
229
+ const optionalModifier = allOptional ? '?' : '';
230
+ params.push(`params${optionalModifier}: { ${paramType} }`);
231
+ }
232
+ // 请求体参数
233
+ if (bodyParams.length > 0) {
234
+ const bodyParam = bodyParams[0];
235
+ const bodyType = bodyParam.schema ? this.getTypeFromSchema(bodyParam.schema) : bodyParam.type;
236
+ params.push(`data: ${bodyType}`);
237
+ }
238
+ // 表单参数
239
+ if (formParams.length > 0) {
240
+ const formType = formParams
241
+ .map(p => {
242
+ const optional = p.required ? '' : '?';
243
+ return `${p.name}${optional}: ${p.type}`;
244
+ })
245
+ .join(', ');
246
+ params.push(`data: { ${formType} }`);
247
+ }
248
+ // 添加可选的config参数
249
+ params.push('config?: any');
250
+ return params.join(', ');
251
+ }
252
+ /**
253
+ * 从schema获取类型
254
+ * @param schema Swagger schema
255
+ * @returns 类型字符串
256
+ */
257
+ getTypeFromSchema(schema) {
258
+ if (schema.$ref) {
259
+ return schema.$ref.split('/').pop() || 'any';
260
+ }
261
+ return (0, utils_1.swaggerTypeToTsType)(schema);
262
+ }
263
+ /**
264
+ * 收集API数组中实际使用的类型
265
+ * @param apis API接口数组
266
+ * @returns 使用的类型名称数组
267
+ */
268
+ collectUsedTypes(apis) {
269
+ const usedTypes = new Set();
270
+ apis.forEach(api => {
271
+ // 收集响应类型
272
+ if (api.responseType && api.responseType !== 'any') {
273
+ usedTypes.add(api.responseType);
274
+ }
275
+ // 收集参数类型
276
+ api.parameters.forEach(param => {
277
+ if (param.schema) {
278
+ const type = this.getTypeFromSchema(param.schema);
279
+ if (type && type !== 'any' && !this.isPrimitiveType(type)) {
280
+ usedTypes.add(type);
281
+ }
282
+ }
283
+ else if (param.type && !this.isPrimitiveType(param.type)) {
284
+ usedTypes.add(param.type);
285
+ }
286
+ });
287
+ });
288
+ return Array.from(usedTypes).sort();
289
+ }
290
+ /**
291
+ * 判断是否为基础类型
292
+ * @param type 类型名称
293
+ * @returns 是否为基础类型
294
+ */
295
+ isPrimitiveType(type) {
296
+ const primitiveTypes = ['string', 'number', 'boolean', 'object', 'array', 'any', 'void', 'null', 'undefined'];
297
+ return primitiveTypes.includes(type.toLowerCase());
298
+ }
299
+ /**
300
+ * 生成请求配置
301
+ * @param api API接口信息
302
+ * @returns 请求配置代码
303
+ */
304
+ generateRequestConfig(api) {
305
+ const config = [];
306
+ // URL处理
307
+ let url = api.path;
308
+ // 添加prefix前缀
309
+ if (this.config.prefix) {
310
+ url = this.config.prefix + url;
311
+ }
312
+ const pathParams = api.parameters.filter(p => p.in === 'path');
313
+ const queryParams = api.parameters.filter(p => p.in === 'query');
314
+ if (pathParams.length > 0) {
315
+ // 替换路径参数,从params对象中获取
316
+ pathParams.forEach(param => {
317
+ url = url.replace(`{${param.name}}`, `\${params.${param.name}}`);
318
+ });
319
+ config.push(`url: \`${url}\``);
320
+ }
321
+ else {
322
+ config.push(`url: '${url}'`);
323
+ }
324
+ // 查询参数和路径参数都从params对象中获取
325
+ if (queryParams.length > 0) {
326
+ // 直接传递params对象,让axios自动过滤undefined值
327
+ config.push('params');
328
+ }
329
+ // 请求体数据
330
+ const bodyParams = api.parameters.filter(p => p.in === 'body');
331
+ const formParams = api.parameters.filter(p => p.in === 'formData');
332
+ if (bodyParams.length > 0) {
333
+ config.push('data');
334
+ }
335
+ else if (formParams.length > 0) {
336
+ config.push('data');
337
+ }
338
+ // 添加config参数合并
339
+ config.push('...config');
340
+ return `{\n ${config.join(',\n ')}\n }`;
341
+ }
342
+ /**
343
+ * 生成入口文件
344
+ * @param groupedApis 按标签分组的API
345
+ */
346
+ async generateIndexFile(groupedApis) {
347
+ const exports = [];
348
+ // 导出类型
349
+ exports.push("export * from './types';");
350
+ if (this.config.groupByTags) {
351
+ // 按标签导出
352
+ for (const tag of groupedApis.keys()) {
353
+ const folderName = this.getTagFileName(tag);
354
+ exports.push(`export * from './${folderName}';`);
355
+ }
356
+ }
357
+ else {
358
+ // 导出单个API文件
359
+ exports.push("export * from './api';");
360
+ }
361
+ const content = [
362
+ '/**',
363
+ ' * API 入口文件',
364
+ ' * 此文件由 swagger2api 自动生成,请勿手动修改',
365
+ ' */',
366
+ '',
367
+ ...exports,
368
+ ''
369
+ ].join('\n');
370
+ const filePath = path.join(this.config.output, 'index.ts');
371
+ (0, utils_1.writeFile)(filePath, content);
372
+ }
373
+ /**
374
+ * 获取标签对应的文件名
375
+ * @param tag 标签名
376
+ * @returns 文件名
377
+ */
378
+ getTagFileName(tag) {
379
+ const cleanTag = (0, utils_1.sanitizeFilename)(tag);
380
+ switch (this.config.tagGrouping?.fileNaming) {
381
+ case 'camelCase':
382
+ return (0, utils_1.toCamelCase)(cleanTag);
383
+ case 'kebab-case':
384
+ return (0, utils_1.toKebabCase)(cleanTag);
385
+ case 'tag':
386
+ default:
387
+ return cleanTag.toLowerCase();
388
+ }
389
+ }
390
+ /**
391
+ * 在所有文件生成完成后运行lint命令
392
+ */
393
+ async runLintOnAllFiles() {
394
+ if (!this.config.lint)
395
+ return;
396
+ try {
397
+ const { exec } = require('child_process');
398
+ const util = require('util');
399
+ const execPromise = util.promisify(exec);
400
+ console.log(`🎨 Running lint command: ${this.config.lint} ${this.config.output}`);
401
+ const result = await execPromise(`${this.config.lint} ${this.config.output}`);
402
+ if (result.stdout) {
403
+ console.log(result.stdout);
404
+ }
405
+ console.log('✅ Lint completed successfully');
406
+ }
407
+ catch (error) {
408
+ console.warn(`⚠️ Failed to run lint command:`, error.message);
409
+ }
410
+ }
411
+ }
412
+ exports.CodeGenerator = CodeGenerator;
@@ -0,0 +1,61 @@
1
+ import { SwaggerDocument, ApiInfo, TypeInfo, SwaggerConfig } from '../types';
2
+ /**
3
+ * Swagger文档解析器
4
+ */
5
+ export declare class SwaggerParser {
6
+ private document;
7
+ private config;
8
+ constructor(document: SwaggerDocument, config: SwaggerConfig);
9
+ /**
10
+ * 解析所有API接口
11
+ * @returns API接口信息数组
12
+ */
13
+ parseApis(): ApiInfo[];
14
+ /**
15
+ * 解析单个操作
16
+ * @param method HTTP方法
17
+ * @param path 路径
18
+ * @param operation 操作对象
19
+ * @param globalParameters 全局参数
20
+ * @returns API接口信息
21
+ */
22
+ private parseOperation;
23
+ /**
24
+ * 解析所有类型定义
25
+ * @returns 类型信息数组
26
+ */
27
+ parseTypes(): TypeInfo[];
28
+ /**
29
+ * 解析单个类型定义
30
+ * @param name 类型名称
31
+ * @param schema 模式对象
32
+ * @returns 类型信息
33
+ */
34
+ private parseTypeDefinition;
35
+ /**
36
+ * 按标签分组API
37
+ * @param apis API接口数组
38
+ * @returns 按标签分组的API映射
39
+ */
40
+ groupApisByTags(apis: ApiInfo[]): Map<string, ApiInfo[]>;
41
+ /**
42
+ * 获取所有标签
43
+ * @returns 标签数组
44
+ */
45
+ getTags(): string[];
46
+ /**
47
+ * 获取基础URL
48
+ * @returns 基础URL字符串
49
+ */
50
+ getBaseUrl(): string;
51
+ /**
52
+ * 获取API文档信息
53
+ * @returns API文档基本信息
54
+ */
55
+ getApiInfo(): {
56
+ title: string;
57
+ description: string | undefined;
58
+ version: string;
59
+ baseUrl: string;
60
+ };
61
+ }
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SwaggerParser = void 0;
4
+ const utils_1 = require("../utils");
5
+ /**
6
+ * Swagger文档解析器
7
+ */
8
+ class SwaggerParser {
9
+ constructor(document, config) {
10
+ this.document = document;
11
+ this.config = config;
12
+ }
13
+ /**
14
+ * 解析所有API接口
15
+ * @returns API接口信息数组
16
+ */
17
+ parseApis() {
18
+ const apis = [];
19
+ const paths = this.document.paths;
20
+ for (const [path, pathItem] of Object.entries(paths)) {
21
+ const methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'];
22
+ for (const method of methods) {
23
+ const operation = pathItem[method];
24
+ if (!operation)
25
+ continue;
26
+ const apiInfo = this.parseOperation(method, path, operation, pathItem.parameters);
27
+ apis.push(apiInfo);
28
+ }
29
+ }
30
+ return apis;
31
+ }
32
+ /**
33
+ * 解析单个操作
34
+ * @param method HTTP方法
35
+ * @param path 路径
36
+ * @param operation 操作对象
37
+ * @param globalParameters 全局参数
38
+ * @returns API接口信息
39
+ */
40
+ parseOperation(method, path, operation, globalParameters) {
41
+ // 合并全局参数和操作参数
42
+ const allParameters = [
43
+ ...(globalParameters || []),
44
+ ...(operation.parameters || [])
45
+ ];
46
+ // 处理 OpenAPI 3.0 requestBody
47
+ if (operation.requestBody) {
48
+ const requestBody = operation.requestBody;
49
+ if (requestBody.content && requestBody.content['application/json']) {
50
+ const schema = requestBody.content['application/json'].schema;
51
+ if (schema) {
52
+ const bodyParam = {
53
+ name: 'body',
54
+ in: 'body',
55
+ required: requestBody.required || false,
56
+ schema: schema,
57
+ type: 'object'
58
+ };
59
+ allParameters.push(bodyParam);
60
+ }
61
+ }
62
+ }
63
+ // 生成函数名
64
+ const functionName = operation.operationId || (0, utils_1.pathToFunctionName)(method, path);
65
+ // 获取响应类型
66
+ const responseType = (0, utils_1.getResponseType)(operation.responses);
67
+ // 获取请求体类型
68
+ const bodyParam = allParameters.find(p => p.in === 'body');
69
+ const requestBodyType = bodyParam ? (0, utils_1.swaggerTypeToTsType)(bodyParam.schema) : undefined;
70
+ // 解析参数信息
71
+ const parameters = allParameters.map(param => {
72
+ const type = param.schema ? (0, utils_1.swaggerTypeToTsType)(param.schema) : (0, utils_1.swaggerTypeToTsType)({ type: param.type || 'string' });
73
+ return {
74
+ name: param.name,
75
+ type,
76
+ in: param.in,
77
+ required: param.required || false,
78
+ description: param.description,
79
+ schema: param.schema
80
+ };
81
+ });
82
+ return {
83
+ name: functionName,
84
+ method: method.toUpperCase(),
85
+ path,
86
+ description: operation.summary || operation.description,
87
+ tags: operation.tags || [],
88
+ parameters,
89
+ responseType,
90
+ requestBodyType
91
+ };
92
+ }
93
+ /**
94
+ * 解析所有类型定义
95
+ * @returns 类型信息数组
96
+ */
97
+ parseTypes() {
98
+ const types = [];
99
+ // 解析 Swagger 2.0 definitions
100
+ if (this.document.definitions) {
101
+ for (const [name, schema] of Object.entries(this.document.definitions)) {
102
+ const typeInfo = this.parseTypeDefinition(name, schema);
103
+ types.push(typeInfo);
104
+ }
105
+ }
106
+ // 解析 OpenAPI 3.0 components.schemas
107
+ if (this.document.components?.schemas) {
108
+ for (const [name, schema] of Object.entries(this.document.components.schemas)) {
109
+ const typeInfo = this.parseTypeDefinition(name, schema);
110
+ types.push(typeInfo);
111
+ }
112
+ }
113
+ return types;
114
+ }
115
+ /**
116
+ * 解析单个类型定义
117
+ * @param name 类型名称
118
+ * @param schema 模式对象
119
+ * @returns 类型信息
120
+ */
121
+ parseTypeDefinition(name, schema) {
122
+ const typeName = (0, utils_1.toPascalCase)(name);
123
+ let definition;
124
+ if (schema.type === 'object' && schema.properties) {
125
+ // 对象类型
126
+ const properties = Object.entries(schema.properties)
127
+ .map(([key, value]) => {
128
+ const optional = schema.required?.includes(key) ? '' : '?';
129
+ const type = (0, utils_1.swaggerTypeToTsType)(value);
130
+ const comment = value.description ? ` /** ${value.description} */` : '';
131
+ return `${comment}\n ${key}${optional}: ${type};`;
132
+ })
133
+ .join('\n');
134
+ definition = `export interface ${typeName} {\n${properties}\n}`;
135
+ }
136
+ else if (schema.type === 'array') {
137
+ // 数组类型
138
+ const itemType = (0, utils_1.swaggerTypeToTsType)(schema.items);
139
+ definition = `export type ${typeName} = ${itemType}[];`;
140
+ }
141
+ else if (schema.enum) {
142
+ // 枚举类型
143
+ const enumValues = schema.enum
144
+ .map((value) => ` ${JSON.stringify(value)}`)
145
+ .join(' |\n');
146
+ definition = `export type ${typeName} =\n${enumValues};`;
147
+ }
148
+ else {
149
+ // 其他类型
150
+ const type = (0, utils_1.swaggerTypeToTsType)(schema);
151
+ definition = `export type ${typeName} = ${type};`;
152
+ }
153
+ return {
154
+ name: typeName,
155
+ definition,
156
+ description: schema.description
157
+ };
158
+ }
159
+ /**
160
+ * 按标签分组API
161
+ * @param apis API接口数组
162
+ * @returns 按标签分组的API映射
163
+ */
164
+ groupApisByTags(apis) {
165
+ const groupedApis = new Map();
166
+ for (const api of apis) {
167
+ const tags = api.tags.length > 0 ? api.tags : ['default'];
168
+ for (const tag of tags) {
169
+ if (!groupedApis.has(tag)) {
170
+ groupedApis.set(tag, []);
171
+ }
172
+ groupedApis.get(tag).push(api);
173
+ }
174
+ }
175
+ return groupedApis;
176
+ }
177
+ /**
178
+ * 获取所有标签
179
+ * @returns 标签数组
180
+ */
181
+ getTags() {
182
+ const tags = new Set();
183
+ // 从文档标签中获取
184
+ if (this.document.tags) {
185
+ this.document.tags.forEach(tag => tags.add(tag.name));
186
+ }
187
+ // 从路径操作中获取
188
+ for (const pathItem of Object.values(this.document.paths)) {
189
+ const methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'];
190
+ for (const method of methods) {
191
+ const operation = pathItem[method];
192
+ if (operation?.tags) {
193
+ operation.tags.forEach(tag => tags.add(tag));
194
+ }
195
+ }
196
+ }
197
+ return Array.from(tags);
198
+ }
199
+ /**
200
+ * 获取基础URL
201
+ * @returns 基础URL字符串
202
+ */
203
+ getBaseUrl() {
204
+ if (this.document.host) {
205
+ const scheme = this.document.schemes?.[0] || 'https';
206
+ const basePath = this.document.basePath || '';
207
+ return `${scheme}://${this.document.host}${basePath}`;
208
+ }
209
+ return '';
210
+ }
211
+ /**
212
+ * 获取API文档信息
213
+ * @returns API文档基本信息
214
+ */
215
+ getApiInfo() {
216
+ return {
217
+ title: this.document.info.title,
218
+ description: this.document.info.description,
219
+ version: this.document.info.version,
220
+ baseUrl: this.getBaseUrl()
221
+ };
222
+ }
223
+ }
224
+ exports.SwaggerParser = SwaggerParser;