openapi-ts-request 1.1.2 → 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 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
@@ -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
- enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"NUMBER_${value}"=${Number(value)}`).join(',')}}`;
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
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"NUMBER_${value}":${Number(value)}`).join(',')}}`;
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) => `"STRING_NUMBER_${value}":"${value}"`).join(',')}}`;
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(',')}}`;
@@ -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>;
@@ -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, schemas, originGetType, }: {
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.1.2",
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.2"
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 }}.I{{ type.typeName }}) {
6
+ export function {{ type.displayLabelFuncName }}(field: {{ namespace }}.{{ type.typeName }}) {
7
7
  return ({{ type.enumLabelType }})[field]
8
8
  }
9
9