openapi-ts-request 1.3.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { GenerateServiceProps } from '../index';
|
|
2
2
|
import { OpenAPIObject } from '../type';
|
|
3
|
-
import { ControllerType, ISchemaItem, TagAPIDataType } from './type';
|
|
3
|
+
import { ControllerType, ISchemaItem, ITypeItem, TagAPIDataType } from './type';
|
|
4
4
|
export default class ServiceGenerator {
|
|
5
5
|
protected apiData: TagAPIDataType;
|
|
6
6
|
protected classNameList: ControllerType[];
|
|
7
7
|
protected config: GenerateServiceProps;
|
|
8
8
|
protected openAPIData: OpenAPIObject;
|
|
9
9
|
protected schemaList: ISchemaItem[];
|
|
10
|
+
protected interfaceTPConfigs: ITypeItem[];
|
|
10
11
|
constructor(config: GenerateServiceProps, openAPIData: OpenAPIObject);
|
|
11
12
|
genFile(): void;
|
|
12
13
|
private getInterfaceTPConfigs;
|
|
@@ -22,6 +22,7 @@ class ServiceGenerator {
|
|
|
22
22
|
this.apiData = {};
|
|
23
23
|
this.classNameList = [];
|
|
24
24
|
this.schemaList = [];
|
|
25
|
+
this.interfaceTPConfigs = [];
|
|
25
26
|
this.config = Object.assign({ templatesFolder: (0, path_1.join)(__dirname, '../../', 'templates') }, config);
|
|
26
27
|
this.generateInfoLog();
|
|
27
28
|
const includeTags = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.includeTags) || [];
|
|
@@ -148,37 +149,6 @@ class ServiceGenerator {
|
|
|
148
149
|
const isGenJavaScript = this.config.isGenJavaScript;
|
|
149
150
|
const reactQueryMode = this.config.reactQueryMode;
|
|
150
151
|
const reactQueryFileName = (0, config_2.displayReactQueryFileName)(reactQueryMode);
|
|
151
|
-
// 处理重复的 typeName
|
|
152
|
-
const interfaceTPConfigs = this.getInterfaceTPConfigs();
|
|
153
|
-
(0, util_2.handleDuplicateTypeNames)(interfaceTPConfigs);
|
|
154
|
-
// 生成 ts 类型声明
|
|
155
|
-
if (!isGenJavaScript) {
|
|
156
|
-
this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
|
|
157
|
-
nullable: this.config.nullable,
|
|
158
|
-
list: interfaceTPConfigs,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
// 生成枚举翻译
|
|
162
|
-
const enums = (0, lodash_1.filter)(interfaceTPConfigs, (item) => item.isEnum);
|
|
163
|
-
if (!isGenJavaScript && !isOnlyGenTypeScriptType && !(0, lodash_1.isEmpty)(enums)) {
|
|
164
|
-
this.genFileFromTemplate(`${config_2.displayEnumLabelFileName}.ts`, config_2.TypescriptFileType.displayEnumLabel, {
|
|
165
|
-
list: enums,
|
|
166
|
-
namespace: this.config.namespace,
|
|
167
|
-
interfaceFileName: config_2.interfaceFileName,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
const displayTypeLabels = (0, lodash_1.filter)(interfaceTPConfigs, (item) => !item.isEnum);
|
|
171
|
-
// 生成 type 翻译
|
|
172
|
-
if (!isGenJavaScript &&
|
|
173
|
-
!isOnlyGenTypeScriptType &&
|
|
174
|
-
this.config.isDisplayTypeLabel &&
|
|
175
|
-
!(0, lodash_1.isEmpty)(displayTypeLabels)) {
|
|
176
|
-
this.genFileFromTemplate(`${config_2.displayTypeLabelFileName}.ts`, config_2.TypescriptFileType.displayTypeLabel, {
|
|
177
|
-
list: displayTypeLabels,
|
|
178
|
-
namespace: this.config.namespace,
|
|
179
|
-
interfaceFileName: config_2.interfaceFileName,
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
152
|
if (!isOnlyGenTypeScriptType) {
|
|
183
153
|
const prettierError = [];
|
|
184
154
|
// 生成 service controller 文件
|
|
@@ -209,6 +179,37 @@ class ServiceGenerator {
|
|
|
209
179
|
(0, log_1.default)('🚥 格式化失败,请检查 service controller 文件内可能存在的语法错误');
|
|
210
180
|
}
|
|
211
181
|
}
|
|
182
|
+
// 处理重复的 typeName
|
|
183
|
+
this.interfaceTPConfigs = this.getInterfaceTPConfigs();
|
|
184
|
+
(0, util_2.handleDuplicateTypeNames)(this.interfaceTPConfigs);
|
|
185
|
+
// 生成 ts 类型声明
|
|
186
|
+
if (!isGenJavaScript) {
|
|
187
|
+
this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
|
|
188
|
+
nullable: this.config.nullable,
|
|
189
|
+
list: this.interfaceTPConfigs,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// 生成枚举翻译
|
|
193
|
+
const enums = (0, lodash_1.filter)(this.interfaceTPConfigs, (item) => item.isEnum);
|
|
194
|
+
if (!isGenJavaScript && !isOnlyGenTypeScriptType && !(0, lodash_1.isEmpty)(enums)) {
|
|
195
|
+
this.genFileFromTemplate(`${config_2.displayEnumLabelFileName}.ts`, config_2.TypescriptFileType.displayEnumLabel, {
|
|
196
|
+
list: enums,
|
|
197
|
+
namespace: this.config.namespace,
|
|
198
|
+
interfaceFileName: config_2.interfaceFileName,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const displayTypeLabels = (0, lodash_1.filter)(this.interfaceTPConfigs, (item) => !item.isEnum);
|
|
202
|
+
// 生成 type 翻译
|
|
203
|
+
if (!isGenJavaScript &&
|
|
204
|
+
!isOnlyGenTypeScriptType &&
|
|
205
|
+
this.config.isDisplayTypeLabel &&
|
|
206
|
+
!(0, lodash_1.isEmpty)(displayTypeLabels)) {
|
|
207
|
+
this.genFileFromTemplate(`${config_2.displayTypeLabelFileName}.ts`, config_2.TypescriptFileType.displayTypeLabel, {
|
|
208
|
+
list: displayTypeLabels,
|
|
209
|
+
namespace: this.config.namespace,
|
|
210
|
+
interfaceFileName: config_2.interfaceFileName,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
212
213
|
if (!isOnlyGenTypeScriptType &&
|
|
213
214
|
this.config.isGenJsonSchemas &&
|
|
214
215
|
!(0, lodash_1.isEmpty)(this.schemaList)) {
|
|
@@ -246,7 +247,7 @@ class ServiceGenerator {
|
|
|
246
247
|
getInterfaceTPConfigs() {
|
|
247
248
|
var _a, _b;
|
|
248
249
|
const schemas = (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas;
|
|
249
|
-
const lastTypes =
|
|
250
|
+
const lastTypes = this.interfaceTPConfigs;
|
|
250
251
|
const includeTags = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.includeTags) || [];
|
|
251
252
|
// 强行替换掉请求参数params的类型,生成方法对应的 xxxxParams 类型
|
|
252
253
|
(0, lodash_1.keys)(this.openAPIData.paths).forEach((pathKey) => {
|
|
@@ -386,6 +387,26 @@ class ServiceGenerator {
|
|
|
386
387
|
else if (functionName) {
|
|
387
388
|
tmpFunctionRD[functionName] = 1;
|
|
388
389
|
}
|
|
390
|
+
if (body === null || body === void 0 ? void 0 : body.isAnonymous) {
|
|
391
|
+
const bodyName = (0, lodash_1.upperFirst)(`${functionName}Body`);
|
|
392
|
+
this.interfaceTPConfigs.push({
|
|
393
|
+
typeName: bodyName,
|
|
394
|
+
type: body === null || body === void 0 ? void 0 : body.type,
|
|
395
|
+
isEnum: false,
|
|
396
|
+
props: [],
|
|
397
|
+
});
|
|
398
|
+
body.type = `${this.config.namespace}.${bodyName}`;
|
|
399
|
+
}
|
|
400
|
+
if (response === null || response === void 0 ? void 0 : response.isAnonymous) {
|
|
401
|
+
const responseName = (0, lodash_1.upperFirst)(`${functionName}Response`);
|
|
402
|
+
this.interfaceTPConfigs.push({
|
|
403
|
+
typeName: responseName,
|
|
404
|
+
type: response === null || response === void 0 ? void 0 : response.type,
|
|
405
|
+
isEnum: false,
|
|
406
|
+
props: [],
|
|
407
|
+
});
|
|
408
|
+
response.type = `${this.config.namespace}.${responseName}`;
|
|
409
|
+
}
|
|
389
410
|
let formattedPath = newApi.path.replace(/:([^/]*)|{([^}]*)}/gi, (_, str, str2) => `$\{${str || str2}}`);
|
|
390
411
|
// 为 path 中的 params 添加 alias
|
|
391
412
|
const escapedPathParams = (0, lodash_1.map)(params.path, (item, index) => (Object.assign(Object.assign({}, item), { alias: `param${index}` })));
|
|
@@ -566,31 +587,20 @@ class ServiceGenerator {
|
|
|
566
587
|
}
|
|
567
588
|
// 如果 requestBody 有 required 属性,则正常展示;如果没有,默认非必填
|
|
568
589
|
const required = typeof (requestBody === null || requestBody === void 0 ? void 0 : requestBody.required) === 'boolean' ? requestBody.required : false;
|
|
569
|
-
|
|
570
|
-
const propertiesList = (0, lodash_1.keys)(schema.properties)
|
|
571
|
-
.map((propertyKey) => {
|
|
572
|
-
var _a, _b;
|
|
573
|
-
const propertyObj = schema.properties[propertyKey];
|
|
574
|
-
if (propertyObj &&
|
|
575
|
-
![config_1.SchemaObjectFormat.binary, config_1.SchemaObjectFormat.base64].includes(propertyObj.format) &&
|
|
576
|
-
!(0, util_2.isBinaryArraySchemaObject)(propertyObj)) {
|
|
577
|
-
// 测试了很多用例,很少有用例走到这里
|
|
578
|
-
return {
|
|
579
|
-
key: propertyKey,
|
|
580
|
-
schema: Object.assign(Object.assign({}, propertyObj), { type: this.getType(propertyObj, this.config.namespace), required: (_b = (_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(propertyKey)) !== null && _b !== void 0 ? _b : false }),
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
return null;
|
|
584
|
-
})
|
|
585
|
-
.filter((p) => p);
|
|
586
|
-
return Object.assign(Object.assign({ mediaType }, schema), { required,
|
|
587
|
-
propertiesList });
|
|
588
|
-
}
|
|
589
|
-
return {
|
|
590
|
+
const bodySchema = {
|
|
590
591
|
mediaType,
|
|
591
592
|
required,
|
|
592
593
|
type: this.getType(schema, this.config.namespace),
|
|
594
|
+
isAnonymous: false,
|
|
593
595
|
};
|
|
596
|
+
// 具名 body 场景
|
|
597
|
+
if ((0, util_2.isReferenceObject)(schema)) {
|
|
598
|
+
bodySchema.type = `${this.config.namespace}.${bodySchema.type}`;
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
bodySchema.isAnonymous = true;
|
|
602
|
+
}
|
|
603
|
+
return bodySchema;
|
|
594
604
|
}
|
|
595
605
|
getFileTP(requestBody) {
|
|
596
606
|
var _a;
|
|
@@ -633,6 +643,7 @@ class ServiceGenerator {
|
|
|
633
643
|
const defaultResponse = {
|
|
634
644
|
mediaType: '*/*',
|
|
635
645
|
type: 'unknown',
|
|
646
|
+
isAnonymous: false,
|
|
636
647
|
};
|
|
637
648
|
if (!response) {
|
|
638
649
|
return defaultResponse;
|
|
@@ -647,6 +658,11 @@ class ServiceGenerator {
|
|
|
647
658
|
}
|
|
648
659
|
let schema = (resContent[mediaType].schema ||
|
|
649
660
|
config_2.DEFAULT_SCHEMA);
|
|
661
|
+
const responseSchema = {
|
|
662
|
+
mediaType,
|
|
663
|
+
type: 'unknown',
|
|
664
|
+
isAnonymous: false,
|
|
665
|
+
};
|
|
650
666
|
if ((0, util_2.isReferenceObject)(schema)) {
|
|
651
667
|
const refName = (0, util_2.getLastRefName)(schema.$ref);
|
|
652
668
|
const childrenSchema = components.schemas[refName];
|
|
@@ -657,6 +673,8 @@ class ServiceGenerator {
|
|
|
657
673
|
resContent[mediaType].schema ||
|
|
658
674
|
config_2.DEFAULT_SCHEMA);
|
|
659
675
|
}
|
|
676
|
+
responseSchema.type = `${this.config.namespace}.${this.getType(schema, this.config.namespace)}`;
|
|
677
|
+
return responseSchema;
|
|
660
678
|
}
|
|
661
679
|
if ((0, util_2.isSchemaObject)(schema)) {
|
|
662
680
|
(0, lodash_1.keys)(schema.properties).map((fieldName) => {
|
|
@@ -664,11 +682,10 @@ class ServiceGenerator {
|
|
|
664
682
|
schema.properties[fieldName]['required'] =
|
|
665
683
|
(_b = (_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(fieldName)) !== null && _b !== void 0 ? _b : false;
|
|
666
684
|
});
|
|
685
|
+
responseSchema.isAnonymous = true;
|
|
667
686
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
type: this.getType(schema, this.config.namespace),
|
|
671
|
-
};
|
|
687
|
+
responseSchema.type = this.getType(schema, this.config.namespace);
|
|
688
|
+
return responseSchema;
|
|
672
689
|
}
|
|
673
690
|
getParamsTP(parameters = [], path = null) {
|
|
674
691
|
const templateParams = {};
|
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'];
|
|
@@ -180,8 +181,9 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
180
181
|
}
|
|
181
182
|
return `{ ${(0, lodash_1.keys)(schemaObject.properties)
|
|
182
183
|
.map((key) => {
|
|
183
|
-
var _a
|
|
184
|
+
var _a;
|
|
184
185
|
let required = false;
|
|
186
|
+
const property = (((_a = schemaObject.properties) === null || _a === void 0 ? void 0 : _a[key]) || {});
|
|
185
187
|
if ((0, lodash_1.isBoolean)(schemaObject.required) && schemaObject.required) {
|
|
186
188
|
required = true;
|
|
187
189
|
}
|
|
@@ -189,8 +191,7 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
189
191
|
schemaObject.required.includes(key)) {
|
|
190
192
|
required = true;
|
|
191
193
|
}
|
|
192
|
-
if (
|
|
193
|
-
((_a = schemaObject.properties[key]) === null || _a === void 0 ? void 0 : _a.required)) {
|
|
194
|
+
if (property.required) {
|
|
194
195
|
required = true;
|
|
195
196
|
}
|
|
196
197
|
/**
|
|
@@ -199,18 +200,28 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
199
200
|
* 在后面进行格式化的时候会将正确的字符串转换为正常形式,
|
|
200
201
|
* 错误的继续保留字符串。
|
|
201
202
|
* */
|
|
202
|
-
return `
|
|
203
|
+
return `
|
|
204
|
+
${property.description ? `/** ${property.description} */\n` : ''}'${key}'${required ? '' : '?'}: ${getDefaultType(property, namespace)}; `;
|
|
203
205
|
})
|
|
204
206
|
.join('')}}`;
|
|
205
207
|
}
|
|
206
208
|
return 'unknown';
|
|
207
209
|
}
|
|
208
210
|
function getDefaultFileTag(operationObject, apiPath) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
211
|
+
let lastTags = [];
|
|
212
|
+
if (operationObject['x-swagger-router-controller']) {
|
|
213
|
+
lastTags = [operationObject['x-swagger-router-controller']];
|
|
214
|
+
}
|
|
215
|
+
else if (!(0, lodash_1.isEmpty)(operationObject.tags)) {
|
|
216
|
+
lastTags = operationObject.tags;
|
|
217
|
+
}
|
|
218
|
+
else if (operationObject.operationId) {
|
|
219
|
+
lastTags = [operationObject.operationId];
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
lastTags = [apiPath.replace('/', '').split('/')[1]];
|
|
223
|
+
}
|
|
224
|
+
return lastTags;
|
|
214
225
|
}
|
|
215
226
|
function findDuplicateTypeNames(arr) {
|
|
216
227
|
const counts = (0, lodash_1.countBy)(arr);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-ts-request",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Swagger2/OpenAPI3/Apifox to TypeScript/JavaScript, request client(support any client), request mock service, enum and enum translation, react-query/vue-query, type field label, JSON Schemas",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@types/lodash": "^4.17.5",
|
|
59
59
|
"@types/memoizee": "^0.4.11",
|
|
60
60
|
"@types/mockjs": "^1.0.10",
|
|
61
|
-
"@types/node": "^
|
|
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",
|
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
|
|