openapi-ts-request 1.1.1 → 1.2.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.
- package/README.md +3 -2
- package/dist/bin/openapi.js +2 -0
- package/dist/generator/serviceGenarator.js +21 -3
- package/dist/generator/util.d.ts +1 -0
- package/dist/generator/util.js +47 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/templates/displayEnumLabel.njk +1 -1
- package/templates/reactQuery.njk +2 -1
package/README.md
CHANGED
|
@@ -87,7 +87,6 @@ src/apis/pet.ts #接口文件
|
|
|
87
87
|
|
|
88
88
|
```typescript
|
|
89
89
|
// src/apis/pet.ts
|
|
90
|
-
|
|
91
90
|
/* eslint-disable */
|
|
92
91
|
// @ts-ignore
|
|
93
92
|
import request from 'axios';
|
|
@@ -205,6 +204,7 @@ $ openapi --help
|
|
|
205
204
|
--isTranslateToEnglishTag <boolean> translate chinese tag name to english tag name (default: false)
|
|
206
205
|
--isOnlyGenTypeScriptType <boolean> only generate typescript type (default: false)
|
|
207
206
|
--isCamelCase <boolean> camelCase naming of controller files and request client (default: true)
|
|
207
|
+
--isSupportParseEnumDesc <boolean> parse enum description to generate enum label (default: false)
|
|
208
208
|
-h, --help display help for command
|
|
209
209
|
```
|
|
210
210
|
|
|
@@ -241,6 +241,7 @@ openapi --i ./spec.json --o ./apis
|
|
|
241
241
|
| isTranslateToEnglishTag | 否 | boolean | false | 将中文 tag 名称翻译成英文 tag 名称 |
|
|
242
242
|
| isOnlyGenTypeScriptType | 否 | boolean | false | 仅生成 typescript 类型 |
|
|
243
243
|
| isCamelCase | 否 | boolean | true | 小驼峰命名文件和请求函数 |
|
|
244
|
+
| isSupportParseEnumDesc | 否 | boolean | false | 解析枚举描述生成枚举标签,格式参考:`系统用户角色:User(普通用户)=0,Agent(经纪人)=1,Admin(管理员)=2` |
|
|
244
245
|
| hook | 否 | [Custom Hook](#Custom-Hook) | - | 自定义 hook |
|
|
245
246
|
|
|
246
247
|
## 自定义 Hook
|
|
@@ -251,7 +252,7 @@ openapi --i ./spec.json --o ./apis
|
|
|
251
252
|
| customFunctionName | (data: APIDataType) => string | 自定义请求方法函数名称 |
|
|
252
253
|
| customTypeName | (data: APIDataType) => string | 自定义类型名称 |
|
|
253
254
|
| customClassName | (tagName: string) => string | 自定义标签名 |
|
|
254
|
-
| customType | (<br>schemaObject: SchemaObject \| ReferenceObject,<br>namespace: string,<br>originGetType:(schemaObject: SchemaObject \| ReferenceObject, namespace: string) => string,<br>) => string | 自定义类型 <br> _返回非字符串将使用默认方法获取type_ |
|
|
255
|
+
| customType | ({<br>schemaObject: SchemaObject \| ReferenceObject,<br>namespace: string,<br>originGetType:(schemaObject: SchemaObject \| ReferenceObject, namespace: string, schemas?: ComponentsObject['schemas']) => string,<br>schemas?: ComponentsObject['schemas'],<br>}) => string | 自定义类型 <br> _返回非字符串将使用默认方法获取type_ |
|
|
255
256
|
| customFileNames | (<br>operationObject: OperationObject,<br>apiPath: string,<br>apiMethod: string,<br>) => string[] | 自定义生成的请求客户端文件名称,可以返回多个文件名称的数组(表示生成多个文件). <br> _返回为空,则使用默认的方法获取_ |
|
|
256
257
|
|
|
257
258
|
## JSON Schemas
|
package/dist/bin/openapi.js
CHANGED
|
@@ -34,6 +34,7 @@ const params = commander_1.program
|
|
|
34
34
|
.option('--isTranslateToEnglishTag <boolean>', 'translate chinese tag name to english tag name', false)
|
|
35
35
|
.option('--isOnlyGenTypeScriptType <boolean>', 'only generate typescript type', false)
|
|
36
36
|
.option('--isCamelCase <boolean>', 'camelCase naming of controller files and request client', true)
|
|
37
|
+
.option('--isSupportParseEnumDesc <boolean>', 'parse enum description to generate enum label', false)
|
|
37
38
|
.parse(process.argv)
|
|
38
39
|
.opts();
|
|
39
40
|
function getPath(path) {
|
|
@@ -71,6 +72,7 @@ function run() {
|
|
|
71
72
|
isTranslateToEnglishTag: JSON.parse(params.isTranslateToEnglishTag) === true,
|
|
72
73
|
isOnlyGenTypeScriptType: JSON.parse(params.isOnlyGenTypeScriptType) === true,
|
|
73
74
|
isCamelCase: JSON.parse(params.isCamelCase) === true,
|
|
75
|
+
isSupportParseEnumDesc: JSON.parse(params.isSupportParseEnumDesc) === true,
|
|
74
76
|
};
|
|
75
77
|
yield (0, index_1.generateService)((0, lodash_1.pickBy)(options, (value) => value !== null && value !== undefined && value !== ''));
|
|
76
78
|
process.exit(0);
|
|
@@ -720,7 +720,16 @@ class ServiceGenerator {
|
|
|
720
720
|
let enumStr = '';
|
|
721
721
|
let enumLabelTypeStr = '';
|
|
722
722
|
if (config_2.numberEnum.includes(schemaObject.type) || (0, util_1.isAllNumber)(enumArray)) {
|
|
723
|
-
|
|
723
|
+
if (this.config.isSupportParseEnumDesc && schemaObject.description) {
|
|
724
|
+
const enumMap = (0, util_1.parseDescriptionEnum)(schemaObject.description);
|
|
725
|
+
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => {
|
|
726
|
+
const enumLabel = enumMap.get(Number(value));
|
|
727
|
+
return `${enumLabel}=${Number(value)}`;
|
|
728
|
+
}).join(',')}}`;
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"NUMBER_${value}"=${Number(value)}`).join(',')}}`;
|
|
732
|
+
}
|
|
724
733
|
}
|
|
725
734
|
else if ((0, util_1.isAllNumeric)(enumArray)) {
|
|
726
735
|
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"STRING_NUMBER_${value}"="${value}"`).join(',')}}`;
|
|
@@ -750,10 +759,19 @@ class ServiceGenerator {
|
|
|
750
759
|
}
|
|
751
760
|
else {
|
|
752
761
|
if (config_2.numberEnum.includes(schemaObject.type) || (0, util_1.isAllNumber)(enumArray)) {
|
|
753
|
-
|
|
762
|
+
if (this.config.isSupportParseEnumDesc && schemaObject.description) {
|
|
763
|
+
const enumMap = (0, util_1.parseDescriptionEnum)(schemaObject.description);
|
|
764
|
+
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => {
|
|
765
|
+
const enumLabel = enumMap.get(Number(value));
|
|
766
|
+
return `${Number(value)}:"${enumLabel}"`;
|
|
767
|
+
}).join(',')}}`;
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `${Number(value)}:"NUMBER_${value}"`).join(',')}}`;
|
|
771
|
+
}
|
|
754
772
|
}
|
|
755
773
|
else if ((0, util_1.isAllNumeric)(enumArray)) {
|
|
756
|
-
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"
|
|
774
|
+
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}":"STRING_NUMBER_${value}"`).join(',')}}`;
|
|
757
775
|
}
|
|
758
776
|
else {
|
|
759
777
|
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `${value}:"${value}"`).join(',')}}`;
|
package/dist/generator/util.d.ts
CHANGED
|
@@ -22,3 +22,4 @@ export declare function resolveRefs(obj: OpenAPIObject, fields: string[]): unkno
|
|
|
22
22
|
export declare function isAllNumeric(arr: any): boolean;
|
|
23
23
|
export declare function isAllNumber(arr: any): boolean;
|
|
24
24
|
export declare function capitalizeFirstLetter(str: string): string;
|
|
25
|
+
export declare const parseDescriptionEnum: (description: string) => Map<number, string>;
|
package/dist/generator/util.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseDescriptionEnum = void 0;
|
|
3
4
|
exports.stripDot = stripDot;
|
|
4
5
|
exports.resolveTypeName = resolveTypeName;
|
|
5
6
|
exports.getRefName = getRefName;
|
|
@@ -343,3 +344,49 @@ function isAllNumber(arr) {
|
|
|
343
344
|
function capitalizeFirstLetter(str) {
|
|
344
345
|
return str.replace(/^[a-z]/, (match) => match.toUpperCase());
|
|
345
346
|
}
|
|
347
|
+
// 解析 description 中的枚举翻译
|
|
348
|
+
const parseDescriptionEnum = (description) => {
|
|
349
|
+
const enumMap = new Map();
|
|
350
|
+
if (!description)
|
|
351
|
+
return enumMap;
|
|
352
|
+
// 首先处理可能的总体描述,例如 "系统用户角色:User=0,..."
|
|
353
|
+
let descToProcess = description;
|
|
354
|
+
const mainDescriptionMatch = description.match(/^([^:]+):(.*)/);
|
|
355
|
+
if (mainDescriptionMatch) {
|
|
356
|
+
// 如果有总体描述(如 "系统用户角色:"),只处理冒号后面的部分
|
|
357
|
+
descToProcess = mainDescriptionMatch[2];
|
|
358
|
+
}
|
|
359
|
+
// 匹配形如 "User(普通用户)=0" 或 "User=0" 的模式
|
|
360
|
+
const enumPattern = /([^():,=]+)(?:\(([^)]+)\))?=(\d+)/g;
|
|
361
|
+
let match;
|
|
362
|
+
while ((match = enumPattern.exec(descToProcess)) !== null) {
|
|
363
|
+
const name = match[1] ? match[1].trim() : '';
|
|
364
|
+
const valueStr = match[3] ? match[3].trim() : '';
|
|
365
|
+
if (valueStr && !isNaN(Number(valueStr))) {
|
|
366
|
+
// 统一使用英文key(如User)
|
|
367
|
+
enumMap.set(Number(valueStr), name);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// 如果没有匹配到任何枚举,尝试使用简单的分割方法作为后备
|
|
371
|
+
if (enumMap.size === 0) {
|
|
372
|
+
const pairs = descToProcess.split(',');
|
|
373
|
+
pairs.forEach((pair) => {
|
|
374
|
+
const parts = pair.split('=');
|
|
375
|
+
if (parts.length === 2) {
|
|
376
|
+
let label = parts[0].trim();
|
|
377
|
+
const value = parts[1].trim();
|
|
378
|
+
// 处理可能带有括号的情况
|
|
379
|
+
const bracketMatch = label.match(/([^(]+)\(([^)]+)\)/);
|
|
380
|
+
if (bracketMatch) {
|
|
381
|
+
// 只使用括号前的英文key
|
|
382
|
+
label = bracketMatch[1].trim();
|
|
383
|
+
}
|
|
384
|
+
if (label && value && !isNaN(Number(value))) {
|
|
385
|
+
enumMap.set(Number(value), label);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
return enumMap;
|
|
391
|
+
};
|
|
392
|
+
exports.parseDescriptionEnum = parseDescriptionEnum;
|
package/dist/index.d.ts
CHANGED
|
@@ -109,6 +109,10 @@ export type GenerateServiceProps = {
|
|
|
109
109
|
* 模板文件、请求函数采用小驼峰命名
|
|
110
110
|
*/
|
|
111
111
|
isCamelCase?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* 是否使用 description 中的枚举定义
|
|
114
|
+
*/
|
|
115
|
+
isSupportParseEnumDesc?: boolean;
|
|
112
116
|
/**
|
|
113
117
|
* 命名空间名称,默认为API,不需要关注
|
|
114
118
|
*/
|
|
@@ -135,17 +139,17 @@ export type GenerateServiceProps = {
|
|
|
135
139
|
* 自定义获取type hook
|
|
136
140
|
* 返回非字符串将使用默认方法获取type
|
|
137
141
|
* @example set number to string
|
|
138
|
-
* function customType(schemaObject,namespace){
|
|
142
|
+
* function customType({ schemaObject, namespace }){
|
|
139
143
|
* if(schemaObject.type==='number' && !schemaObject.format){
|
|
140
144
|
* return 'BigDecimalString';
|
|
141
145
|
* }
|
|
142
146
|
* }
|
|
143
147
|
*/
|
|
144
|
-
customType?: ({ schemaObject, namespace,
|
|
148
|
+
customType?: ({ schemaObject, namespace, originGetType, schemas, }: {
|
|
145
149
|
schemaObject: SchemaObject | ReferenceObject;
|
|
146
150
|
namespace: string;
|
|
151
|
+
originGetType: (schemaObject: SchemaObject, namespace: string, schemas?: ComponentsObject['schemas']) => string;
|
|
147
152
|
schemas?: ComponentsObject['schemas'];
|
|
148
|
-
originGetType: (schemaObject: SchemaObject, namespace: string) => string;
|
|
149
153
|
}) => string;
|
|
150
154
|
/**
|
|
151
155
|
* 自定义生成文件名,可返回多个,表示生成多个文件;
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ function generateService(_a) {
|
|
|
28
28
|
? [/.*/g]
|
|
29
29
|
: null, excludeTags: excludeTags
|
|
30
30
|
? (0, lodash_1.map)(excludeTags, (item) => typeof item === 'string' ? item.toLowerCase() : item)
|
|
31
|
-
: null, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', isGenReactQuery: false, reactQueryMode, isGenJavaScript: false, isDisplayTypeLabel: false, isGenJsonSchemas: false, nullable: false, isOnlyGenTypeScriptType: false, isCamelCase: true }, rest), openAPI);
|
|
31
|
+
: null, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', isGenReactQuery: false, reactQueryMode, isGenJavaScript: false, isDisplayTypeLabel: false, isGenJsonSchemas: false, nullable: false, isOnlyGenTypeScriptType: false, isCamelCase: true, isSupportParseEnumDesc: false }, rest), openAPI);
|
|
32
32
|
serviceGenerator.genFile();
|
|
33
33
|
if (mockFolder) {
|
|
34
34
|
(0, mockGenarator_1.mockGenerator)({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-ts-request",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.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",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"lint-staged": "^15.3.0",
|
|
69
69
|
"openapi-types": "^12.1.3",
|
|
70
70
|
"ts-node": "^10.9.2",
|
|
71
|
-
"typescript": "5.7.
|
|
71
|
+
"typescript": "5.7.3"
|
|
72
72
|
},
|
|
73
73
|
"keywords": [
|
|
74
74
|
"openapi",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as {{ namespace }} from './{{ interfaceFileName }}';
|
|
4
4
|
|
|
5
5
|
{% for type in list -%}
|
|
6
|
-
export function {{ type.displayLabelFuncName }}(field: {{ namespace }}.
|
|
6
|
+
export function {{ type.displayLabelFuncName }}(field: {{ namespace }}.{{ type.typeName }}) {
|
|
7
7
|
return ({{ type.enumLabelType }})[field]
|
|
8
8
|
}
|
|
9
9
|
|
package/templates/reactQuery.njk
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
import { queryOptions, useMutation } from '{{ reactQueryModePackageName }}';
|
|
6
6
|
{%- if genType === "ts" %}
|
|
7
7
|
import type { DefaultError } from '{{ reactQueryModePackageName }}';
|
|
8
|
-
{% endif
|
|
8
|
+
{% endif -%}
|
|
9
|
+
{{ requestImportStatement }}
|
|
9
10
|
|
|
10
11
|
import * as apis from './{{ className }}';
|
|
11
12
|
{%- if genType === "ts" %}
|