openapi-ts-request 1.4.0 → 1.5.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.
@@ -1,12 +1,13 @@
1
1
  import type { GenerateServiceProps } from '../index';
2
2
  import { OpenAPIObject } from '../type';
3
- import { ControllerType, ISchemaItem, TagAPIDataType } from './type';
3
+ import { ControllerType, ISchemaItem, ITypeItem, TagAPIDataType } from './type';
4
4
  export default class ServiceGenerator {
5
5
  protected apiData: TagAPIDataType;
6
6
  protected classNameList: ControllerType[];
7
7
  protected config: GenerateServiceProps;
8
8
  protected openAPIData: OpenAPIObject;
9
9
  protected schemaList: ISchemaItem[];
10
+ protected interfaceTPConfigs: ITypeItem[];
10
11
  constructor(config: GenerateServiceProps, openAPIData: OpenAPIObject);
11
12
  genFile(): void;
12
13
  private getInterfaceTPConfigs;
@@ -22,6 +22,7 @@ class ServiceGenerator {
22
22
  this.apiData = {};
23
23
  this.classNameList = [];
24
24
  this.schemaList = [];
25
+ this.interfaceTPConfigs = [];
25
26
  this.config = Object.assign({ templatesFolder: (0, path_1.join)(__dirname, '../../', 'templates') }, config);
26
27
  this.generateInfoLog();
27
28
  const includeTags = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.includeTags) || [];
@@ -148,37 +149,6 @@ class ServiceGenerator {
148
149
  const isGenJavaScript = this.config.isGenJavaScript;
149
150
  const reactQueryMode = this.config.reactQueryMode;
150
151
  const reactQueryFileName = (0, config_2.displayReactQueryFileName)(reactQueryMode);
151
- // 处理重复的 typeName
152
- const interfaceTPConfigs = this.getInterfaceTPConfigs();
153
- (0, util_2.handleDuplicateTypeNames)(interfaceTPConfigs);
154
- // 生成 ts 类型声明
155
- if (!isGenJavaScript) {
156
- this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
157
- nullable: this.config.nullable,
158
- list: interfaceTPConfigs,
159
- });
160
- }
161
- // 生成枚举翻译
162
- const enums = (0, lodash_1.filter)(interfaceTPConfigs, (item) => item.isEnum);
163
- if (!isGenJavaScript && !isOnlyGenTypeScriptType && !(0, lodash_1.isEmpty)(enums)) {
164
- this.genFileFromTemplate(`${config_2.displayEnumLabelFileName}.ts`, config_2.TypescriptFileType.displayEnumLabel, {
165
- list: enums,
166
- namespace: this.config.namespace,
167
- interfaceFileName: config_2.interfaceFileName,
168
- });
169
- }
170
- const displayTypeLabels = (0, lodash_1.filter)(interfaceTPConfigs, (item) => !item.isEnum);
171
- // 生成 type 翻译
172
- if (!isGenJavaScript &&
173
- !isOnlyGenTypeScriptType &&
174
- this.config.isDisplayTypeLabel &&
175
- !(0, lodash_1.isEmpty)(displayTypeLabels)) {
176
- this.genFileFromTemplate(`${config_2.displayTypeLabelFileName}.ts`, config_2.TypescriptFileType.displayTypeLabel, {
177
- list: displayTypeLabels,
178
- namespace: this.config.namespace,
179
- interfaceFileName: config_2.interfaceFileName,
180
- });
181
- }
182
152
  if (!isOnlyGenTypeScriptType) {
183
153
  const prettierError = [];
184
154
  // 生成 service controller 文件
@@ -209,6 +179,37 @@ class ServiceGenerator {
209
179
  (0, log_1.default)('🚥 格式化失败,请检查 service controller 文件内可能存在的语法错误');
210
180
  }
211
181
  }
182
+ // 处理重复的 typeName
183
+ this.interfaceTPConfigs = this.getInterfaceTPConfigs();
184
+ (0, util_2.handleDuplicateTypeNames)(this.interfaceTPConfigs);
185
+ // 生成 ts 类型声明
186
+ if (!isGenJavaScript) {
187
+ this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
188
+ nullable: this.config.nullable,
189
+ list: this.interfaceTPConfigs,
190
+ });
191
+ }
192
+ // 生成枚举翻译
193
+ const enums = (0, lodash_1.filter)(this.interfaceTPConfigs, (item) => item.isEnum);
194
+ if (!isGenJavaScript && !isOnlyGenTypeScriptType && !(0, lodash_1.isEmpty)(enums)) {
195
+ this.genFileFromTemplate(`${config_2.displayEnumLabelFileName}.ts`, config_2.TypescriptFileType.displayEnumLabel, {
196
+ list: enums,
197
+ namespace: this.config.namespace,
198
+ interfaceFileName: config_2.interfaceFileName,
199
+ });
200
+ }
201
+ const displayTypeLabels = (0, lodash_1.filter)(this.interfaceTPConfigs, (item) => !item.isEnum);
202
+ // 生成 type 翻译
203
+ if (!isGenJavaScript &&
204
+ !isOnlyGenTypeScriptType &&
205
+ this.config.isDisplayTypeLabel &&
206
+ !(0, lodash_1.isEmpty)(displayTypeLabels)) {
207
+ this.genFileFromTemplate(`${config_2.displayTypeLabelFileName}.ts`, config_2.TypescriptFileType.displayTypeLabel, {
208
+ list: displayTypeLabels,
209
+ namespace: this.config.namespace,
210
+ interfaceFileName: config_2.interfaceFileName,
211
+ });
212
+ }
212
213
  if (!isOnlyGenTypeScriptType &&
213
214
  this.config.isGenJsonSchemas &&
214
215
  !(0, lodash_1.isEmpty)(this.schemaList)) {
@@ -244,10 +245,11 @@ class ServiceGenerator {
244
245
  (0, log_1.default)('✅ 成功生成 api 文件目录-> ', this.config.serversPath);
245
246
  }
246
247
  getInterfaceTPConfigs() {
247
- var _a, _b;
248
+ var _a, _b, _c;
248
249
  const schemas = (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas;
249
- const lastTypes = [];
250
+ const lastTypes = this.interfaceTPConfigs;
250
251
  const includeTags = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.includeTags) || [];
252
+ const includePaths = ((_c = this.config) === null || _c === void 0 ? void 0 : _c.includePaths) || [];
251
253
  // 强行替换掉请求参数params的类型,生成方法对应的 xxxxParams 类型
252
254
  (0, lodash_1.keys)(this.openAPIData.paths).forEach((pathKey) => {
253
255
  const pathItem = this.openAPIData.paths[pathKey];
@@ -259,11 +261,14 @@ class ServiceGenerator {
259
261
  return;
260
262
  }
261
263
  const tags = hookCustomFileNames(operationObject, pathKey, method);
262
- if ((0, lodash_1.isEmpty)(includeTags) || (!(0, lodash_1.isEmpty)(includeTags) && (0, lodash_1.isEmpty)(tags))) {
264
+ if ((0, lodash_1.isEmpty)(includeTags) ||
265
+ (!(0, lodash_1.isEmpty)(includeTags) && (0, lodash_1.isEmpty)(tags)) ||
266
+ (0, lodash_1.isEmpty)(includePaths)) {
263
267
  return;
264
268
  }
265
269
  const flag = this.validateRegexp((0, lodash_1.filter)((0, lodash_1.map)(tags, (tag) => (tag === null || tag === void 0 ? void 0 : tag.toLowerCase) ? tag.toLowerCase() : undefined), (tag) => !!tag), includeTags);
266
- if (!flag) {
270
+ const pathFlag = this.validateRegexp(pathKey, includePaths);
271
+ if (!flag || !pathFlag) {
267
272
  return;
268
273
  }
269
274
  // 筛选出 pathItem 包含的 $ref 对应的schema
@@ -386,6 +391,26 @@ class ServiceGenerator {
386
391
  else if (functionName) {
387
392
  tmpFunctionRD[functionName] = 1;
388
393
  }
394
+ if (body === null || body === void 0 ? void 0 : body.isAnonymous) {
395
+ const bodyName = (0, lodash_1.upperFirst)(`${functionName}Body`);
396
+ this.interfaceTPConfigs.push({
397
+ typeName: bodyName,
398
+ type: body === null || body === void 0 ? void 0 : body.type,
399
+ isEnum: false,
400
+ props: [],
401
+ });
402
+ body.type = `${this.config.namespace}.${bodyName}`;
403
+ }
404
+ if (response === null || response === void 0 ? void 0 : response.isAnonymous) {
405
+ const responseName = (0, lodash_1.upperFirst)(`${functionName}Response`);
406
+ this.interfaceTPConfigs.push({
407
+ typeName: responseName,
408
+ type: response === null || response === void 0 ? void 0 : response.type,
409
+ isEnum: false,
410
+ props: [],
411
+ });
412
+ response.type = `${this.config.namespace}.${responseName}`;
413
+ }
389
414
  let formattedPath = newApi.path.replace(/:([^/]*)|{([^}]*)}/gi, (_, str, str2) => `$\{${str || str2}}`);
390
415
  // 为 path 中的 params 添加 alias
391
416
  const escapedPathParams = (0, lodash_1.map)(params.path, (item, index) => (Object.assign(Object.assign({}, item), { alias: `param${index}` })));
@@ -566,31 +591,20 @@ class ServiceGenerator {
566
591
  }
567
592
  // 如果 requestBody 有 required 属性,则正常展示;如果没有,默认非必填
568
593
  const required = typeof (requestBody === null || requestBody === void 0 ? void 0 : requestBody.required) === 'boolean' ? requestBody.required : false;
569
- if (schema.type === 'object' && schema.properties) {
570
- const propertiesList = (0, lodash_1.keys)(schema.properties)
571
- .map((propertyKey) => {
572
- var _a, _b;
573
- const propertyObj = schema.properties[propertyKey];
574
- if (propertyObj &&
575
- ![config_1.SchemaObjectFormat.binary, config_1.SchemaObjectFormat.base64].includes(propertyObj.format) &&
576
- !(0, util_2.isBinaryArraySchemaObject)(propertyObj)) {
577
- // 测试了很多用例,很少有用例走到这里
578
- return {
579
- key: propertyKey,
580
- schema: Object.assign(Object.assign({}, propertyObj), { type: this.getType(propertyObj, this.config.namespace), required: (_b = (_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(propertyKey)) !== null && _b !== void 0 ? _b : false }),
581
- };
582
- }
583
- return null;
584
- })
585
- .filter((p) => p);
586
- return Object.assign(Object.assign({ mediaType }, schema), { required,
587
- propertiesList });
588
- }
589
- return {
594
+ const bodySchema = {
590
595
  mediaType,
591
596
  required,
592
597
  type: this.getType(schema, this.config.namespace),
598
+ isAnonymous: false,
593
599
  };
600
+ // 具名 body 场景
601
+ if ((0, util_2.isReferenceObject)(schema)) {
602
+ bodySchema.type = `${this.config.namespace}.${bodySchema.type}`;
603
+ }
604
+ else {
605
+ bodySchema.isAnonymous = true;
606
+ }
607
+ return bodySchema;
594
608
  }
595
609
  getFileTP(requestBody) {
596
610
  var _a;
@@ -633,6 +647,7 @@ class ServiceGenerator {
633
647
  const defaultResponse = {
634
648
  mediaType: '*/*',
635
649
  type: 'unknown',
650
+ isAnonymous: false,
636
651
  };
637
652
  if (!response) {
638
653
  return defaultResponse;
@@ -647,6 +662,11 @@ class ServiceGenerator {
647
662
  }
648
663
  let schema = (resContent[mediaType].schema ||
649
664
  config_2.DEFAULT_SCHEMA);
665
+ const responseSchema = {
666
+ mediaType,
667
+ type: 'unknown',
668
+ isAnonymous: false,
669
+ };
650
670
  if ((0, util_2.isReferenceObject)(schema)) {
651
671
  const refName = (0, util_2.getLastRefName)(schema.$ref);
652
672
  const childrenSchema = components.schemas[refName];
@@ -657,6 +677,8 @@ class ServiceGenerator {
657
677
  resContent[mediaType].schema ||
658
678
  config_2.DEFAULT_SCHEMA);
659
679
  }
680
+ responseSchema.type = `${this.config.namespace}.${this.getType(schema, this.config.namespace)}`;
681
+ return responseSchema;
660
682
  }
661
683
  if ((0, util_2.isSchemaObject)(schema)) {
662
684
  (0, lodash_1.keys)(schema.properties).map((fieldName) => {
@@ -664,11 +686,10 @@ class ServiceGenerator {
664
686
  schema.properties[fieldName]['required'] =
665
687
  (_b = (_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(fieldName)) !== null && _b !== void 0 ? _b : false;
666
688
  });
689
+ responseSchema.isAnonymous = true;
667
690
  }
668
- return {
669
- mediaType,
670
- type: this.getType(schema, this.config.namespace),
671
- };
691
+ responseSchema.type = this.getType(schema, this.config.namespace);
692
+ return responseSchema;
672
693
  }
673
694
  getParamsTP(parameters = [], path = null) {
674
695
  const templateParams = {};
@@ -98,7 +98,8 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
98
98
  return schemaObject;
99
99
  }
100
100
  if (isReferenceObject(schemaObject)) {
101
- return [namespace, getRefName(schemaObject)].filter((s) => s).join('.');
101
+ return getRefName(schemaObject);
102
+ // return [namespace, getRefName(schemaObject)].filter((s) => s).join('.');
102
103
  }
103
104
  let type = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.type;
104
105
  const dateEnum = ['Date', 'date', 'dateTime', 'date-time', 'datetime'];
@@ -200,8 +201,7 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
200
201
  * 错误的继续保留字符串。
201
202
  * */
202
203
  return `
203
- ${property.description ? `/** ${property.description} */` : ''}
204
- '${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace)}; `;
204
+ ${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace)}; `;
205
205
  })
206
206
  .join('')}}`;
207
207
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-ts-request",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "Swagger2/OpenAPI3/Apifox to TypeScript/JavaScript, request client(support any client), request mock service, enum and enum translation, react-query/vue-query, type field label, JSON Schemas",
5
5
  "engines": {
6
6
  "node": ">=18.0.0",
@@ -24,7 +24,7 @@
24
24
  "prettier.config.cjs"
25
25
  ],
26
26
  "dependencies": {
27
- "@prettier/sync": "^0.5.2",
27
+ "@prettier/sync": "^0.6.1",
28
28
  "@trivago/prettier-plugin-sort-imports": "^5.2.1",
29
29
  "axios": "^1.7.2",
30
30
  "bing-translate-api": "^4.0.2",
@@ -58,7 +58,7 @@
58
58
  "@types/lodash": "^4.17.5",
59
59
  "@types/memoizee": "^0.4.11",
60
60
  "@types/mockjs": "^1.0.10",
61
- "@types/node": "^20.14.6",
61
+ "@types/node": "^22.15.17",
62
62
  "@types/nunjucks": "^3.2.6",
63
63
  "@types/reserved-words": "^0.1.4",
64
64
  "@types/swagger2openapi": "^7.0.4",
@@ -66,7 +66,7 @@
66
66
  "@typescript-eslint/parser": "^7.9.0",
67
67
  "eslint": "^8.57.1",
68
68
  "husky": "^9.0.11",
69
- "lint-staged": "^15.3.0",
69
+ "lint-staged": "^16.0.0",
70
70
  "openapi-types": "^12.1.3",
71
71
  "ts-node": "^10.9.2",
72
72
  "typescript": "5.8.3"
@@ -42,18 +42,7 @@ import * as apis from './{{ className }}';
42
42
  {%- endif -%}
43
43
 
44
44
  {%- if api.body -%}
45
- body:
46
- {% if api.body.propertiesList %}{
47
- {%- for prop in api.body.propertiesList %}
48
- {% if prop.schema.description -%}
49
- /** {{ prop.schema.description }} */
50
- {% endif -%}
51
- '{{ prop.key }}'{{ "?" if not prop.schema.required }}: {{ prop.schema.type }},
52
- {%- endfor %}
53
- }
54
- {%- else -%}
55
- {{ api.body.type }}
56
- {%- endif -%}
45
+ body: {{ api.body.type }}
57
46
  {{ ";" if api.file }}
58
47
  {%- endif %}
59
48
 
@@ -56,19 +56,7 @@
56
56
  {%- endif -%}
57
57
 
58
58
  {%- if api.body -%}
59
- body:
60
- {% if api.body.propertiesList %}
61
- {
62
- {%- for prop in api.body.propertiesList %}
63
- {% if prop.schema.description -%}
64
- /** {{ prop.schema.description }} */
65
- {% endif -%}
66
- '{{ prop.key }}'{{ "?" if not prop.schema.required }}: {{ prop.schema.type }},
67
- {%- endfor %}
68
- }
69
- {%- else -%}
70
- {{ api.body.type }}
71
- {%- endif -%}
59
+ body: {{ api.body.type }}
72
60
  {{ ";" if api.file }}
73
61
  {%- endif %}
74
62