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.
- package/dist/generator/serviceGenarator.d.ts +1 -0
- package/dist/generator/serviceGenarator.js +48 -19
- package/dist/generator/serviceGeneratorHelper.js +38 -10
- package/dist/generator/type.d.ts +2 -0
- package/dist/generator/util.d.ts +9 -2
- package/dist/generator/util.js +50 -12
- package/dist/parser-mock/index.js +7 -3
- package/dist/parser-mock/util.d.ts +1 -1
- package/dist/type.d.ts +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
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({},
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
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
|
-
((
|
|
637
|
-
? `返回值: ${((
|
|
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
|
-
|
|
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, '*') + '\n'
|
|
653
|
+
: formattedPath.replace(/\*/g, '*');
|
|
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:
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
183
|
+
let refDesc = [refSchema.title, refSchema.description]
|
|
168
184
|
.filter((item) => item)
|
|
169
|
-
.join(' ')
|
|
170
|
-
|
|
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
|
-
|
|
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
|
|
291
|
+
? ` /**\n * ${formattedDescription}\n */\n ${statusCode}: ${lastType};`
|
|
264
292
|
: ` ${statusCode}: ${lastType};`;
|
|
265
293
|
});
|
|
266
294
|
// 返回完整的对象类型定义
|
package/dist/generator/type.d.ts
CHANGED
|
@@ -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;
|
package/dist/generator/util.d.ts
CHANGED
|
@@ -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'>>):
|
|
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;
|
package/dist/generator/util.js
CHANGED
|
@@ -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
|
-
//
|
|
102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
90
|
-
|
|
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: ${
|
|
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.
|
|
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",
|