openapi-ts-request 1.10.0 → 1.11.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
@@ -186,7 +186,6 @@ $ openapi --help
186
186
  -o, --output <string> output directory
187
187
  -cfn, --configFileName <string> config file name
188
188
  -cfp, --configFilePath <string> config file path
189
- -u, --uniqueKey <string> unique key
190
189
  --requestLibPath <string> custom request lib path, for example: "@/request", "node-fetch" (default: "axios")
191
190
  -f, --full <boolean> full replacement (default: true)
192
191
  --enableLogging <boolean> open the log (default: false)
@@ -211,6 +210,7 @@ $ openapi --help
211
210
  --isOnlyGenTypeScriptType <boolean> only generate typescript type (default: false)
212
211
  --isCamelCase <boolean> camelCase naming of controller files and request client (default: true)
213
212
  --isSupportParseEnumDesc <boolean> parse enum description to generate enum label (default: false)
213
+ --supportParseEnumDescByReg <string> custom regex for parsing enum description
214
214
  -h, --help display help for command
215
215
  ```
216
216
 
@@ -252,6 +252,7 @@ openapi --i ./spec.json --o ./apis
252
252
  | isOnlyGenTypeScriptType | 否 | boolean | false | 仅生成 typescript 类型 |
253
253
  | isCamelCase | 否 | boolean | true | 小驼峰命名文件和请求函数 |
254
254
  | isSupportParseEnumDesc | 否 | boolean | false | 解析枚举描述生成枚举标签,格式参考:`系统用户角色:User(普通用户)=0,Agent(经纪人)=1,Admin(管理员)=2` |
255
+ | supportParseEnumDescByReg | 否 | string \| RegExp | - | 自定义正则表达式,用于解析 description 中的枚举定义。如果设置了此参数,将使用此正则表达式替代默认的 parseDescriptionEnum 方法。例如:`/([^\s=<>/&;]+(?:\s+[^\s=<>/&;]+)*)\s*=\s*(\d+)/g` 可以匹配 "普通 = 0" 或 "SampleMaker = 1" 这样的格式 |
255
256
  | binaryMediaTypes | 否 | string[] | - | 自定义二进制媒体类型列表,默认包含:['application/octet-stream', 'application/pdf', 'image/*', 'video/*', 'audio/*'] |
256
257
  | hook | 否 | [Custom Hook](#Custom-Hook) | - | 自定义 hook |
257
258
 
package/dist/bin/cli.js CHANGED
@@ -9,14 +9,12 @@ const log_1 = require("../log");
9
9
  const readConfig_1 = require("../readConfig");
10
10
  commander_1.program
11
11
  .option('-cfn, --configFileName <string>', 'config file name')
12
- .option('-cfp, --configFilePath <string>', 'config file path')
13
- .option('-u, --uniqueKey <string>', 'unique key');
12
+ .option('-cfp, --configFilePath <string>', 'config file path');
14
13
  commander_1.program.parse();
15
14
  const options = commander_1.program.opts();
16
15
  /**
17
16
  * 1. 执行 cli 命令读取配置文件,已经使用 openapi.ts 替代了 cli.ts,后期会废弃 cli.ts
18
- * 2. 如果配置文件中有 uniqueKey,则根据 uniqueKey 生成 service
19
- * 3. 如果配置文件中没有 uniqueKey,且有多个 service,则交互式选择要生成的 service
17
+ * 2. 如果配置文件有多个 service,则交互式选择要生成的 service
20
18
  */
21
19
  function run() {
22
20
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -33,11 +31,8 @@ function run() {
33
31
  : [config];
34
32
  /** 是否交互式 */
35
33
  let isInteractive = false;
36
- if (options.uniqueKey) {
37
- configs = configs.filter((config) => config.uniqueKey === options.uniqueKey);
38
- }
39
- else if (configs.length > 1) {
40
- // 如果没有指定 uniqueKey,并且有多个配置,则交互式选择
34
+ if (configs.length > 1) {
35
+ // 有多个配置,则交互式选择
41
36
  isInteractive = true;
42
37
  console.log(''); // 添加一个空行
43
38
  (0, prompts_1.intro)('🎉 欢迎使用 openapi-ts-request 生成器');
@@ -63,7 +58,8 @@ function run() {
63
58
  const result = results[i];
64
59
  if (result.status === 'rejected') {
65
60
  const cnf = configs[i];
66
- errorMsg += `${cnf.uniqueKey}${cnf.uniqueKey && ':'}${result.reason}\n`;
61
+ const label = cnf.describe || cnf.schemaPath;
62
+ errorMsg += `${label}${label && ':'}${result.reason}\n`;
67
63
  }
68
64
  }
69
65
  if (errorMsg) {
@@ -18,7 +18,6 @@ const params = commander_1.program
18
18
  .option('-o, --output <string>', 'output directory')
19
19
  .option('-cfn, --configFileName <string>', 'config file name')
20
20
  .option('-cfp, --configFilePath <string>', 'config file path')
21
- .option('-u, --uniqueKey <string>', 'unique key')
22
21
  .option('--requestLibPath <string>', 'custom request lib path, for example: "@/request", "node-fetch" (default: "axios")')
23
22
  .option('-f, --full <boolean>', 'full replacement', true)
24
23
  .option('--enableLogging <boolean>', 'open the log', false)
@@ -43,6 +42,7 @@ const params = commander_1.program
43
42
  .option('--isOnlyGenTypeScriptType <boolean>', 'only generate typescript type', false)
44
43
  .option('--isCamelCase <boolean>', 'camelCase naming of controller files and request client', true)
45
44
  .option('--isSupportParseEnumDesc <boolean>', 'parse enum description to generate enum label', false)
45
+ .option('--supportParseEnumDescByReg <string>', 'custom regex for parsing enum description')
46
46
  .parse(process.argv)
47
47
  .opts();
48
48
  function getPath(path) {
@@ -81,6 +81,7 @@ const baseGenerate = (_params_) => {
81
81
  isOnlyGenTypeScriptType: JSON.parse(_params_.isOnlyGenTypeScriptType) === true,
82
82
  isCamelCase: JSON.parse(_params_.isCamelCase) === true,
83
83
  isSupportParseEnumDesc: JSON.parse(_params_.isSupportParseEnumDesc) === true,
84
+ supportParseEnumDescByReg: _params_.supportParseEnumDescByReg,
84
85
  };
85
86
  return options;
86
87
  };
@@ -102,11 +103,8 @@ function run() {
102
103
  let configs = Array.isArray(cnf) ? cnf : [cnf];
103
104
  /** 是否交互式 */
104
105
  let isInteractive = false;
105
- if (params.uniqueKey) {
106
- configs = configs.filter((config) => config.uniqueKey === params.uniqueKey);
107
- }
108
- else if (configs.length > 1) {
109
- // 如果没有指定 uniqueKey,并且有多个配置,则交互式选择
106
+ if (configs.length > 1) {
107
+ // 有多个配置,则交互式选择
110
108
  isInteractive = true;
111
109
  console.log(''); // 添加一个空行
112
110
  (0, prompts_1.intro)('🎉 欢迎使用 openapi-ts-request 生成器');
@@ -132,7 +130,8 @@ function run() {
132
130
  const result = results[i];
133
131
  if (result.status === 'rejected') {
134
132
  const cnf = configs[i];
135
- errorMsg += `${cnf.uniqueKey}${cnf.uniqueKey && ':'}${result.reason}\n`;
133
+ const label = cnf.describe || cnf.schemaPath;
134
+ errorMsg += `${label}${label && ':'}${result.reason}\n`;
136
135
  }
137
136
  }
138
137
  if (errorMsg) {
@@ -1032,8 +1032,12 @@ class ServiceGenerator {
1032
1032
  }
1033
1033
  else {
1034
1034
  if (config_2.numberEnum.includes(schemaObject.type) || (0, util_2.isAllNumber)(enumArray)) {
1035
- if (this.config.isSupportParseEnumDesc && schemaObject.description) {
1036
- const enumMap = (0, util_2.parseDescriptionEnum)(schemaObject.description);
1035
+ if ((this.config.isSupportParseEnumDesc ||
1036
+ this.config.supportParseEnumDescByReg) &&
1037
+ schemaObject.description) {
1038
+ const enumMap = this.config.isSupportParseEnumDesc
1039
+ ? (0, util_2.parseDescriptionEnum)(schemaObject.description)
1040
+ : (0, util_2.parseDescriptionEnumByReg)(schemaObject.description, this.config.supportParseEnumDescByReg);
1037
1041
  enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => {
1038
1042
  const enumLabel = enumMap.get(Number(value));
1039
1043
  return `${Number(value)}:"${enumLabel}"`;
@@ -23,6 +23,13 @@ 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
25
  export declare const parseDescriptionEnum: (description: string) => Map<number, string>;
26
+ /**
27
+ * 通过自定义正则表达式解析 description 中的枚举翻译
28
+ * @param description 描述文本
29
+ * @param regex 自定义正则表达式,用于匹配枚举项,例如:(\S+)\s*=\s*(\S+)
30
+ * @returns Map<number, string> 枚举值到标签的映射
31
+ */
32
+ export declare const parseDescriptionEnumByReg: (description: string, regex: string | RegExp) => Map<number, string>;
26
33
  /**
27
34
  * 获取默认的二进制媒体类型列表
28
35
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAxiosResponseType = exports.getBinaryResponseType = exports.isBinaryMediaType = exports.getBinaryMediaTypes = exports.getDefaultBinaryMediaTypes = exports.parseDescriptionEnum = void 0;
3
+ exports.getAxiosResponseType = exports.getBinaryResponseType = exports.isBinaryMediaType = exports.getBinaryMediaTypes = exports.getDefaultBinaryMediaTypes = exports.parseDescriptionEnumByReg = exports.parseDescriptionEnum = void 0;
4
4
  exports.stripDot = stripDot;
5
5
  exports.resolveTypeName = resolveTypeName;
6
6
  exports.getRefName = getRefName;
@@ -408,6 +408,54 @@ const parseDescriptionEnum = (description) => {
408
408
  return enumMap;
409
409
  };
410
410
  exports.parseDescriptionEnum = parseDescriptionEnum;
411
+ /**
412
+ * 通过自定义正则表达式解析 description 中的枚举翻译
413
+ * @param description 描述文本
414
+ * @param regex 自定义正则表达式,用于匹配枚举项,例如:(\S+)\s*=\s*(\S+)
415
+ * @returns Map<number, string> 枚举值到标签的映射
416
+ */
417
+ const parseDescriptionEnumByReg = (description, regex) => {
418
+ const enumMap = new Map();
419
+ if (!description)
420
+ return enumMap;
421
+ // 将字符串正则转换为 RegExp 对象,确保有全局标志
422
+ let regExp;
423
+ if (typeof regex === 'string') {
424
+ const flagsMatch = regex.match(/\/([gimsuy]*)$/);
425
+ if (flagsMatch) {
426
+ const parts = regex.split('/');
427
+ const pattern = parts.slice(1, -1).join('/');
428
+ const flags = flagsMatch[1] || '';
429
+ regExp = new RegExp(pattern, flags.includes('g') ? flags : flags + 'g');
430
+ }
431
+ else {
432
+ regExp = new RegExp(regex, 'g');
433
+ }
434
+ }
435
+ else {
436
+ const flags = regex.flags;
437
+ regExp = flags.includes('g')
438
+ ? regex
439
+ : new RegExp(regex.source, flags + 'g');
440
+ }
441
+ // 匹配所有结果,然后对每个匹配结果按 = 拆分
442
+ let match;
443
+ while ((match = regExp.exec(description)) !== null) {
444
+ const fullMatch = match[0].trim();
445
+ // 按 = 拆分,左边是标签,右边是值
446
+ const parts = fullMatch.split(/\s*=\s*/);
447
+ if (parts.length >= 2) {
448
+ const label = parts[0].trim();
449
+ const valueStr = parts[1].trim();
450
+ const numValue = Number(valueStr);
451
+ if (label && valueStr && !isNaN(numValue)) {
452
+ enumMap.set(numValue, label);
453
+ }
454
+ }
455
+ }
456
+ return enumMap;
457
+ };
458
+ exports.parseDescriptionEnumByReg = parseDescriptionEnumByReg;
411
459
  /**
412
460
  * 获取默认的二进制媒体类型列表
413
461
  */
package/dist/index.d.ts CHANGED
@@ -131,6 +131,12 @@ export type GenerateServiceProps = {
131
131
  * 是否使用 description 中的枚举定义
132
132
  */
133
133
  isSupportParseEnumDesc?: boolean;
134
+ /**
135
+ * 自定义正则表达式,用于解析 description 中的枚举定义
136
+ * 如果设置了此参数,将使用此正则表达式替代默认的 parseDescriptionEnum 方法
137
+ * 例如:/([^\s=<>/&;]+(?:\s+[^\s=<>/&;]+)*)\s*=\s*(\d+)/g 可以匹配 "普通 = 0" 或 "SampleMaker = 1" 这样的格式
138
+ */
139
+ supportParseEnumDescByReg?: string | RegExp;
134
140
  /**
135
141
  * 命名空间名称,默认为API,不需要关注
136
142
  */
@@ -143,10 +149,6 @@ export type GenerateServiceProps = {
143
149
  * 请求超时时间
144
150
  */
145
151
  timeout?: number;
146
- /**
147
- * 多网关唯一标识
148
- */
149
- uniqueKey?: string;
150
152
  /**
151
153
  * 自定义二进制媒体类型列表
152
154
  * 默认包含: ['application/octet-stream', 'application/pdf', 'image/*', 'video/*', 'audio/*']
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-ts-request",
3
- "version": "1.10.0",
3
+ "version": "1.11.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",
@@ -59,7 +59,7 @@
59
59
  "@types/lodash": "^4.17.5",
60
60
  "@types/memoizee": "^0.4.11",
61
61
  "@types/mockjs": "^1.0.10",
62
- "@types/node": "^24.0.14",
62
+ "@types/node": "^25.0.1",
63
63
  "@types/nunjucks": "^3.2.6",
64
64
  "@types/reserved-words": "^0.1.4",
65
65
  "@types/swagger2openapi": "^7.0.4",