openapi-ts-request 1.12.3 → 1.12.5
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 +49 -19
- package/dist/generator/serviceGeneratorHelper.js +20 -8
- package/dist/generator/type.d.ts +2 -0
- package/dist/generator/util.d.ts +14 -2
- package/dist/generator/util.js +55 -12
- package/package.json +1 -1
- package/templates/displayTypeLabel.njk +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) {
|
|
@@ -733,6 +752,7 @@ class ServiceGenerator {
|
|
|
733
752
|
autoescape: false,
|
|
734
753
|
});
|
|
735
754
|
env.addFilter('capitalizeFirst', util_2.capitalizeFirstLetter);
|
|
755
|
+
env.addFilter('escapeJs', util_2.escapeStringForJs);
|
|
736
756
|
const destPath = (0, path_1.join)(this.config.serversPath, fileName);
|
|
737
757
|
const destCode = nunjucks_1.default.renderString(template, Object.assign({ disableTypeCheck: false }, processedParams));
|
|
738
758
|
let mergerProps = {};
|
|
@@ -779,18 +799,21 @@ class ServiceGenerator {
|
|
|
779
799
|
var _a, _b;
|
|
780
800
|
const customTypeHookFunc = (_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customType;
|
|
781
801
|
const schemas = (_b = this.openAPIData.components) === null || _b === void 0 ? void 0 : _b.schemas;
|
|
802
|
+
const schemaKeyToTypeNameMap = this.schemaKeyToTypeNameMap;
|
|
782
803
|
if (customTypeHookFunc) {
|
|
804
|
+
// 为自定义 hook 提供支持映射的 originGetType
|
|
805
|
+
const originGetTypeWithMapping = (schema, ns, s) => (0, util_2.getDefaultType)(schema, ns, s, schemaKeyToTypeNameMap);
|
|
783
806
|
const type = customTypeHookFunc({
|
|
784
807
|
schemaObject,
|
|
785
808
|
namespace,
|
|
786
809
|
schemas,
|
|
787
|
-
originGetType:
|
|
810
|
+
originGetType: originGetTypeWithMapping,
|
|
788
811
|
});
|
|
789
812
|
if (typeof type === 'string') {
|
|
790
813
|
return type;
|
|
791
814
|
}
|
|
792
815
|
}
|
|
793
|
-
return (0, util_2.getDefaultType)(schemaObject, namespace, schemas);
|
|
816
|
+
return (0, util_2.getDefaultType)(schemaObject, namespace, schemas, schemaKeyToTypeNameMap);
|
|
794
817
|
}
|
|
795
818
|
getFunctionParamsTypeName(data) {
|
|
796
819
|
var _a, _b, _c;
|
|
@@ -1153,6 +1176,13 @@ class ServiceGenerator {
|
|
|
1153
1176
|
});
|
|
1154
1177
|
// 处理公共类型的依赖:如果公共类型依赖某个模块类型,将该类型也移到公共类型
|
|
1155
1178
|
Helper.moveCommonTypeDependenciesToCommon({ moduleTypes, commonTypes });
|
|
1179
|
+
// 对每个模块的类型列表进行排序
|
|
1180
|
+
moduleTypes.forEach((types) => {
|
|
1181
|
+
types.sort((a, b) => a.typeName.localeCompare(b.typeName));
|
|
1182
|
+
});
|
|
1183
|
+
// 对公共类型和枚举类型进行排序
|
|
1184
|
+
commonTypes.sort((a, b) => a.typeName.localeCompare(b.typeName));
|
|
1185
|
+
enumTypes.sort((a, b) => a.typeName.localeCompare(b.typeName));
|
|
1156
1186
|
return { moduleTypes, commonTypes, enumTypes };
|
|
1157
1187
|
}
|
|
1158
1188
|
}
|
|
@@ -126,11 +126,15 @@ function resolveEnumObject(params) {
|
|
|
126
126
|
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}":"${value}"`).join(',')}}`;
|
|
127
127
|
}
|
|
128
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;
|
|
129
133
|
return {
|
|
130
134
|
isEnum: true,
|
|
131
135
|
type: Array.isArray(enumArray) ? enumStr : 'string',
|
|
132
136
|
enumLabelType: enumLabelTypeStr,
|
|
133
|
-
description:
|
|
137
|
+
description: formattedDescription,
|
|
134
138
|
};
|
|
135
139
|
}
|
|
136
140
|
/**
|
|
@@ -166,17 +170,23 @@ function getProps(params) {
|
|
|
166
170
|
// 获取描述信息,如果是 $ref 引用,尝试获取引用对象的描述
|
|
167
171
|
let desc = [schema.title, schema.description]
|
|
168
172
|
.filter((item) => item)
|
|
169
|
-
.join(' ')
|
|
170
|
-
|
|
173
|
+
.join(' ');
|
|
174
|
+
// 格式化描述文本,让描述支持换行
|
|
175
|
+
desc = config_2.lineBreakReg.test(desc)
|
|
176
|
+
? '\n * ' + desc.split('\n').join('\n * ') + '\n'
|
|
177
|
+
: desc;
|
|
171
178
|
// 如果是 $ref 引用,尝试获取引用对象的描述
|
|
172
179
|
if ((0, util_1.isReferenceObject)(schema) && openAPIData) {
|
|
173
180
|
const refName = (0, util_1.getLastRefName)(schema.$ref);
|
|
174
181
|
const refSchema = (_b = (_a = openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas) === null || _b === void 0 ? void 0 : _b[refName];
|
|
175
182
|
if (refSchema) {
|
|
176
|
-
|
|
183
|
+
let refDesc = [refSchema.title, refSchema.description]
|
|
177
184
|
.filter((item) => item)
|
|
178
|
-
.join(' ')
|
|
179
|
-
|
|
185
|
+
.join(' ');
|
|
186
|
+
// 格式化描述文本,让描述支持换行
|
|
187
|
+
refDesc = config_2.lineBreakReg.test(refDesc)
|
|
188
|
+
? '\n * ' + refDesc.split('\n').join('\n * ') + '\n'
|
|
189
|
+
: refDesc;
|
|
180
190
|
if (refDesc) {
|
|
181
191
|
desc = desc + refDesc;
|
|
182
192
|
}
|
|
@@ -237,7 +247,9 @@ function resolveRefObject(params) {
|
|
|
237
247
|
// 处理 OpenAPI 3.1 的 type 数组情况
|
|
238
248
|
if (Array.isArray(schemaObj.type)) {
|
|
239
249
|
// 如果是数组,使用第一个非 null 类型
|
|
240
|
-
resolvedType =
|
|
250
|
+
resolvedType =
|
|
251
|
+
schemaObj.type.find((t) => t !== 'null') ||
|
|
252
|
+
'string';
|
|
241
253
|
}
|
|
242
254
|
else {
|
|
243
255
|
resolvedType = schemaObj.type;
|
|
@@ -276,7 +288,7 @@ function getResponsesType(params) {
|
|
|
276
288
|
: description;
|
|
277
289
|
// 生成带注释的类型定义
|
|
278
290
|
return formattedDescription
|
|
279
|
-
? ` /**\n
|
|
291
|
+
? ` /**\n * ${formattedDescription}\n */\n ${statusCode}: ${lastType};`
|
|
280
292
|
: ` ${statusCode}: ${lastType};`;
|
|
281
293
|
});
|
|
282
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;
|
|
@@ -22,6 +29,11 @@ export declare function resolveRefs(obj: OpenAPIObject, fields: string[]): unkno
|
|
|
22
29
|
export declare function isAllNumeric(arr: any): boolean;
|
|
23
30
|
export declare function isAllNumber(arr: any): boolean;
|
|
24
31
|
export declare function capitalizeFirstLetter(str: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* 转义字符串,用于 JavaScript 字符串字面量
|
|
34
|
+
* 将换行符、单引号等特殊字符转义为转义序列
|
|
35
|
+
*/
|
|
36
|
+
export declare function escapeStringForJs(str: string): string;
|
|
25
37
|
export declare const parseDescriptionEnum: (description: string) => Map<number, string>;
|
|
26
38
|
/**
|
|
27
39
|
* 通过自定义正则表达式解析 description 中的枚举翻译
|
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;
|
|
@@ -23,6 +24,7 @@ exports.resolveRefs = resolveRefs;
|
|
|
23
24
|
exports.isAllNumeric = isAllNumeric;
|
|
24
25
|
exports.isAllNumber = isAllNumber;
|
|
25
26
|
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
27
|
+
exports.escapeStringForJs = escapeStringForJs;
|
|
26
28
|
const tslib_1 = require("tslib");
|
|
27
29
|
const lodash_1 = require("lodash");
|
|
28
30
|
const reserved_words_1 = tslib_1.__importDefault(require("reserved-words"));
|
|
@@ -83,13 +85,31 @@ function getRefName(refObject) {
|
|
|
83
85
|
}
|
|
84
86
|
return resolveTypeName(getLastRefName(refObject.$ref));
|
|
85
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* 获取引用类型名称,支持类型名称映射
|
|
90
|
+
* @param refObject 引用对象
|
|
91
|
+
* @param schemaKeyToTypeNameMap 从原始 schema key 到最终类型名称的映射(处理重名情况)
|
|
92
|
+
* @returns 最终的类型名称
|
|
93
|
+
*/
|
|
94
|
+
function getRefNameWithMapping(refObject, schemaKeyToTypeNameMap) {
|
|
95
|
+
if (!isReferenceObject(refObject)) {
|
|
96
|
+
return refObject;
|
|
97
|
+
}
|
|
98
|
+
const schemaKey = getLastRefName(refObject.$ref);
|
|
99
|
+
// 如果存在映射,使用映射后的类型名称
|
|
100
|
+
if (schemaKeyToTypeNameMap === null || schemaKeyToTypeNameMap === void 0 ? void 0 : schemaKeyToTypeNameMap.has(schemaKey)) {
|
|
101
|
+
return schemaKeyToTypeNameMap.get(schemaKey);
|
|
102
|
+
}
|
|
103
|
+
// 否则使用默认的类型名称解析
|
|
104
|
+
return resolveTypeName(schemaKey);
|
|
105
|
+
}
|
|
86
106
|
function getLastRefName(refPath = '') {
|
|
87
107
|
const refPaths = refPath.split('/');
|
|
88
108
|
return refPaths.length > 0
|
|
89
109
|
? decodeURIComponent(refPaths[refPaths.length - 1])
|
|
90
110
|
: '';
|
|
91
111
|
}
|
|
92
|
-
function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
112
|
+
function getDefaultType(schemaObject, namespace = '', schemas, schemaKeyToTypeNameMap) {
|
|
93
113
|
var _a, _b;
|
|
94
114
|
if ((0, lodash_1.isUndefined)(schemaObject) || (0, lodash_1.isNull)(schemaObject)) {
|
|
95
115
|
return 'unknown';
|
|
@@ -98,8 +118,9 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
98
118
|
return schemaObject;
|
|
99
119
|
}
|
|
100
120
|
if (isReferenceObject(schemaObject)) {
|
|
101
|
-
//
|
|
102
|
-
|
|
121
|
+
// 使用映射获取正确的类型名称(处理重名情况)
|
|
122
|
+
const refName = getRefNameWithMapping(schemaObject, schemaKeyToTypeNameMap);
|
|
123
|
+
return [namespace, refName].filter((s) => s).join('.');
|
|
103
124
|
}
|
|
104
125
|
let type = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.type;
|
|
105
126
|
const dateEnum = ['Date', 'date', 'dateTime', 'date-time', 'datetime'];
|
|
@@ -142,11 +163,11 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
142
163
|
}
|
|
143
164
|
if (Array.isArray(items)) {
|
|
144
165
|
const arrayItemType = items
|
|
145
|
-
.map((subType) => getDefaultType((subType.schema || subType), namespace))
|
|
166
|
+
.map((subType) => getDefaultType((subType.schema || subType), namespace, schemas, schemaKeyToTypeNameMap))
|
|
146
167
|
.toString();
|
|
147
168
|
return `[${arrayItemType}]`;
|
|
148
169
|
}
|
|
149
|
-
const arrayType = getDefaultType(items, namespace);
|
|
170
|
+
const arrayType = getDefaultType(items, namespace, schemas, schemaKeyToTypeNameMap);
|
|
150
171
|
return arrayType.includes(' | ') ? `(${arrayType})[]` : `${arrayType}[]`;
|
|
151
172
|
}
|
|
152
173
|
if (type === 'enum') {
|
|
@@ -158,12 +179,12 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
158
179
|
}
|
|
159
180
|
if (schemaObject.oneOf && schemaObject.oneOf.length) {
|
|
160
181
|
return schemaObject.oneOf
|
|
161
|
-
.map((item) => getDefaultType(item, namespace))
|
|
182
|
+
.map((item) => getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap))
|
|
162
183
|
.join(' | ');
|
|
163
184
|
}
|
|
164
185
|
if ((_a = schemaObject.anyOf) === null || _a === void 0 ? void 0 : _a.length) {
|
|
165
186
|
return schemaObject.anyOf
|
|
166
|
-
.map((item) => getDefaultType(item, namespace))
|
|
187
|
+
.map((item) => getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap))
|
|
167
188
|
.join(' | ');
|
|
168
189
|
}
|
|
169
190
|
if ((_b = schemaObject.allOf) === null || _b === void 0 ? void 0 : _b.length) {
|
|
@@ -173,17 +194,16 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
173
194
|
// 不使用 getRefName 函数处理,无法通过 schemas[schemaKey] 获取到schema
|
|
174
195
|
const schemaKey = getLastRefName(item.$ref);
|
|
175
196
|
if ((_a = schemas === null || schemas === void 0 ? void 0 : schemas[schemaKey]) === null || _a === void 0 ? void 0 : _a.enum) {
|
|
176
|
-
|
|
177
|
-
return getDefaultType(item, namespace);
|
|
197
|
+
return getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap);
|
|
178
198
|
}
|
|
179
199
|
}
|
|
180
|
-
return getDefaultType(item, namespace);
|
|
200
|
+
return getDefaultType(item, namespace, schemas, schemaKeyToTypeNameMap);
|
|
181
201
|
});
|
|
182
202
|
return `(${allofList.join(' & ')})`;
|
|
183
203
|
}
|
|
184
204
|
if (schemaObject.type === 'object' || schemaObject.properties) {
|
|
185
205
|
if ((0, lodash_1.isObject)(schemaObject.additionalProperties)) {
|
|
186
|
-
const type = getDefaultType(schemaObject.additionalProperties, namespace, schemas);
|
|
206
|
+
const type = getDefaultType(schemaObject.additionalProperties, namespace, schemas, schemaKeyToTypeNameMap);
|
|
187
207
|
return `Record<string, ${type}>`;
|
|
188
208
|
}
|
|
189
209
|
if (!(0, lodash_1.keys)(schemaObject.properties).length) {
|
|
@@ -211,7 +231,7 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
211
231
|
* 错误的继续保留字符串。
|
|
212
232
|
* */
|
|
213
233
|
return `
|
|
214
|
-
${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace)}; `;
|
|
234
|
+
${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace, schemas, schemaKeyToTypeNameMap)}; `;
|
|
215
235
|
})
|
|
216
236
|
.join('')}}`;
|
|
217
237
|
}
|
|
@@ -239,6 +259,8 @@ function findDuplicateTypeNames(arr) {
|
|
|
239
259
|
return duplicates;
|
|
240
260
|
}
|
|
241
261
|
function handleDuplicateTypeNames(interfaceTPConfigs) {
|
|
262
|
+
// 创建从原始 schema key 到最终类型名称的映射
|
|
263
|
+
const schemaKeyToTypeNameMap = new Map();
|
|
242
264
|
const duplicateTypeNames = findDuplicateTypeNames((0, lodash_1.map)(interfaceTPConfigs, (item) => item.typeName));
|
|
243
265
|
if (!(0, lodash_1.isEmpty)(duplicateTypeNames)) {
|
|
244
266
|
(0, lodash_1.forEach)(duplicateTypeNames, (typeName) => {
|
|
@@ -253,6 +275,13 @@ function handleDuplicateTypeNames(interfaceTPConfigs) {
|
|
|
253
275
|
});
|
|
254
276
|
});
|
|
255
277
|
}
|
|
278
|
+
// 建立映射关系(在处理重名之后)
|
|
279
|
+
(0, lodash_1.forEach)(interfaceTPConfigs, (interfaceTP) => {
|
|
280
|
+
if (interfaceTP.originalSchemaKey) {
|
|
281
|
+
schemaKeyToTypeNameMap.set(interfaceTP.originalSchemaKey, interfaceTP.typeName);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
return schemaKeyToTypeNameMap;
|
|
256
285
|
}
|
|
257
286
|
// 检测所有path重复区域(prefix)
|
|
258
287
|
function getBasePrefix(paths) {
|
|
@@ -372,6 +401,20 @@ function isAllNumber(arr) {
|
|
|
372
401
|
function capitalizeFirstLetter(str) {
|
|
373
402
|
return str.replace(/^[a-z]/, (match) => match.toUpperCase());
|
|
374
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* 转义字符串,用于 JavaScript 字符串字面量
|
|
406
|
+
* 将换行符、单引号等特殊字符转义为转义序列
|
|
407
|
+
*/
|
|
408
|
+
function escapeStringForJs(str) {
|
|
409
|
+
if (!str)
|
|
410
|
+
return str;
|
|
411
|
+
return str
|
|
412
|
+
.replace(/\\/g, '\\\\') // 先转义反斜杠
|
|
413
|
+
.replace(/'/g, "\\'") // 转义单引号
|
|
414
|
+
.replace(/\n/g, '\\n') // 转义换行符
|
|
415
|
+
.replace(/\r/g, '\\r') // 转义回车符
|
|
416
|
+
.replace(/\t/g, '\\t'); // 转义制表符
|
|
417
|
+
}
|
|
375
418
|
// 解析 description 中的枚举翻译
|
|
376
419
|
const parseDescriptionEnum = (description) => {
|
|
377
420
|
const enumMap = new Map();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-ts-request",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.5",
|
|
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",
|
|
@@ -23,7 +23,7 @@ import * as {{ namespace }} from './{{ interfaceFileName }}';
|
|
|
23
23
|
{%- if p["$ref"] and not p.name %}
|
|
24
24
|
display{{ p.type | safe }}(field as keyof {{ namespace }}.{{ p.type }})
|
|
25
25
|
{%- else %}
|
|
26
|
-
{{ p.name }}: '{{ p.desc if p.desc else p.name }}',
|
|
26
|
+
{{ p.name }}: '{{ (p.desc if p.desc else p.name) | escapeJs }}',
|
|
27
27
|
{%- endif %}
|
|
28
28
|
{%- endfor %}
|
|
29
29
|
{%- if prop.length > 1 %}
|