openapi-ts-request 1.3.4 → 1.5.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.
@@ -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)) {
@@ -246,7 +247,7 @@ class ServiceGenerator {
246
247
  getInterfaceTPConfigs() {
247
248
  var _a, _b;
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) || [];
251
252
  // 强行替换掉请求参数params的类型,生成方法对应的 xxxxParams 类型
252
253
  (0, lodash_1.keys)(this.openAPIData.paths).forEach((pathKey) => {
@@ -386,6 +387,26 @@ class ServiceGenerator {
386
387
  else if (functionName) {
387
388
  tmpFunctionRD[functionName] = 1;
388
389
  }
390
+ if (body === null || body === void 0 ? void 0 : body.isAnonymous) {
391
+ const bodyName = (0, lodash_1.upperFirst)(`${functionName}Body`);
392
+ this.interfaceTPConfigs.push({
393
+ typeName: bodyName,
394
+ type: body === null || body === void 0 ? void 0 : body.type,
395
+ isEnum: false,
396
+ props: [],
397
+ });
398
+ body.type = `${this.config.namespace}.${bodyName}`;
399
+ }
400
+ if (response === null || response === void 0 ? void 0 : response.isAnonymous) {
401
+ const responseName = (0, lodash_1.upperFirst)(`${functionName}Response`);
402
+ this.interfaceTPConfigs.push({
403
+ typeName: responseName,
404
+ type: response === null || response === void 0 ? void 0 : response.type,
405
+ isEnum: false,
406
+ props: [],
407
+ });
408
+ response.type = `${this.config.namespace}.${responseName}`;
409
+ }
389
410
  let formattedPath = newApi.path.replace(/:([^/]*)|{([^}]*)}/gi, (_, str, str2) => `$\{${str || str2}}`);
390
411
  // 为 path 中的 params 添加 alias
391
412
  const escapedPathParams = (0, lodash_1.map)(params.path, (item, index) => (Object.assign(Object.assign({}, item), { alias: `param${index}` })));
@@ -566,31 +587,20 @@ class ServiceGenerator {
566
587
  }
567
588
  // 如果 requestBody 有 required 属性,则正常展示;如果没有,默认非必填
568
589
  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 {
590
+ const bodySchema = {
590
591
  mediaType,
591
592
  required,
592
593
  type: this.getType(schema, this.config.namespace),
594
+ isAnonymous: false,
593
595
  };
596
+ // 具名 body 场景
597
+ if ((0, util_2.isReferenceObject)(schema)) {
598
+ bodySchema.type = `${this.config.namespace}.${bodySchema.type}`;
599
+ }
600
+ else {
601
+ bodySchema.isAnonymous = true;
602
+ }
603
+ return bodySchema;
594
604
  }
595
605
  getFileTP(requestBody) {
596
606
  var _a;
@@ -633,6 +643,7 @@ class ServiceGenerator {
633
643
  const defaultResponse = {
634
644
  mediaType: '*/*',
635
645
  type: 'unknown',
646
+ isAnonymous: false,
636
647
  };
637
648
  if (!response) {
638
649
  return defaultResponse;
@@ -647,6 +658,11 @@ class ServiceGenerator {
647
658
  }
648
659
  let schema = (resContent[mediaType].schema ||
649
660
  config_2.DEFAULT_SCHEMA);
661
+ const responseSchema = {
662
+ mediaType,
663
+ type: 'unknown',
664
+ isAnonymous: false,
665
+ };
650
666
  if ((0, util_2.isReferenceObject)(schema)) {
651
667
  const refName = (0, util_2.getLastRefName)(schema.$ref);
652
668
  const childrenSchema = components.schemas[refName];
@@ -657,6 +673,8 @@ class ServiceGenerator {
657
673
  resContent[mediaType].schema ||
658
674
  config_2.DEFAULT_SCHEMA);
659
675
  }
676
+ responseSchema.type = `${this.config.namespace}.${this.getType(schema, this.config.namespace)}`;
677
+ return responseSchema;
660
678
  }
661
679
  if ((0, util_2.isSchemaObject)(schema)) {
662
680
  (0, lodash_1.keys)(schema.properties).map((fieldName) => {
@@ -664,11 +682,10 @@ class ServiceGenerator {
664
682
  schema.properties[fieldName]['required'] =
665
683
  (_b = (_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(fieldName)) !== null && _b !== void 0 ? _b : false;
666
684
  });
685
+ responseSchema.isAnonymous = true;
667
686
  }
668
- return {
669
- mediaType,
670
- type: this.getType(schema, this.config.namespace),
671
- };
687
+ responseSchema.type = this.getType(schema, this.config.namespace);
688
+ return responseSchema;
672
689
  }
673
690
  getParamsTP(parameters = [], path = null) {
674
691
  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'];
@@ -180,8 +181,9 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
180
181
  }
181
182
  return `{ ${(0, lodash_1.keys)(schemaObject.properties)
182
183
  .map((key) => {
183
- var _a, _b;
184
+ var _a;
184
185
  let required = false;
186
+ const property = (((_a = schemaObject.properties) === null || _a === void 0 ? void 0 : _a[key]) || {});
185
187
  if ((0, lodash_1.isBoolean)(schemaObject.required) && schemaObject.required) {
186
188
  required = true;
187
189
  }
@@ -189,8 +191,7 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
189
191
  schemaObject.required.includes(key)) {
190
192
  required = true;
191
193
  }
192
- if ('required' in (schemaObject.properties[key] || {}) &&
193
- ((_a = schemaObject.properties[key]) === null || _a === void 0 ? void 0 : _a.required)) {
194
+ if (property.required) {
194
195
  required = true;
195
196
  }
196
197
  /**
@@ -199,18 +200,28 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
199
200
  * 在后面进行格式化的时候会将正确的字符串转换为正常形式,
200
201
  * 错误的继续保留字符串。
201
202
  * */
202
- return `'${key}'${required ? '' : '?'}: ${getDefaultType((_b = schemaObject.properties) === null || _b === void 0 ? void 0 : _b[key], namespace)}; `;
203
+ return `
204
+ ${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace)}; `;
203
205
  })
204
206
  .join('')}}`;
205
207
  }
206
208
  return 'unknown';
207
209
  }
208
210
  function getDefaultFileTag(operationObject, apiPath) {
209
- return operationObject['x-swagger-router-controller']
210
- ? [operationObject['x-swagger-router-controller']]
211
- : operationObject.tags || [operationObject.operationId] || [
212
- apiPath.replace('/', '').split('/')[1],
213
- ];
211
+ let lastTags = [];
212
+ if (operationObject['x-swagger-router-controller']) {
213
+ lastTags = [operationObject['x-swagger-router-controller']];
214
+ }
215
+ else if (!(0, lodash_1.isEmpty)(operationObject.tags)) {
216
+ lastTags = operationObject.tags;
217
+ }
218
+ else if (operationObject.operationId) {
219
+ lastTags = [operationObject.operationId];
220
+ }
221
+ else {
222
+ lastTags = [apiPath.replace('/', '').split('/')[1]];
223
+ }
224
+ return lastTags;
214
225
  }
215
226
  function findDuplicateTypeNames(arr) {
216
227
  const counts = (0, lodash_1.countBy)(arr);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-ts-request",
3
- "version": "1.3.4",
3
+ "version": "1.5.0",
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",
@@ -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",
@@ -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