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) ||
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
669
|
-
|
|
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 = {};
|
package/dist/generator/util.js
CHANGED
|
@@ -98,7 +98,8 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
98
98
|
return schemaObject;
|
|
99
99
|
}
|
|
100
100
|
if (isReferenceObject(schemaObject)) {
|
|
101
|
-
return
|
|
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.
|
|
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.
|
|
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": "^
|
|
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": "^
|
|
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"
|
package/templates/reactQuery.njk
CHANGED
|
@@ -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
|
|