openapi-ts-request 1.12.2 → 1.12.4

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.
@@ -9,6 +9,7 @@ export default class ServiceGenerator {
9
9
  protected schemaList: ISchemaItem[];
10
10
  protected interfaceTPConfigs: ITypeItem[];
11
11
  protected typeModuleMap: Map<string, Set<string>>;
12
+ protected schemaKeyToTypeNameMap: Map<string, string>;
12
13
  constructor(config: GenerateServiceProps, openAPIData: OpenAPIObject);
13
14
  genFile(): void;
14
15
  private getInterfaceTPConfigs;
@@ -26,6 +26,8 @@ class ServiceGenerator {
26
26
  this.interfaceTPConfigs = [];
27
27
  // 记录每个类型被哪些模块使用(用于拆分类型文件)
28
28
  this.typeModuleMap = new Map();
29
+ // 从原始 schema key 到最终类型名称的映射(用于处理重名情况)
30
+ this.schemaKeyToTypeNameMap = new Map();
29
31
  this.config = Object.assign({ templatesFolder: (0, path_1.join)(__dirname, '../../', 'templates') }, config);
30
32
  this.generateInfoLog();
31
33
  const includeTags = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.includeTags) || [];
@@ -151,9 +153,12 @@ class ServiceGenerator {
151
153
  const isGenJavaScript = this.config.isGenJavaScript;
152
154
  const reactQueryMode = this.config.reactQueryMode;
153
155
  const reactQueryFileName = (0, config_2.displayReactQueryFileName)(reactQueryMode);
156
+ // 先处理重复的 typeName,建立类型名称映射(在生成 service controller 之前)
157
+ this.interfaceTPConfigs = this.getInterfaceTPConfigs();
158
+ this.schemaKeyToTypeNameMap = (0, util_2.handleDuplicateTypeNames)(this.interfaceTPConfigs);
154
159
  if (!isOnlyGenTypeScriptType) {
155
160
  const prettierError = [];
156
- // 生成 service controller 文件
161
+ // 生成 service controller 文件(此时类型名称映射已经建立)
157
162
  this.getServiceTPConfigs().forEach((tp) => {
158
163
  var _a, _b;
159
164
  const { list } = tp, restTp = tslib_1.__rest(tp, ["list"]);
@@ -181,9 +186,6 @@ class ServiceGenerator {
181
186
  (0, log_1.default)('🚥 格式化失败,请检查 service controller 文件内可能存在的语法错误');
182
187
  }
183
188
  }
184
- // 处理重复的 typeName
185
- this.interfaceTPConfigs = this.getInterfaceTPConfigs();
186
- (0, util_2.handleDuplicateTypeNames)(this.interfaceTPConfigs);
187
189
  // 生成 ts 类型声明
188
190
  if (!isGenJavaScript) {
189
191
  if (this.config.isSplitTypesByModule) {
@@ -230,7 +232,8 @@ class ServiceGenerator {
230
232
  });
231
233
  }
232
234
  else {
233
- // 传统方式:所有类型在一个文件
235
+ // 在生成文件前,对 interfaceTPConfigs 进行排序(因为 getServiceTPConfigs 可能添加了新类型)
236
+ this.interfaceTPConfigs.sort((a, b) => a.typeName.localeCompare(b.typeName));
234
237
  this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
235
238
  nullable: this.config.nullable,
236
239
  list: this.interfaceTPConfigs,
@@ -477,6 +480,7 @@ class ServiceGenerator {
477
480
  : '',
478
481
  enumLabelType: isEnum ? result.enumLabelType : '',
479
482
  description: result.description,
483
+ originalSchemaKey: schemaKey, // 保存原始 schema key,用于处理重名后的类型映射
480
484
  });
481
485
  // 记录 schema 类型归属
482
486
  if (this.config.isSplitTypesByModule && schemaUsageMap.has(schemaKey)) {
@@ -495,7 +499,8 @@ class ServiceGenerator {
495
499
  });
496
500
  }
497
501
  });
498
- return lastTypes === null || lastTypes === void 0 ? void 0 : lastTypes.sort((a, b) => a.typeName.localeCompare(b.typeName)); // typeName排序
502
+ return lastTypes;
503
+ // return lastTypes?.sort((a, b) => a.typeName.localeCompare(b.typeName)); // typeName排序
499
504
  }
500
505
  getServiceTPConfigs() {
501
506
  return (0, lodash_1.keys)(this.apiData)
@@ -513,7 +518,7 @@ class ServiceGenerator {
513
518
  // 暂不支持变量, path 需要普通前缀请使用例如: apiPrefix: "`api`", path 需要变量前缀请使用例如: apiPrefix: "api"
514
519
  !api.path.includes('${'))
515
520
  .map((api) => {
516
- var _a, _b, _c, _d, _e, _f, _g, _h;
521
+ var _a, _b, _c, _d, _e;
517
522
  const newApi = api;
518
523
  try {
519
524
  const params = this.getParamsTP(newApi.parameters, newApi.path) || {};
@@ -624,22 +629,36 @@ class ServiceGenerator {
624
629
  // prefix 变量
625
630
  return `$\{${prefix}}${formattedPath}`;
626
631
  };
627
- return Object.assign(Object.assign({}, newApi), { functionName: this.config.isCamelCase
628
- ? (0, util_1.camelCase)(functionName)
629
- : functionName, typeName: this.getFunctionParamsTypeName(newApi), path: getPrefixPath(), pathInComment: formattedPath.replace(/\*/g, '&#42;'), apifoxRunLink: newApi === null || newApi === void 0 ? void 0 : newApi['x-run-in-apifox'], hasPathVariables: formattedPath.includes('{'), hasApiPrefix: !!this.config.apiPrefix, method: newApi.method,
630
- // 如果 functionName 和 summary 相同,则不显示 summary
631
- desc: functionName === newApi.summary
632
- ? (newApi.description || '').replace(config_2.lineBreakReg, '')
632
+ return Object.assign(Object.assign(Object.assign({}, (() => {
633
+ var _a, _b, _c;
634
+ const rawDesc = functionName === newApi.summary
635
+ ? newApi.description || ''
633
636
  : [
634
637
  newApi.summary,
635
638
  newApi.description,
636
- ((_e = (_d = newApi.responses) === null || _d === void 0 ? void 0 : _d.default) === null || _e === void 0 ? void 0 : _e.description)
637
- ? `返回值: ${((_f = newApi.responses) === null || _f === void 0 ? void 0 : _f.default).description}`
639
+ ((_b = (_a = newApi.responses) === null || _a === void 0 ? void 0 : _a.default) === null || _b === void 0 ? void 0 : _b.description)
640
+ ? `返回值: ${((_c = newApi.responses) === null || _c === void 0 ? void 0 : _c.default).description}`
638
641
  : '',
639
642
  ]
640
643
  .filter((s) => s)
641
- .join(' ')
642
- .replace(config_2.lineBreakReg, ''), hasHeader: !!(params === null || params === void 0 ? void 0 : params.header) || !!(body === null || body === void 0 ? void 0 : body.mediaType), params: finalParams, hasParams: Boolean((0, lodash_1.keys)(finalParams).length), options: ((_h = (_g = this.config.hook) === null || _g === void 0 ? void 0 : _g.customOptionsDefaultValue) === null || _h === void 0 ? void 0 : _h.call(_g, newApi)) || {}, body,
644
+ .join(' ');
645
+ const hasLineBreak = config_2.lineBreakReg.test(rawDesc);
646
+ // 格式化描述文本,让描述支持换行
647
+ const desc = hasLineBreak
648
+ ? '\n * ' + rawDesc.split('\n').join('\n * ') + '\n *'
649
+ : rawDesc;
650
+ // 如果描述有换行,pathInComment 结尾加换行使 */ 单独一行
651
+ const pathInComment = hasLineBreak
652
+ ? formattedPath.replace(/\*/g, '&#42;') + '\n'
653
+ : formattedPath.replace(/\*/g, '&#42;');
654
+ const originApifoxRunLink = newApi === null || newApi === void 0 ? void 0 : newApi['x-run-in-apifox'];
655
+ const apifoxRunLink = hasLineBreak && originApifoxRunLink
656
+ ? ' * ' + originApifoxRunLink + '\n'
657
+ : originApifoxRunLink;
658
+ return { desc, pathInComment, apifoxRunLink };
659
+ })()), newApi), { functionName: this.config.isCamelCase
660
+ ? (0, util_1.camelCase)(functionName)
661
+ : functionName, typeName: this.getFunctionParamsTypeName(newApi), path: getPrefixPath(), hasPathVariables: formattedPath.includes('{'), hasApiPrefix: !!this.config.apiPrefix, method: newApi.method, hasHeader: !!(params === null || params === void 0 ? void 0 : params.header) || !!(body === null || body === void 0 ? void 0 : body.mediaType), params: finalParams, hasParams: Boolean((0, lodash_1.keys)(finalParams).length), options: ((_e = (_d = this.config.hook) === null || _d === void 0 ? void 0 : _d.customOptionsDefaultValue) === null || _e === void 0 ? void 0 : _e.call(_d, newApi)) || {}, body,
643
662
  file, hasFormData: formData, response });
644
663
  }
645
664
  catch (error) {
@@ -779,18 +798,21 @@ class ServiceGenerator {
779
798
  var _a, _b;
780
799
  const customTypeHookFunc = (_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customType;
781
800
  const schemas = (_b = this.openAPIData.components) === null || _b === void 0 ? void 0 : _b.schemas;
801
+ const schemaKeyToTypeNameMap = this.schemaKeyToTypeNameMap;
782
802
  if (customTypeHookFunc) {
803
+ // 为自定义 hook 提供支持映射的 originGetType
804
+ const originGetTypeWithMapping = (schema, ns, s) => (0, util_2.getDefaultType)(schema, ns, s, schemaKeyToTypeNameMap);
783
805
  const type = customTypeHookFunc({
784
806
  schemaObject,
785
807
  namespace,
786
808
  schemas,
787
- originGetType: util_2.getDefaultType,
809
+ originGetType: originGetTypeWithMapping,
788
810
  });
789
811
  if (typeof type === 'string') {
790
812
  return type;
791
813
  }
792
814
  }
793
- return (0, util_2.getDefaultType)(schemaObject, namespace, schemas);
815
+ return (0, util_2.getDefaultType)(schemaObject, namespace, schemas, schemaKeyToTypeNameMap);
794
816
  }
795
817
  getFunctionParamsTypeName(data) {
796
818
  var _a, _b, _c;
@@ -1153,6 +1175,13 @@ class ServiceGenerator {
1153
1175
  });
1154
1176
  // 处理公共类型的依赖:如果公共类型依赖某个模块类型,将该类型也移到公共类型
1155
1177
  Helper.moveCommonTypeDependenciesToCommon({ moduleTypes, commonTypes });
1178
+ // 对每个模块的类型列表进行排序
1179
+ moduleTypes.forEach((types) => {
1180
+ types.sort((a, b) => a.typeName.localeCompare(b.typeName));
1181
+ });
1182
+ // 对公共类型和枚举类型进行排序
1183
+ commonTypes.sort((a, b) => a.typeName.localeCompare(b.typeName));
1184
+ enumTypes.sort((a, b) => a.typeName.localeCompare(b.typeName));
1156
1185
  return { moduleTypes, commonTypes, enumTypes };
1157
1186
  }
1158
1187
  }
@@ -56,7 +56,16 @@ function resolveEnumObject(params) {
56
56
  const enumArray = schemaObject.enum;
57
57
  let enumStr = '';
58
58
  let enumLabelTypeStr = '';
59
- if (config_2.numberEnum.includes(schemaObject.type) || (0, util_1.isAllNumber)(enumArray)) {
59
+ // 获取实际的类型(处理 OpenAPI 3.1 type 数组情况)
60
+ const getActualType = (type) => {
61
+ if (Array.isArray(type)) {
62
+ // 如果是数组,返回第一个非 null 类型
63
+ return type.find((t) => t !== 'null') || 'string';
64
+ }
65
+ return type;
66
+ };
67
+ const actualType = getActualType(schemaObject.type);
68
+ if (config_2.numberEnum.includes(actualType) || (0, util_1.isAllNumber)(enumArray)) {
60
69
  if (config.isSupportParseEnumDesc && schemaObject.description) {
61
70
  const enumMap = (0, util_1.parseDescriptionEnum)(schemaObject.description);
62
71
  enumStr = `{${(0, lodash_1.map)(enumArray, (value) => {
@@ -95,7 +104,7 @@ function resolveEnumObject(params) {
95
104
  }).join(',')}}`;
96
105
  }
97
106
  else {
98
- if (config_2.numberEnum.includes(schemaObject.type) || (0, util_1.isAllNumber)(enumArray)) {
107
+ if (config_2.numberEnum.includes(actualType) || (0, util_1.isAllNumber)(enumArray)) {
99
108
  if ((config.isSupportParseEnumDesc || config.supportParseEnumDescByReg) &&
100
109
  schemaObject.description) {
101
110
  const enumMap = config.isSupportParseEnumDesc
@@ -117,11 +126,15 @@ function resolveEnumObject(params) {
117
126
  enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}":"${value}"`).join(',')}}`;
118
127
  }
119
128
  }
129
+ // 格式化描述文本,让描述支持换行
130
+ const formattedDescription = schemaObject.description && config_2.lineBreakReg.test(schemaObject.description)
131
+ ? '\n * ' + schemaObject.description.split('\n').join('\n * ') + '\n'
132
+ : schemaObject.description;
120
133
  return {
121
134
  isEnum: true,
122
135
  type: Array.isArray(enumArray) ? enumStr : 'string',
123
136
  enumLabelType: enumLabelTypeStr,
124
- description: schemaObject.description,
137
+ description: formattedDescription,
125
138
  };
126
139
  }
127
140
  /**
@@ -157,17 +170,23 @@ function getProps(params) {
157
170
  // 获取描述信息,如果是 $ref 引用,尝试获取引用对象的描述
158
171
  let desc = [schema.title, schema.description]
159
172
  .filter((item) => item)
160
- .join(' ')
161
- .replace(config_2.lineBreakReg, '');
173
+ .join(' ');
174
+ // 格式化描述文本,让描述支持换行
175
+ desc = config_2.lineBreakReg.test(desc)
176
+ ? '\n * ' + desc.split('\n').join('\n * ') + '\n'
177
+ : desc;
162
178
  // 如果是 $ref 引用,尝试获取引用对象的描述
163
179
  if ((0, util_1.isReferenceObject)(schema) && openAPIData) {
164
180
  const refName = (0, util_1.getLastRefName)(schema.$ref);
165
181
  const refSchema = (_b = (_a = openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas) === null || _b === void 0 ? void 0 : _b[refName];
166
182
  if (refSchema) {
167
- const refDesc = [refSchema.title, refSchema.description]
183
+ let refDesc = [refSchema.title, refSchema.description]
168
184
  .filter((item) => item)
169
- .join(' ')
170
- .replace(config_2.lineBreakReg, '');
185
+ .join(' ');
186
+ // 格式化描述文本,让描述支持换行
187
+ refDesc = config_2.lineBreakReg.test(refDesc)
188
+ ? '\n * ' + refDesc.split('\n').join('\n * ') + '\n'
189
+ : refDesc;
171
190
  if (refDesc) {
172
191
  desc = desc + refDesc;
173
192
  }
@@ -225,7 +244,16 @@ function resolveRefObject(params) {
225
244
  }
226
245
  else {
227
246
  const schemaObj = schema;
228
- resolvedType = schemaObj.type;
247
+ // 处理 OpenAPI 3.1 的 type 数组情况
248
+ if (Array.isArray(schemaObj.type)) {
249
+ // 如果是数组,使用第一个非 null 类型
250
+ resolvedType =
251
+ schemaObj.type.find((t) => t !== 'null') ||
252
+ 'string';
253
+ }
254
+ else {
255
+ resolvedType = schemaObj.type;
256
+ }
229
257
  }
230
258
  const finalSchema = schema;
231
259
  return Object.assign(Object.assign({}, (resolvedSchema || {})), { type: resolvedType || finalSchema.type });
@@ -260,7 +288,7 @@ function getResponsesType(params) {
260
288
  : description;
261
289
  // 生成带注释的类型定义
262
290
  return formattedDescription
263
- ? ` /**\n * ${formattedDescription}\n */\n ${statusCode}: ${lastType};`
291
+ ? ` /**\n * ${formattedDescription}\n */\n ${statusCode}: ${lastType};`
264
292
  : ` ${statusCode}: ${lastType};`;
265
293
  });
266
294
  // 返回完整的对象类型定义
@@ -29,6 +29,8 @@ export interface ITypeItem {
29
29
  description?: string;
30
30
  /** 类型所属的模块名称(用于拆分类型文件) */
31
31
  belongsToModules?: Set<string>;
32
+ /** 原始的 schema key(用于处理重名后的类型映射) */
33
+ originalSchemaKey?: string;
32
34
  }
33
35
  export type ICustomSchemaObject = SchemaObject & {
34
36
  isAllowed?: boolean;
@@ -3,10 +3,17 @@ import type { ITypeItem } from './type';
3
3
  export declare function stripDot(str: string): string;
4
4
  export declare function resolveTypeName(typeName: string): string;
5
5
  export declare function getRefName(refObject: ReferenceObject | string): string;
6
+ /**
7
+ * 获取引用类型名称,支持类型名称映射
8
+ * @param refObject 引用对象
9
+ * @param schemaKeyToTypeNameMap 从原始 schema key 到最终类型名称的映射(处理重名情况)
10
+ * @returns 最终的类型名称
11
+ */
12
+ export declare function getRefNameWithMapping(refObject: ReferenceObject | string, schemaKeyToTypeNameMap?: Map<string, string>): string;
6
13
  export declare function getLastRefName(refPath?: string): string;
7
- export declare function getDefaultType(schemaObject?: ISchemaObject | string, namespace?: string, schemas?: ComponentsObject['schemas']): string;
14
+ export declare function getDefaultType(schemaObject?: ISchemaObject | string, namespace?: string, schemas?: ComponentsObject['schemas'], schemaKeyToTypeNameMap?: Map<string, string>): string;
8
15
  export declare function getDefaultFileTag(operationObject: OperationObject, apiPath: string): string[];
9
- export declare function handleDuplicateTypeNames(interfaceTPConfigs: Array<Pick<ITypeItem, 'typeName' | 'displayLabelFuncName'>>): void;
16
+ export declare function handleDuplicateTypeNames(interfaceTPConfigs: Array<Pick<ITypeItem, 'typeName' | 'displayLabelFuncName' | 'originalSchemaKey'>>): Map<string, string>;
10
17
  export declare function getBasePrefix(paths: string[]): string;
11
18
  export declare function genDefaultFunctionName(path: string, pathBasePrefix: string): string;
12
19
  export declare function getFinalFileName(s: string): string;
@@ -4,6 +4,7 @@ exports.getAxiosResponseType = exports.getBinaryResponseType = exports.isBinaryM
4
4
  exports.stripDot = stripDot;
5
5
  exports.resolveTypeName = resolveTypeName;
6
6
  exports.getRefName = getRefName;
7
+ exports.getRefNameWithMapping = getRefNameWithMapping;
7
8
  exports.getLastRefName = getLastRefName;
8
9
  exports.getDefaultType = getDefaultType;
9
10
  exports.getDefaultFileTag = getDefaultFileTag;
@@ -83,13 +84,31 @@ function getRefName(refObject) {
83
84
  }
84
85
  return resolveTypeName(getLastRefName(refObject.$ref));
85
86
  }
87
+ /**
88
+ * 获取引用类型名称,支持类型名称映射
89
+ * @param refObject 引用对象
90
+ * @param schemaKeyToTypeNameMap 从原始 schema key 到最终类型名称的映射(处理重名情况)
91
+ * @returns 最终的类型名称
92
+ */
93
+ function getRefNameWithMapping(refObject, schemaKeyToTypeNameMap) {
94
+ if (!isReferenceObject(refObject)) {
95
+ return refObject;
96
+ }
97
+ const schemaKey = getLastRefName(refObject.$ref);
98
+ // 如果存在映射,使用映射后的类型名称
99
+ if (schemaKeyToTypeNameMap === null || schemaKeyToTypeNameMap === void 0 ? void 0 : schemaKeyToTypeNameMap.has(schemaKey)) {
100
+ return schemaKeyToTypeNameMap.get(schemaKey);
101
+ }
102
+ // 否则使用默认的类型名称解析
103
+ return resolveTypeName(schemaKey);
104
+ }
86
105
  function getLastRefName(refPath = '') {
87
106
  const refPaths = refPath.split('/');
88
107
  return refPaths.length > 0
89
108
  ? decodeURIComponent(refPaths[refPaths.length - 1])
90
109
  : '';
91
110
  }
92
- function getDefaultType(schemaObject, namespace = '', schemas) {
111
+ function getDefaultType(schemaObject, namespace = '', schemas, schemaKeyToTypeNameMap) {
93
112
  var _a, _b;
94
113
  if ((0, lodash_1.isUndefined)(schemaObject) || (0, lodash_1.isNull)(schemaObject)) {
95
114
  return 'unknown';
@@ -98,12 +117,23 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
98
117
  return schemaObject;
99
118
  }
100
119
  if (isReferenceObject(schemaObject)) {
101
- // return getRefName(schemaObject);
102
- return [namespace, getRefName(schemaObject)].filter((s) => s).join('.');
120
+ // 使用映射获取正确的类型名称(处理重名情况)
121
+ const refName = getRefNameWithMapping(schemaObject, schemaKeyToTypeNameMap);
122
+ return [namespace, refName].filter((s) => s).join('.');
103
123
  }
104
124
  let type = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.type;
105
125
  const dateEnum = ['Date', 'date', 'dateTime', 'date-time', 'datetime'];
106
126
  const stringEnum = ['string', 'email', 'password', 'url', 'byte', 'binary'];
127
+ // OpenAPI 3.1 支持 type 为数组,例如 ["string", "null"]
128
+ if (Array.isArray(type)) {
129
+ return type
130
+ .map((t) => {
131
+ // 为数组中的每个类型创建一个临时的 schemaObject
132
+ const tempSchema = Object.assign(Object.assign({}, schemaObject), { type: t });
133
+ return getDefaultType(tempSchema, namespace, schemas);
134
+ })
135
+ .join(' | ');
136
+ }
107
137
  if (type === 'null') {
108
138
  return 'null';
109
139
  }
@@ -132,11 +162,11 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
132
162
  }
133
163
  if (Array.isArray(items)) {
134
164
  const arrayItemType = items
135
- .map((subType) => getDefaultType((subType.schema || subType), namespace))
165
+ .map((subType) => getDefaultType((subType.schema || subType), namespace, schemas, schemaKeyToTypeNameMap))
136
166
  .toString();
137
167
  return `[${arrayItemType}]`;
138
168
  }
139
- const arrayType = getDefaultType(items, namespace);
169
+ const arrayType = getDefaultType(items, namespace, schemas, schemaKeyToTypeNameMap);
140
170
  return arrayType.includes(' | ') ? `(${arrayType})[]` : `${arrayType}[]`;
141
171
  }
142
172
  if (type === 'enum') {
@@ -148,12 +178,12 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
148
178
  }
149
179
  if (schemaObject.oneOf && schemaObject.oneOf.length) {
150
180
  return schemaObject.oneOf
151
- .map((item) => getDefaultType(item, namespace))
181
+ .map((item) => getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap))
152
182
  .join(' | ');
153
183
  }
154
184
  if ((_a = schemaObject.anyOf) === null || _a === void 0 ? void 0 : _a.length) {
155
185
  return schemaObject.anyOf
156
- .map((item) => getDefaultType(item, namespace))
186
+ .map((item) => getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap))
157
187
  .join(' | ');
158
188
  }
159
189
  if ((_b = schemaObject.allOf) === null || _b === void 0 ? void 0 : _b.length) {
@@ -163,17 +193,16 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
163
193
  // 不使用 getRefName 函数处理,无法通过 schemas[schemaKey] 获取到schema
164
194
  const schemaKey = getLastRefName(item.$ref);
165
195
  if ((_a = schemas === null || schemas === void 0 ? void 0 : schemas[schemaKey]) === null || _a === void 0 ? void 0 : _a.enum) {
166
- // return `I${getDefaultType(item, namespace)}`;
167
- return getDefaultType(item, namespace);
196
+ return getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap);
168
197
  }
169
198
  }
170
- return getDefaultType(item, namespace);
199
+ return getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap);
171
200
  });
172
201
  return `(${allofList.join(' & ')})`;
173
202
  }
174
203
  if (schemaObject.type === 'object' || schemaObject.properties) {
175
204
  if ((0, lodash_1.isObject)(schemaObject.additionalProperties)) {
176
- const type = getDefaultType(schemaObject.additionalProperties, namespace, schemas);
205
+ const type = getDefaultType(schemaObject.additionalProperties, namespace, schemas, schemaKeyToTypeNameMap);
177
206
  return `Record<string, ${type}>`;
178
207
  }
179
208
  if (!(0, lodash_1.keys)(schemaObject.properties).length) {
@@ -201,7 +230,7 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
201
230
  * 错误的继续保留字符串。
202
231
  * */
203
232
  return `
204
- ${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace)}; `;
233
+ ${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace, schemas, schemaKeyToTypeNameMap)}; `;
205
234
  })
206
235
  .join('')}}`;
207
236
  }
@@ -229,6 +258,8 @@ function findDuplicateTypeNames(arr) {
229
258
  return duplicates;
230
259
  }
231
260
  function handleDuplicateTypeNames(interfaceTPConfigs) {
261
+ // 创建从原始 schema key 到最终类型名称的映射
262
+ const schemaKeyToTypeNameMap = new Map();
232
263
  const duplicateTypeNames = findDuplicateTypeNames((0, lodash_1.map)(interfaceTPConfigs, (item) => item.typeName));
233
264
  if (!(0, lodash_1.isEmpty)(duplicateTypeNames)) {
234
265
  (0, lodash_1.forEach)(duplicateTypeNames, (typeName) => {
@@ -243,6 +274,13 @@ function handleDuplicateTypeNames(interfaceTPConfigs) {
243
274
  });
244
275
  });
245
276
  }
277
+ // 建立映射关系(在处理重名之后)
278
+ (0, lodash_1.forEach)(interfaceTPConfigs, (interfaceTP) => {
279
+ if (interfaceTP.originalSchemaKey) {
280
+ schemaKeyToTypeNameMap.set(interfaceTP.originalSchemaKey, interfaceTP.typeName);
281
+ }
282
+ });
283
+ return schemaKeyToTypeNameMap;
246
284
  }
247
285
  // 检测所有path重复区域(prefix)
248
286
  function getBasePrefix(paths) {
@@ -86,10 +86,14 @@ function getDateByName(name, parentsKey) {
86
86
  function primitive(schemaParams, propsName) {
87
87
  const schema = (0, util_2.objectify)(schemaParams);
88
88
  const { type, format } = schema;
89
- const value = primitives_1.primitives[`${type}_${format || getDateByName(propsName)}`] ||
90
- primitives_1.primitives[type];
89
+ // 处理 OpenAPI 3.1 type 数组情况
90
+ const actualType = Array.isArray(type)
91
+ ? type.find((t) => t !== 'null') || 'string'
92
+ : type;
93
+ const value = primitives_1.primitives[`${actualType}_${format || getDateByName(propsName)}`] ||
94
+ primitives_1.primitives[actualType];
91
95
  if ((0, lodash_1.isUndefined)(schema.example)) {
92
- return value || `Unknown Type: ${schema.type}`;
96
+ return value || `Unknown Type: ${actualType}`;
93
97
  }
94
98
  return schema.example;
95
99
  }
@@ -3,7 +3,7 @@ import type { OpenAPIObject, ParameterObject, ReferenceObject, SchemaObject } fr
3
3
  export declare function objectify<T>(thing: T): T;
4
4
  export declare function get(openAPI: OpenAPIObject, path: string): OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject;
5
5
  export declare function normalizeArray(arr: string[] | string): string[];
6
- export declare function inferSchema(thing: ParameterObject | SchemaObject | ReferenceObject | OpenAPIV3.MediaTypeObject): OpenAPIV3.ReferenceObject | OpenAPIV3.MediaTypeObject | {
6
+ export declare function inferSchema(thing: ParameterObject | SchemaObject | ReferenceObject | OpenAPIV3.MediaTypeObject): import("../type").NonArraySchemaObject | OpenAPIV3.ReferenceObject | OpenAPIV3.MediaTypeObject | {
7
7
  type: string;
8
8
  enum?: any[];
9
9
  title?: string;
package/dist/type.d.ts CHANGED
@@ -16,7 +16,7 @@ export type MutuallyExclusiveWithFallback<T, N> = {
16
16
  }[keyof T];
17
17
  type Modify<T, R> = Omit<T, keyof R> & R;
18
18
  type ICustomBaseSchemaObject = {
19
- type: ISchemaObjectType;
19
+ type: ISchemaObjectType | ISchemaObjectType[];
20
20
  format?: ISchemaObjectFormat;
21
21
  additionalProperties?: boolean | ISchemaObject;
22
22
  properties?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-ts-request",
3
- "version": "1.12.2",
3
+ "version": "1.12.4",
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",