yapi-apifox-to-typescript 4.1.3 → 4.2.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.
@@ -7,10 +7,12 @@ exports.ApifoxToYApiData = void 0;
7
7
 
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
9
 
10
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var _createForOfIteratorHelperLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelperLoose"));
11
11
 
12
12
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
13
 
14
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
15
+
14
16
  var _axios = _interopRequireDefault(require("axios"));
15
17
 
16
18
  var _types = require("./types");
@@ -19,8 +21,7 @@ var _utils = require("./utils");
19
21
 
20
22
  var ApifoxToYApiData = /*#__PURE__*/function () {
21
23
  function ApifoxToYApiData(options) {
22
- this.schemas = void 0;
23
- this.folders = void 0;
24
+ this.openApiDoc = null;
24
25
  this.options = void 0;
25
26
  this.project = {
26
27
  _id: 0,
@@ -35,55 +36,333 @@ var ApifoxToYApiData = /*#__PURE__*/function () {
35
36
  }]
36
37
  };
37
38
  this.schemas = {};
38
- this.folders = [];
39
+ this.interfaceIdCounter = 0;
39
40
  this.options = options;
40
41
  }
42
+
43
+ var _proto = ApifoxToYApiData.prototype;
44
+
45
+ _proto.resolveRef = function resolveRef(ref) {
46
+ if (!ref.startsWith('#/components/schemas/')) {
47
+ return null;
48
+ }
49
+
50
+ var schemaName = ref.replace('#/components/schemas/', '');
51
+ return this.schemas[schemaName] || null;
52
+ };
53
+
54
+ _proto.resolveSchema = function resolveSchema(schema) {
55
+ if (!schema) return undefined;
56
+
57
+ if (schema.$ref) {
58
+ return this.resolveRef(schema.$ref) || schema;
59
+ }
60
+
61
+ return schema;
62
+ };
63
+
64
+ _proto.getSchemaType = function getSchemaType(schema) {
65
+ if (!schema) return 'string';
66
+ var resolved = this.resolveSchema(schema);
67
+ if (!resolved) return 'string';
68
+ return resolved.type || 'string';
69
+ };
70
+
71
+ _proto.convertParametersToReqParams = function convertParametersToReqParams(parameters, type) {
72
+ var _this = this;
73
+
74
+ if (parameters === void 0) {
75
+ parameters = [];
76
+ }
77
+
78
+ if (type === 'path') {
79
+ return parameters.filter(function (p) {
80
+ return p.in === 'path';
81
+ }).map(function (p) {
82
+ return {
83
+ name: p.name,
84
+ desc: p.description || '',
85
+ example: p.example || '',
86
+ required: p.required ? _types.Required.true : _types.Required.false,
87
+ type: _this.getSchemaType(p.schema) === 'string' ? _types.RequestParamType.string : _types.RequestParamType.number
88
+ };
89
+ });
90
+ }
91
+
92
+ return parameters.filter(function (p) {
93
+ return p.in === 'query';
94
+ }).map(function (p) {
95
+ return {
96
+ name: p.name,
97
+ desc: p.description || '',
98
+ example: p.example || '',
99
+ required: p.required ? _types.Required.true : _types.Required.false,
100
+ type: _this.getSchemaType(p.schema) === 'string' ? _types.RequestQueryType.string : _types.RequestQueryType.number
101
+ };
102
+ });
103
+ };
104
+
105
+ _proto.convertRequestBody = function convertRequestBody(requestBody) {
106
+ if (!(requestBody != null && requestBody.content)) {
107
+ return {
108
+ req_body_type: _types.RequestBodyType.none,
109
+ req_body_is_json_schema: false,
110
+ req_body_form: [],
111
+ req_body_other: '',
112
+ contentType: ''
113
+ };
114
+ }
115
+
116
+ var contentTypes = Object.keys(requestBody.content);
117
+ var jsonContentType = contentTypes.find(function (ct) {
118
+ return ct.includes('application/json');
119
+ });
120
+ var formContentType = contentTypes.find(function (ct) {
121
+ return ct.includes('application/x-www-form-urlencoded') || ct.includes('multipart/form-data');
122
+ });
123
+
124
+ if (jsonContentType) {
125
+ var schema = requestBody.content[jsonContentType].schema;
126
+ return {
127
+ req_body_type: _types.RequestBodyType.json,
128
+ req_body_is_json_schema: true,
129
+ req_body_form: [],
130
+ req_body_other: schema ? JSON.stringify(this.normalizeSchema(schema)) : '',
131
+ contentType: jsonContentType
132
+ };
133
+ }
134
+
135
+ if (formContentType) {
136
+ var _schema = requestBody.content[formContentType].schema;
137
+ var resolvedSchema = this.resolveSchema(_schema);
138
+ var formItems = [];
139
+
140
+ if (resolvedSchema != null && resolvedSchema.properties) {
141
+ var requiredFields = resolvedSchema.required || [];
142
+
143
+ for (var _i = 0, _Object$entries = Object.entries(resolvedSchema.properties); _i < _Object$entries.length; _i++) {
144
+ var _Object$entries$_i = _Object$entries[_i],
145
+ name = _Object$entries$_i[0],
146
+ prop = _Object$entries$_i[1];
147
+ var resolvedProp = this.resolveSchema(prop);
148
+ formItems.push({
149
+ name: name,
150
+ type: (resolvedProp == null ? void 0 : resolvedProp.type) === 'file' || (resolvedProp == null ? void 0 : resolvedProp.format) === 'binary' ? _types.RequestFormItemType.file : _types.RequestFormItemType.text,
151
+ desc: (resolvedProp == null ? void 0 : resolvedProp.description) || '',
152
+ example: (resolvedProp == null ? void 0 : resolvedProp.example) || '',
153
+ required: requiredFields.includes(name) ? _types.Required.true : _types.Required.false
154
+ });
155
+ }
156
+ }
157
+
158
+ return {
159
+ req_body_type: _types.RequestBodyType.form,
160
+ req_body_is_json_schema: false,
161
+ req_body_form: formItems,
162
+ req_body_other: '',
163
+ contentType: formContentType
164
+ };
165
+ }
166
+
167
+ return {
168
+ req_body_type: _types.RequestBodyType.raw,
169
+ req_body_is_json_schema: false,
170
+ req_body_form: [],
171
+ req_body_other: '',
172
+ contentType: contentTypes[0] || ''
173
+ };
174
+ };
175
+
176
+ _proto.normalizeSchema = function normalizeSchema(schema) {
177
+ var result = (0, _extends2.default)({}, schema);
178
+
179
+ if (schema.$ref) {
180
+ var resolved = this.resolveRef(schema.$ref);
181
+
182
+ if (resolved) {
183
+ return this.normalizeSchema(resolved);
184
+ }
185
+ }
186
+
187
+ if (schema.properties) {
188
+ result.properties = {};
189
+
190
+ for (var _i2 = 0, _Object$entries2 = Object.entries(schema.properties); _i2 < _Object$entries2.length; _i2++) {
191
+ var _Object$entries2$_i = _Object$entries2[_i2],
192
+ key = _Object$entries2$_i[0],
193
+ _value = _Object$entries2$_i[1];
194
+
195
+ if (_value) {
196
+ result.properties[key] = this.normalizeSchema(_value);
197
+ }
198
+ }
199
+ }
200
+
201
+ if (schema.items) {
202
+ result.items = this.normalizeSchema(schema.items);
203
+ }
204
+
205
+ delete result.$ref;
206
+ return result;
207
+ };
208
+
209
+ _proto.convertResponse = function convertResponse(responses) {
210
+ if (responses === void 0) {
211
+ responses = {};
212
+ }
213
+
214
+ var successResponse = responses['200'] || responses['201'] || responses['204'];
215
+
216
+ if (!(successResponse != null && successResponse.content)) {
217
+ return {
218
+ res_body_type: _types.ResponseBodyType.json,
219
+ res_body_is_json_schema: false,
220
+ res_body: ''
221
+ };
222
+ }
223
+
224
+ var jsonContent = successResponse.content['application/json'];
225
+
226
+ if (jsonContent != null && jsonContent.schema) {
227
+ return {
228
+ res_body_type: _types.ResponseBodyType.json,
229
+ res_body_is_json_schema: true,
230
+ res_body: JSON.stringify(this.normalizeSchema(jsonContent.schema))
231
+ };
232
+ }
233
+
234
+ return {
235
+ res_body_type: _types.ResponseBodyType.json,
236
+ res_body_is_json_schema: false,
237
+ res_body: ''
238
+ };
239
+ };
240
+
241
+ _proto.generateInterfaceId = function generateInterfaceId() {
242
+ this.interfaceIdCounter += 1;
243
+ return this.interfaceIdCounter;
244
+ }
41
245
  /**
42
- * http-api-tree 这个接口拿到所有的folder(category)
43
- * data-schemas 这个接口拿到所用通用的schema
246
+ * 获取接口所属的目录名称
247
+ * Apifox 优先使用 x-apifox-folder 字段,其次才用 tags[0]
44
248
  */
249
+ ;
45
250
 
251
+ _proto.getOperationFolder = function getOperationFolder(operation) {
252
+ // 优先使用 x-apifox-folder
253
+ if (operation['x-apifox-folder']) {
254
+ return operation['x-apifox-folder'];
255
+ } // 其次使用 tags[0]
46
256
 
47
- var _proto = ApifoxToYApiData.prototype;
48
257
 
49
- _proto.getProjectInfo =
50
- /*#__PURE__*/
51
- function () {
258
+ if (operation.tags && operation.tags.length > 0) {
259
+ return operation.tags[0];
260
+ }
261
+
262
+ return 'default';
263
+ };
264
+
265
+ _proto.convertOperationToInterface = function convertOperationToInterface(path, method, operation, categoryName, categoryId) {
266
+ var _operation$tags;
267
+
268
+ var parameters = operation.parameters || [];
269
+ var pathParams = this.convertParametersToReqParams(parameters, 'path');
270
+ var queryParams = this.convertParametersToReqParams(parameters, 'query'); // const headerParams = parameters.filter(p => p.in === 'header')
271
+
272
+ var reqHeaders = [];
273
+ var requestBodyInfo = this.convertRequestBody(operation.requestBody);
274
+
275
+ if (requestBodyInfo.contentType) {
276
+ reqHeaders.push({
277
+ name: 'Content-Type',
278
+ value: requestBodyInfo.contentType,
279
+ desc: '',
280
+ example: '',
281
+ required: _types.Required.true
282
+ });
283
+ }
284
+
285
+ var responseInfo = this.convertResponse(operation.responses); // 获取接口所属目录:优先使用 x-apifox-folder,其次用 tags
286
+
287
+ var folderName = this.getOperationFolder(operation);
288
+ var interfaceTags = (_operation$tags = operation.tags) != null && _operation$tags.length ? operation.tags : folderName !== 'default' ? [folderName] : [];
289
+ return {
290
+ _id: this.generateInterfaceId(),
291
+ _category: {
292
+ _id: categoryId,
293
+ _url: '',
294
+ name: categoryName,
295
+ desc: '',
296
+ add_time: 0,
297
+ up_time: 0
298
+ },
299
+ _project: (0, _extends2.default)({}, this.project),
300
+ _url: '',
301
+ title: operation.summary || path,
302
+ status: operation.deprecated ? 'undone' : 'done',
303
+ markdown: operation.description || '',
304
+ path: path,
305
+ method: method.toUpperCase(),
306
+ project_id: this.options.projectId,
307
+ catid: categoryId,
308
+ tag: interfaceTags,
309
+ req_headers: reqHeaders,
310
+ req_params: pathParams,
311
+ req_query: queryParams,
312
+ req_body_type: requestBodyInfo.req_body_type,
313
+ req_body_is_json_schema: requestBodyInfo.req_body_is_json_schema,
314
+ req_body_form: requestBodyInfo.req_body_form,
315
+ req_body_other: requestBodyInfo.req_body_other,
316
+ res_body_type: responseInfo.res_body_type,
317
+ res_body_is_json_schema: responseInfo.res_body_is_json_schema,
318
+ res_body: responseInfo.res_body,
319
+ add_time: Math.floor(Date.now() / 1000),
320
+ up_time: Math.floor(Date.now() / 1000),
321
+ uid: 0
322
+ };
323
+ };
324
+
325
+ _proto.getProjectInfo = /*#__PURE__*/function () {
52
326
  var _getProjectInfo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
53
- var _this = this;
327
+ var _this$options$addFold, _this$options$oasVers, _this$options$exportF, _this$openApiDoc, _this$openApiDoc$comp, _this$openApiDoc2, _this$openApiDoc2$inf, _this$openApiDoc3, _this$openApiDoc3$inf;
54
328
 
55
- var folders, schemas;
329
+ var baseUrl, response;
56
330
  return _regenerator.default.wrap(function _callee$(_context) {
57
331
  while (1) {
58
332
  switch (_context.prev = _context.next) {
59
333
  case 0:
60
- _context.next = 2;
61
- return _axios.default.get("https://apifox.com/api/v1/shared-docs/" + this.options.token + "/http-api-tree");
62
-
63
- case 2:
64
- folders = _context.sent;
65
- _context.next = 5;
66
- return _axios.default.get("https://apifox.com/api/v1/shared-docs/" + this.options.token + "/data-schemas");
67
-
68
- case 5:
69
- schemas = _context.sent;
70
- // 初始化
71
- schemas.data.data.forEach(function (item) {
72
- _this.schemas[item.id] = item.jsonSchema;
334
+ baseUrl = this.options.serverUrl.replace(/\/$/, '');
335
+ _context.next = 3;
336
+ return _axios.default.post(baseUrl + "/v1/projects/" + this.options.projectId + "/export-openapi?locale=zh-CN", {
337
+ scope: {
338
+ type: 'ALL',
339
+ excludedByTags: []
340
+ },
341
+ options: {
342
+ includeApifoxExtensionProperties: true,
343
+ addFoldersToTags: (_this$options$addFold = this.options.addFoldersToTags) != null ? _this$options$addFold : true
344
+ },
345
+ oasVersion: (_this$options$oasVers = this.options.oasVersion) != null ? _this$options$oasVers : '3.0',
346
+ exportFormat: (_this$options$exportF = this.options.exportFormat) != null ? _this$options$exportF : 'JSON'
347
+ }, {
348
+ headers: {
349
+ 'Authorization': "Bearer " + this.options.token,
350
+ 'X-Apifox-Api-Version': '2024-03-28',
351
+ 'Content-Type': 'application/json'
352
+ }
73
353
  });
74
- this.folders = folders.data.data; // const categoryIds = getFilteredCat(this.options, [])
75
- // 由于这里面所有的cats是递归的,所以涉及到多层级的cats如果判定权限。这里先做一遍过滤,后续就不再做了
76
- // const cats: Category[] = folders.data.data.map(item => ({
77
- // _id: item.folder.id,
78
- // _url: '',
79
- // name: item.name,
80
- // desc: item.key,
81
- // list: [],
82
- // add_time: 0,
83
- // up_time: 0,
84
- // }))
85
-
86
- this.project._id = schemas.data.data[0].projectId;
354
+
355
+ case 3:
356
+ response = _context.sent;
357
+ this.openApiDoc = response.data;
358
+
359
+ if ((_this$openApiDoc = this.openApiDoc) != null && (_this$openApiDoc$comp = _this$openApiDoc.components) != null && _this$openApiDoc$comp.schemas) {
360
+ this.schemas = this.openApiDoc.components.schemas;
361
+ }
362
+
363
+ this.project._id = this.options.projectId;
364
+ this.project.name = ((_this$openApiDoc2 = this.openApiDoc) == null ? void 0 : (_this$openApiDoc2$inf = _this$openApiDoc2.info) == null ? void 0 : _this$openApiDoc2$inf.title) || 'ApifoxProject';
365
+ this.project.desc = ((_this$openApiDoc3 = this.openApiDoc) == null ? void 0 : (_this$openApiDoc3$inf = _this$openApiDoc3.info) == null ? void 0 : _this$openApiDoc3$inf.description) || '';
87
366
  return _context.abrupt("return", (0, _extends2.default)({}, this.project, {
88
367
  cats: [],
89
368
  getMockUrl: function getMockUrl() {
@@ -110,253 +389,176 @@ var ApifoxToYApiData = /*#__PURE__*/function () {
110
389
  }
111
390
 
112
391
  return getProjectInfo;
113
- }()
114
- /**
115
- * 根据筛选后的权限目录,对当前folder进行筛选
116
- * 如果传入的cats为空,表明获取所有
117
- */
118
- ;
392
+ }();
119
393
 
120
- _proto.getValidCat = function getValidCat(cats, allFolders) {
121
- var _this2 = this;
394
+ _proto.getTagId = function getTagId(tagName) {
395
+ var hash = 0;
122
396
 
123
- if (allFolders === void 0) {
124
- allFolders = this.folders;
125
- }
397
+ for (var i = 0; i < tagName.length; i++) {
398
+ var _char = tagName.charCodeAt(i);
126
399
 
127
- var folders = [];
128
- allFolders.forEach(function (item) {
129
- if (item.type !== 'apiDetailFolder') return;
130
- if (cats.length && !cats.includes(item.folder.id)) return;
131
- folders.push(item.folder.id);
400
+ hash = (hash << 5) - hash + _char;
401
+ hash = hash & hash;
402
+ }
132
403
 
133
- if (item.type === 'apiDetailFolder' && item.children.length) {
134
- folders.push.apply(folders, _this2.getValidCat(cats, item.children));
135
- }
136
- });
137
- return folders;
404
+ return Math.abs(hash);
138
405
  }
139
406
  /**
140
- * 根据传入的目录配置,返回有效的目录列表
407
+ * 从 OpenAPI tags 中获取目录对应的 tag
408
+ * 如果 x-apifox-folder 在 tags 中存在,则返回对应的 tag;否则返回 x-apifox-folder 本身
141
409
  */
142
410
  ;
143
411
 
144
- _proto.getCats = function getCats(cats) {
145
- var categoryIds = (0, _utils.getFilteredCat)(cats, [], true); // 对cat进行有效性过滤
412
+ _proto.getMatchingTag = function getMatchingTag(xApifoxFolder) {
413
+ var _this$openApiDoc4;
146
414
 
147
- return this.getValidCat(categoryIds);
148
- }
149
- /**
150
- * 通过目录的ID查找目录
151
- */
152
- ;
415
+ if (!((_this$openApiDoc4 = this.openApiDoc) != null && _this$openApiDoc4.tags)) return null; // 先精确匹配
153
416
 
154
- _proto.findCats = function findCats(id, folders) {
155
- var _this3 = this;
417
+ var exactMatch = this.openApiDoc.tags.find(function (tag) {
418
+ return tag.name === xApifoxFolder;
419
+ });
420
+ if (exactMatch) return exactMatch.name; // 如果 addFoldersToTags=true,可能目录名被添加到 tag 描述或其他地方
421
+ // 或者 tag.name 本身就包含了目录路径
156
422
 
157
- if (folders === void 0) {
158
- folders = this.folders;
159
- }
423
+ return null;
424
+ };
425
+
426
+ _proto.getCats = function getCats(cats) {
427
+ var _this2 = this;
160
428
 
161
- var folder = null;
162
- folders.forEach(function (item) {
163
- if (folder) return;
429
+ var categoryIds = (0, _utils.getFilteredCat)(cats, [], true);
164
430
 
165
- if (item.type === 'apiDetailFolder' && item.folder.id === id) {
166
- folder = item;
167
- return;
168
- }
431
+ if (categoryIds.length === 0 || categoryIds.includes(0)) {
432
+ var _this$openApiDoc5;
169
433
 
170
- if (item.type === 'apiDetailFolder' && item.children) {
171
- folder = _this3.findCats(id, item.children);
434
+ if (!((_this$openApiDoc5 = this.openApiDoc) != null && _this$openApiDoc5.tags)) {
435
+ console.log("\uD83D\uDCC1 getCats: \u8FD4\u56DE\u7A7A\u6570\u7EC4 (openApiDoc.tags \u4E0D\u5B58\u5728)");
436
+ return [];
172
437
  }
173
- });
174
- return folder;
175
- }
176
- /**
177
- * 由于yapi中基本没有处理ref的方案
178
- * 都是直接由具体的参数值管理,所以这里需要对所有的ref进行转换
179
- *
180
- * 在apifox中,对于cat来说,cat的children有可能是folder,对于folder,我们要过滤掉
181
- */
182
- ;
183
438
 
184
- _proto.getInterfaceList =
185
- /*#__PURE__*/
186
- function () {
187
- var _getInterfaceList = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(syntheticalConfig) {
188
- var _this4 = this;
439
+ var tagIds = this.openApiDoc.tags.map(function (tag) {
440
+ return _this2.getTagId(tag.name);
441
+ });
442
+ console.log("\uD83D\uDCC1 getCats (id=0 \u83B7\u53D6\u5168\u90E8): \u8FD4\u56DE " + tagIds.length + " \u4E2A\u5206\u7C7B");
443
+ console.log(" Tags: " + this.openApiDoc.tags.map(function (t) {
444
+ return t.name;
445
+ }).join(', '));
446
+ return tagIds;
447
+ }
448
+
449
+ console.log("\uD83D\uDCC1 getCats: \u8FD4\u56DE " + categoryIds.length + " \u4E2A\u5206\u7C7B: " + categoryIds.join(', '));
450
+ return categoryIds;
451
+ };
189
452
 
190
- var cat, transformRefToSchema;
191
- return _regenerator.default.wrap(function _callee3$(_context3) {
453
+ _proto.getInterfaceList = /*#__PURE__*/function () {
454
+ var _getInterfaceList = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(syntheticalConfig) {
455
+ var _this$openApiDoc6,
456
+ _this$openApiDoc7,
457
+ _this3 = this;
458
+
459
+ var catId, interfaces, seenKeys, tagName, tag, methods, _i3, _Object$entries3, _Object$entries3$_i, path, pathItem, _iterator, _step, method, operation, xApifoxFolder, tagId, key, categoryTag, interfaceInfo;
460
+
461
+ return _regenerator.default.wrap(function _callee2$(_context2) {
192
462
  while (1) {
193
- switch (_context3.prev = _context3.next) {
463
+ switch (_context2.prev = _context2.next) {
194
464
  case 0:
195
- // syntheticalConfig.id 就是catId
196
- cat = this.findCats(syntheticalConfig.id);
465
+ if ((_this$openApiDoc6 = this.openApiDoc) != null && _this$openApiDoc6.paths) {
466
+ _context2.next = 2;
467
+ break;
468
+ }
469
+
470
+ return _context2.abrupt("return", []);
471
+
472
+ case 2:
473
+ catId = syntheticalConfig.id;
474
+ interfaces = []; // 用于去重:基于 path + method
475
+
476
+ seenKeys = new Set(); // 调试:获取 tag 名称
477
+
478
+ tagName = 'unknown';
197
479
 
198
- if (cat) {
199
- _context3.next = 3;
480
+ if ((_this$openApiDoc7 = this.openApiDoc) != null && _this$openApiDoc7.tags) {
481
+ tag = this.openApiDoc.tags.find(function (t) {
482
+ return _this3.getTagId(t.name) === catId;
483
+ });
484
+ tagName = (tag == null ? void 0 : tag.name) || "unknown(" + catId + ")";
485
+ }
486
+
487
+ console.log("\n\uD83D\uDCC2 \u5206\u7C7B [" + tagName + "] (id: " + catId + ") \u5F00\u59CB\u83B7\u53D6\u63A5\u53E3...");
488
+ methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'];
489
+ _i3 = 0, _Object$entries3 = Object.entries(this.openApiDoc.paths);
490
+
491
+ case 10:
492
+ if (!(_i3 < _Object$entries3.length)) {
493
+ _context2.next = 34;
200
494
  break;
201
495
  }
202
496
 
203
- return _context3.abrupt("return", []);
497
+ _Object$entries3$_i = _Object$entries3[_i3], path = _Object$entries3$_i[0], pathItem = _Object$entries3$_i[1];
498
+ _iterator = (0, _createForOfIteratorHelperLoose2.default)(methods);
204
499
 
205
- case 3:
206
- transformRefToSchema = function transformRefToSchema(refString) {
207
- var refId = refString.split('/').pop();
208
- return _this4.schemas[refId];
209
- };
210
-
211
- return _context3.abrupt("return", Promise.all(cat.children.filter(function (child) {
212
- return child.type === 'apiDetail';
213
- }).map( /*#__PURE__*/function () {
214
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(child) {
215
- var _resultData$responses, _resultData$responses2, _resultData$responses3, _resultData$responses4, _resultData$responses5, _resultData$responses6, _resultData$responses7, _resultData$requestBo, _resultData$requestBo2, _resultData$parameter, _resultData$parameter2, _resultData$requestBo3;
216
-
217
- var result, resultData, resbodyIndex, respref, dataProperties, item, _dataProperties$item$, dataPropRef, reqref;
218
-
219
- return _regenerator.default.wrap(function _callee2$(_context2) {
220
- while (1) {
221
- switch (_context2.prev = _context2.next) {
222
- case 0:
223
- _context2.next = 2;
224
- return _axios.default.get("https://apifox.com/api/v1/shared-docs/" + _this4.options.token + "/http-apis/" + child.api.id);
225
-
226
- case 2:
227
- result = _context2.sent;
228
- resultData = result.data.data; // 根据result对应的param查询制定的schema
229
-
230
- // 根据result对应的param查询制定的schema
231
- resbodyIndex = resultData.responses.findIndex(function (item) {
232
- return item.code === 200;
233
- }); // 处理response重可能存在ref
234
-
235
- // 处理response重可能存在ref
236
- respref = (_resultData$responses = resultData.responses[resbodyIndex].jsonSchema) == null ? void 0 : (_resultData$responses2 = _resultData$responses.properties) == null ? void 0 : (_resultData$responses3 = _resultData$responses2.data) == null ? void 0 : (_resultData$responses4 = _resultData$responses3.items) == null ? void 0 : _resultData$responses4.$ref;
237
-
238
- if (respref) {
239
- // @ts-ignore
240
- resultData.responses[resbodyIndex].jsonSchema.properties.data.items = transformRefToSchema(respref);
241
- } // 处理data中可能存在ref的问题
242
- // 这里只考虑了一层,如果存在多层,需要递归处理
243
-
244
-
245
- // 处理data中可能存在ref的问题
246
- // 这里只考虑了一层,如果存在多层,需要递归处理
247
- dataProperties = (_resultData$responses5 = resultData.responses[resbodyIndex].jsonSchema) == null ? void 0 : (_resultData$responses6 = _resultData$responses5.properties) == null ? void 0 : (_resultData$responses7 = _resultData$responses6.data) == null ? void 0 : _resultData$responses7.properties;
248
-
249
- if (dataProperties) {
250
- for (item in dataProperties) {
251
- // @ts-ignore
252
- dataPropRef = (_dataProperties$item$ = dataProperties[item].items) == null ? void 0 : _dataProperties$item$['$ref']; // @ts-ignore
253
-
254
- // @ts-ignore
255
- if (dataProperties[item].type === 'array' && dataPropRef) {
256
- // @ts-ignore
257
- resultData.responses[resbodyIndex].jsonSchema.properties.data.properties[item].items = transformRefToSchema(dataPropRef);
258
- }
259
- }
260
- } // 处理request中可能存在的ref
261
-
262
-
263
- // 处理request中可能存在的ref
264
- if ((_resultData$requestBo = resultData.requestBody.jsonSchema) != null && _resultData$requestBo['x-apifox-refs'] && (_resultData$requestBo2 = resultData.requestBody.jsonSchema) != null && _resultData$requestBo2['x-apifox-orders']) {
265
- // @ts-ignore
266
- reqref = resultData.requestBody.jsonSchema['x-apifox-refs'][resultData.requestBody.jsonSchema['x-apifox-orders'][0]];
267
- resultData.requestBody.jsonSchema.properties = transformRefToSchema(reqref['$ref']).properties; // @ts-ignore
268
-
269
- // @ts-ignore
270
- resultData.requestBody.jsonSchema['required'] = reqref.required;
271
- delete resultData.requestBody.jsonSchema['x-apifox-refs'];
272
- delete resultData.requestBody.jsonSchema['x-apifox-orders'];
273
- }
274
-
275
- return _context2.abrupt("return", {
276
- _id: resultData.id,
277
- _category: {
278
- _id: syntheticalConfig.id,
279
- _url: '',
280
- name: cat.name,
281
- desc: '',
282
- add_time: 0,
283
- up_time: 0,
284
- list: []
285
- },
286
- _project: (0, _extends2.default)({}, _this4.project),
287
- _url: '',
288
- title: resultData.name,
289
- status: 'undone',
290
- markdown: resultData.operationId,
291
- path: resultData.path,
292
- method: resultData.method.toUpperCase(),
293
- project_id: resultData.projectId,
294
- catid: syntheticalConfig.id,
295
- tag: resultData.tags,
296
- req_headers: resultData.requestBody.type ? [{
297
- name: 'Content-Type',
298
- value: resultData.requestBody.type,
299
- desc: '',
300
- example: '',
301
- required: _types.Required.true
302
- }] : [],
303
- req_params: ((_resultData$parameter = resultData.parameters.path) == null ? void 0 : _resultData$parameter.map(function (item) {
304
- return {
305
- name: item.name,
306
- desc: item.description,
307
- example: '',
308
- required: item.required ? _types.Required.true : _types.Required.false,
309
- type: item.type === 'string' ? _types.RequestParamType.string : _types.RequestParamType.number
310
- };
311
- })) || [],
312
- req_query: ((_resultData$parameter2 = resultData.parameters.query) == null ? void 0 : _resultData$parameter2.map(function (item) {
313
- return {
314
- name: item.name,
315
- desc: item.description,
316
- example: '',
317
- required: item.required ? _types.Required.true : _types.Required.false,
318
- type: item.type === 'string' ? _types.RequestQueryType.string : _types.RequestQueryType.number
319
- };
320
- })) || [],
321
- req_body_type: resultData.requestBody.type === 'multipart/form-data' ? _types.RequestBodyType.form : resultData.requestBody.jsonSchema ? _types.RequestBodyType.json : _types.RequestBodyType.raw,
322
- req_body_is_json_schema: !!resultData.requestBody.jsonSchema,
323
- req_body_form: ((_resultData$requestBo3 = resultData.requestBody.parameters) == null ? void 0 : _resultData$requestBo3.map(function (item) {
324
- return {
325
- name: item.name,
326
- desc: item.description,
327
- example: item.example,
328
- required: item.required ? _types.Required.true : _types.Required.false,
329
- type: item.type === 'string' ? _types.RequestFormItemType.text : _types.RequestFormItemType.file
330
- };
331
- })) || [],
332
- req_body_other: resultData.requestBody.jsonSchema ? JSON.stringify(resultData.requestBody.jsonSchema) : '',
333
- res_body_type: _types.ResponseBodyType.json,
334
- res_body_is_json_schema: true,
335
- res_body: JSON.stringify(resultData.responses[resbodyIndex].jsonSchema),
336
- add_time: Math.floor(new Date(resultData.createdAt).getTime() / 1000),
337
- up_time: Math.floor(new Date(resultData.updatedAt).getTime() / 1000),
338
- uid: 0
339
- });
340
-
341
- case 11:
342
- case "end":
343
- return _context2.stop();
344
- }
345
- }
346
- }, _callee2);
347
- }));
348
-
349
- return function (_x2) {
350
- return _ref.apply(this, arguments);
351
- };
352
- }())));
353
-
354
- case 5:
500
+ case 13:
501
+ if ((_step = _iterator()).done) {
502
+ _context2.next = 31;
503
+ break;
504
+ }
505
+
506
+ method = _step.value;
507
+ operation = pathItem[method];
508
+
509
+ if (operation) {
510
+ _context2.next = 18;
511
+ break;
512
+ }
513
+
514
+ return _context2.abrupt("continue", 29);
515
+
516
+ case 18:
517
+ // 获取接口的目录信息:优先使用 x-apifox-folder
518
+ xApifoxFolder = this.getOperationFolder(operation);
519
+ tagId = this.getTagId(xApifoxFolder);
520
+
521
+ if (!(tagId === catId)) {
522
+ _context2.next = 29;
523
+ break;
524
+ }
525
+
526
+ // 去重:基于 path + method
527
+ key = method.toUpperCase() + ":" + path;
528
+
529
+ if (!seenKeys.has(key)) {
530
+ _context2.next = 25;
531
+ break;
532
+ }
533
+
534
+ console.log(" \u26A0\uFE0F \u8DF3\u8FC7\u91CD\u590D\u63A5\u53E3: " + key);
535
+ return _context2.abrupt("continue", 29);
536
+
537
+ case 25:
538
+ seenKeys.add(key); // 根据实际的目录名称来确定分类
539
+
540
+ categoryTag = xApifoxFolder;
541
+ interfaceInfo = this.convertOperationToInterface(path, method, operation, categoryTag, catId);
542
+ interfaces.push(interfaceInfo);
543
+
544
+ case 29:
545
+ _context2.next = 13;
546
+ break;
547
+
548
+ case 31:
549
+ _i3++;
550
+ _context2.next = 10;
551
+ break;
552
+
553
+ case 34:
554
+ return _context2.abrupt("return", interfaces);
555
+
556
+ case 35:
355
557
  case "end":
356
- return _context3.stop();
558
+ return _context2.stop();
357
559
  }
358
560
  }
359
- }, _callee3, this);
561
+ }, _callee2, this);
360
562
  }));
361
563
 
362
564
  function getInterfaceList(_x) {