openapi-ts-request 0.12.1 → 0.13.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
@@ -4,13 +4,13 @@
4
4
 
5
5
  <a href="https://github.com/openapi-ui/openapi-ts-request/blob/master/README-en_US.md">English</a> | 简体中文
6
6
 
7
- 根据 [Swagger2/OpenAPI3](https://swagger.io/blog/news/whats-new-in-openapi-3-0/) 文档生成 TS 类型, 客户端请求函数, 模拟请求响应服务, 枚举, 类型字段翻译, JSON Schemas
7
+ 根据 [Swagger2/OpenAPI3/Apifox](https://swagger.io/blog/news/whats-new-in-openapi-3-0/) 文档生成 TS 类型, 客户端请求函数, 模拟请求响应服务, 枚举, 类型字段翻译, JSON Schemas
8
8
 
9
9
  文档:[使用手册](https://github.com/openapi-ui/openapi-ts-request/issues/100)
10
10
 
11
11
  ## 功能
12
12
 
13
- - 支持 Swagger2.0/OpenAPI 3.0,3.1 定义
13
+ - 支持 Swagger2.0/OpenAPI/Apifox 3.0,3.1 定义
14
14
  - 生成 TS 类型, 请求客户端, 请求模拟服务, 枚举, 类型字段翻译, JSON Schemas
15
15
  - 支持通过 npx、CLI、Nodejs 的方式使用
16
16
  - 支持自定义请求工具函数, 支持 Fetch、Axios、[UniApp-Request](https://github.com/openapi-ui/openapi-ts-request/issues/46)、Node.js、XHR 客户端
@@ -136,8 +136,13 @@ $ openapi --help
136
136
  -V, --version output the version number
137
137
  -i, --input <string> OpenAPI specification, can be a path, url (required)
138
138
  -o, --output <string> output directory (required)
139
- --requestLibPath <string> custom request lib path, for example: "@/request", "node-fetch", default is "axios"
140
- --allowedTags <string[]> generate code from allowed tags
139
+ --requestLibPath <string> custom request lib path, for example: "@/request", "node-fetch" (default: "axios")
140
+ --enableLogging <boolean> open the log (default: false)
141
+ --priorityRule <string> priority rule, include/exclude/both (default: "include")
142
+ --includeTags <(string|RegExp)[]> generate code from include tags
143
+ --includePaths <(string|RegExp)[]> generate code from include paths
144
+ --excludeTags <(string|RegExp)[]> generate code from exclude tags
145
+ --excludePaths <(string|RegExp)[]> generate code from exclude paths
141
146
  --requestOptionsType <string> custom request method options parameter type (default: "{ [key:
142
147
  string]: unknown }")
143
148
  --requestImportStatement <string> custom request import statement, for example: "const request =
@@ -146,7 +151,7 @@ $ openapi --help
146
151
  "'api'"(string)
147
152
  --isDisplayTypeLabel <boolean> generate label matching type field (default: false)
148
153
  --isGenJsonSchemas <boolean> generate JSON Schemas (default: false)
149
- --mockFolder <string> mock file path
154
+ --mockFolder <string> mock file path, for example: './mocks'
150
155
  --authorization <string> docs authorization
151
156
  --nullable <boolean> null instead of optional (default: false)
152
157
  --isTranslateToEnglishTag <boolean>translate chinese tag name to english tag name (default: false)
@@ -168,13 +173,18 @@ openapi --i ./spec.json --o ./apis
168
173
  | schemaPath | 是 | string | - | Swagger2/OpenAPI3 地址 |
169
174
  | serversPath | 否 | string | './src/apis' | 生成结果的文件夹路径 |
170
175
  | requestLibPath | 否 | string | 'axios' | 自定义请求方法路径,例如:'@/request'、'node-fetch' |
171
- | allowedTags | 否 | string[] | - | 根据指定的 tags 生成代码 |
176
+ | enableLogging | 否 | boolean | false | 是否开启日志 |
177
+ | priorityRule | 否 | string | 'include' | 模式规则,可选include/exclude/both |
178
+ | includeTags | 否 | (string\|RegExp)[] | - | 根据指定的 tags 生成代码, priorityRule=include则必填 |
179
+ | includePaths | 否 | (string\|RegExp)[] | - | 根据指定的 paths 生成代码 |
180
+ | excludeTags | 否 | (string\|RegExp)[] | - | 根据指定的 tags 不生成代码 |
181
+ | excludePaths | 否 | (string\|RegExp)[] | - | 根据指定的 paths 不生成代码 |
172
182
  | requestOptionsType | 否 | string | '{ [key: string]: unknown }' | 自定义请求方法 options 参数类型 |
173
183
  | requestImportStatement | 否 | string | - | 自定义请求方法表达式,例如:"const request = require('@/request')" |
174
184
  | apiPrefix | 否 | string | - | api path的前缀,例如:'api'(动态变量), "'api'"(字符串) |
175
185
  | isDisplayTypeLabel | 否 | boolean | false | 是否生成 type 对应的label |
176
186
  | isGenJsonSchemas | 否 | boolean | false | 是否生成 JSON Schemas |
177
- | mockFolder | 否 | string | './mocks' | mock文件路径 |
187
+ | mockFolder | 否 | string | - | mock文件路径,例如:'./mocks' |
178
188
  | authorization | 否 | string | - | 文档权限凭证 |
179
189
  | nullable | 否 | boolean | false | 使用 null 代替可选 |
180
190
  | isTranslateToEnglishTag | 否 | boolean | false | 将中文 tag 名称翻译成英文 tag 名称 |
@@ -12,8 +12,13 @@ const params = commander_1.program
12
12
  .version(pkg.version)
13
13
  .requiredOption('-i, --input <string>', 'OpenAPI specification, can be a path, url (required)')
14
14
  .requiredOption('-o, --output <string>', 'output directory (required)')
15
- .option('--requestLibPath <string>', 'custom request lib path, for example: "@/request", "node-fetch", default is "axios"')
16
- .option('--allowedTags <string[]>', 'generate results from allowed tags')
15
+ .option('--requestLibPath <string>', 'custom request lib path, for example: "@/request", "node-fetch" (default: "axios")')
16
+ .option('--enableLogging <boolean>', 'open the log', false)
17
+ .option('--priorityRule <string>', 'priority rule, include/exclude/both (default: "include")')
18
+ .option('--includeTags <(string|RegExp)[]>', 'generate code from include tags')
19
+ .option('--includePaths <(string|RegExp)[]>', 'generate code from include paths')
20
+ .option('--excludeTags <(string|RegExp)[]>', 'generate code from exclude tags')
21
+ .option('--excludePaths <(string|RegExp)[]>', 'generate code from exclude paths')
17
22
  .option('--requestOptionsType <string>', 'custom request method options parameter type (default: "{ [key: string]: unknown }")')
18
23
  .option('--requestImportStatement <string>', `custom request import statement, for example: "const request = require('@/request')"`)
19
24
  .option('--apiPrefix <string>', `custom the prefix of the api path, for example: "api"(variable), "'api'"(string)`)
@@ -43,7 +48,12 @@ function run() {
43
48
  schemaPath: input,
44
49
  serversPath: output,
45
50
  requestLibPath: params.requestLibPath,
46
- allowedTags: params.allowedTags,
51
+ enableLogging: JSON.parse(params.enableLogging) === true,
52
+ priorityRule: params.priorityRule,
53
+ includeTags: params.includeTags,
54
+ includePaths: params.includePaths,
55
+ excludeTags: params.excludeTags,
56
+ excludePaths: params.excludePaths,
47
57
  requestOptionsType: params.requestOptionsType,
48
58
  apiPrefix: params.apiPrefix,
49
59
  isDisplayTypeLabel: JSON.parse(params.isDisplayTypeLabel) === true,
@@ -29,4 +29,18 @@ export default class ServiceGenerator {
29
29
  private resolveAllOfObject;
30
30
  private getProps;
31
31
  private resolveRefObject;
32
+ log(message: string): void;
33
+ private generateInfoLog;
34
+ /**
35
+ * 校验规则
36
+ * @param regexp 正则数组
37
+ * @param data 数据
38
+ */
39
+ private validateRegexp;
40
+ /**
41
+ *
42
+ * @param item 数组数据
43
+ * @param reg 规则
44
+ */
45
+ private matches;
32
46
  }
@@ -4,6 +4,7 @@ const tslib_1 = require("tslib");
4
4
  const fs_1 = require("fs");
5
5
  const glob_1 = require("glob");
6
6
  const lodash_1 = require("lodash");
7
+ const minimatch_1 = require("minimatch");
7
8
  const nunjucks_1 = tslib_1.__importDefault(require("nunjucks"));
8
9
  const path_1 = require("path");
9
10
  const rimraf_1 = require("rimraf");
@@ -15,14 +16,19 @@ const patchSchema_1 = require("./patchSchema");
15
16
  const util_1 = require("./util");
16
17
  class ServiceGenerator {
17
18
  constructor(config, openAPIData) {
18
- var _a, _b;
19
+ var _a, _b, _c, _d, _e;
19
20
  this.apiData = {};
20
21
  this.classNameList = [];
21
22
  this.schemaList = [];
22
23
  this.finalPath = '';
23
24
  this.config = Object.assign({ templatesFolder: (0, path_1.join)(__dirname, '../../', 'templates') }, config);
24
- const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) || util_1.getDefaultFileTag;
25
- if ((_b = this.config.hook) === null || _b === void 0 ? void 0 : _b.afterOpenApiDataInited) {
25
+ this.generateInfoLog();
26
+ const includeTags = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.includeTags) || [];
27
+ const includePaths = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.includePaths) || [];
28
+ const excludeTags = ((_c = this.config) === null || _c === void 0 ? void 0 : _c.excludeTags) || [];
29
+ const excludePaths = ((_d = this.config) === null || _d === void 0 ? void 0 : _d.excludePaths) || [];
30
+ const priorityRule = type_1.PriorityRule[config.priorityRule];
31
+ if ((_e = this.config.hook) === null || _e === void 0 ? void 0 : _e.afterOpenApiDataInited) {
26
32
  this.openAPIData =
27
33
  this.config.hook.afterOpenApiDataInited(openAPIData) || openAPIData;
28
34
  }
@@ -30,23 +36,85 @@ class ServiceGenerator {
30
36
  this.openAPIData = openAPIData;
31
37
  }
32
38
  // 用 tag 分组 paths, { [tag]: [pathMap, pathMap] }
33
- (0, lodash_1.keys)(this.openAPIData.paths).forEach((pathKey) => {
39
+ outerLoop: for (const pathKey in this.openAPIData.paths) {
40
+ // 这里判断paths
41
+ switch (priorityRule) {
42
+ case type_1.PriorityRule.include: {
43
+ // includePaths and includeTags is empty, 直接跳过
44
+ if ((0, lodash_1.isEmpty)(includeTags) && (0, lodash_1.isEmpty)(includePaths)) {
45
+ this.log('priorityRule include need includeTags or includePaths');
46
+ break outerLoop;
47
+ }
48
+ if (!(0, lodash_1.isEmpty)(includePaths) &&
49
+ !this.validateRegexp(pathKey, includePaths)) {
50
+ continue;
51
+ }
52
+ break;
53
+ }
54
+ case type_1.PriorityRule.exclude: {
55
+ if (this.validateRegexp(pathKey, excludePaths)) {
56
+ continue;
57
+ }
58
+ break;
59
+ }
60
+ case type_1.PriorityRule.both: {
61
+ // includePaths and includeTags is empty,直接跳过
62
+ if ((0, lodash_1.isEmpty)(includeTags) && (0, lodash_1.isEmpty)(includePaths)) {
63
+ this.log('priorityRule both need includeTags or includePaths');
64
+ break outerLoop;
65
+ }
66
+ const outIncludePaths = !(0, lodash_1.isEmpty)(includePaths) &&
67
+ !this.validateRegexp(pathKey, includePaths);
68
+ const inExcludePaths = !(0, lodash_1.isEmpty)(excludePaths) &&
69
+ this.validateRegexp(pathKey, excludePaths);
70
+ if (outIncludePaths || inExcludePaths) {
71
+ continue;
72
+ }
73
+ break;
74
+ }
75
+ default:
76
+ throw new Error('priorityRule must be "include" or "exclude" or "include"');
77
+ }
34
78
  const pathItem = this.openAPIData.paths[pathKey];
35
79
  (0, lodash_1.forEach)(config_1.methods, (method) => {
80
+ var _a;
36
81
  const operationObject = pathItem[method];
37
82
  if (!operationObject) {
38
83
  return;
39
84
  }
40
- let tags = hookCustomFileNames(operationObject, pathKey, method);
41
- if (!tags) {
42
- tags = (0, util_1.getDefaultFileTag)(operationObject, pathKey);
43
- }
85
+ const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) || util_1.getDefaultFileTag;
86
+ const tags = hookCustomFileNames(operationObject, pathKey, method);
87
+ // 这里判断tags
44
88
  tags.forEach((tag) => {
45
- var _a;
46
- // 筛选出 tags 关联的paths
47
- if (!(0, lodash_1.isEmpty)((_a = this.config) === null || _a === void 0 ? void 0 : _a.allowedTags) &&
48
- !(0, lodash_1.includes)(this.config.allowedTags, tag.toLowerCase())) {
49
- return;
89
+ const tagLowerCase = tag.toLowerCase();
90
+ if (priorityRule === type_1.PriorityRule.include) {
91
+ // includeTags 为空,不会匹配任何path,故跳过
92
+ if ((0, lodash_1.isEmpty)(includeTags)) {
93
+ this.log('priorityRule include need includeTags or includePaths');
94
+ return;
95
+ }
96
+ if (!this.validateRegexp(tagLowerCase, includeTags)) {
97
+ return;
98
+ }
99
+ }
100
+ if (priorityRule === type_1.PriorityRule.exclude) {
101
+ if (this.validateRegexp(tagLowerCase, excludeTags)) {
102
+ return;
103
+ }
104
+ }
105
+ if (priorityRule === type_1.PriorityRule.both) {
106
+ // includeTags is empty 没有配置, 直接跳过
107
+ if ((0, lodash_1.isEmpty)(includeTags)) {
108
+ this.log('priorityRule both need includeTags or includePaths');
109
+ return;
110
+ }
111
+ const outIncludeTags = !(0, lodash_1.isEmpty)(includeTags) &&
112
+ !this.validateRegexp(tagLowerCase, includeTags);
113
+ const inExcludeTags = !(0, lodash_1.isEmpty)(excludeTags) &&
114
+ this.validateRegexp(tagLowerCase, excludeTags);
115
+ if (outIncludeTags || inExcludeTags) {
116
+ return;
117
+ }
50
118
  }
51
119
  const tagKey = this.config.isCamelCase
52
120
  ? (0, lodash_1.camelCase)((0, util_1.resolveTypeName)(tag))
@@ -57,7 +125,7 @@ class ServiceGenerator {
57
125
  this.apiData[tagKey].push(Object.assign({ path: pathKey, method }, operationObject));
58
126
  });
59
127
  });
60
- });
128
+ }
61
129
  }
62
130
  genFile() {
63
131
  try {
@@ -139,28 +207,30 @@ class ServiceGenerator {
139
207
  (0, log_1.default)('✅ 成功生成 api 文件');
140
208
  }
141
209
  getInterfaceTPConfigs() {
142
- var _a;
210
+ var _a, _b;
143
211
  const schemas = (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas;
144
212
  const lastTypes = [];
213
+ const includeTags = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.includeTags) || [];
145
214
  // 强行替换掉请求参数params的类型,生成方法对应的 xxxxParams 类型
146
215
  (0, lodash_1.keys)(this.openAPIData.paths).forEach((pathKey) => {
147
216
  const pathItem = this.openAPIData.paths[pathKey];
148
217
  (0, lodash_1.forEach)(config_1.methods, (method) => {
149
218
  var _a, _b, _c, _d;
150
219
  const operationObject = pathItem[method];
220
+ const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) || util_1.getDefaultFileTag;
151
221
  if (!operationObject) {
152
222
  return;
153
223
  }
154
- // 筛选出 pathItem 包含的 $ref 对应的schema
155
- if (!(0, lodash_1.isEmpty)((_a = this.config) === null || _a === void 0 ? void 0 : _a.allowedTags) &&
156
- !(0, lodash_1.isEmpty)(operationObject.tags)) {
157
- if (!(0, lodash_1.isEmpty)((0, lodash_1.intersection)(this.config.allowedTags, (0, lodash_1.map)(operationObject.tags, (tag) => tag.toLowerCase())))) {
158
- (0, util_1.markAllowedSchema)(JSON.stringify(pathItem), schemas);
159
- }
160
- else {
161
- return;
162
- }
224
+ const tags = hookCustomFileNames(operationObject, pathKey, method);
225
+ if ((0, lodash_1.isEmpty)(includeTags) || (!(0, lodash_1.isEmpty)(includeTags) && (0, lodash_1.isEmpty)(tags))) {
226
+ return;
227
+ }
228
+ const flag = this.validateRegexp((0, lodash_1.map)(tags, (tag) => tag.toLowerCase()), includeTags);
229
+ if (!flag) {
230
+ return;
163
231
  }
232
+ // 筛选出 pathItem 包含的 $ref 对应的schema
233
+ (0, util_1.markAllowedSchema)(JSON.stringify(pathItem), this.openAPIData);
164
234
  operationObject.parameters = (_b = operationObject.parameters) === null || _b === void 0 ? void 0 : _b.filter((item) => (item === null || item === void 0 ? void 0 : item.in) !== `${config_1.parametersInsEnum.header}`);
165
235
  const props = [];
166
236
  (_c = operationObject.parameters) === null || _c === void 0 ? void 0 : _c.forEach((parameter) => {
@@ -196,6 +266,10 @@ class ServiceGenerator {
196
266
  (0, lodash_1.keys)(schemas).forEach((schemaKey) => {
197
267
  var _a;
198
268
  const schema = schemas[schemaKey];
269
+ // 判断哪些 schema 需要添加进 type, schemas 渲染数组
270
+ if (!(schema === null || schema === void 0 ? void 0 : schema.isAllowed)) {
271
+ return;
272
+ }
199
273
  const result = this.resolveObject(schema);
200
274
  const getDefinesType = () => {
201
275
  if (result === null || result === void 0 ? void 0 : result.type) {
@@ -223,29 +297,25 @@ class ServiceGenerator {
223
297
  }
224
298
  });
225
299
  }
226
- // 判断哪些 schema 需要添加进 type, schemas 渲染数组
227
- if ((0, lodash_1.isEmpty)(this.config.allowedTags) ||
228
- (schema === null || schema === void 0 ? void 0 : schema.isAllowed)) {
229
- const isEnum = result.isEnum;
230
- const typeName = (0, util_1.resolveTypeName)(schemaKey);
231
- if (typeName) {
232
- lastTypes.push({
233
- typeName,
234
- type: getDefinesType(),
235
- props: (result.props || []),
236
- isEnum,
237
- displayLabelFuncName: isEnum
238
- ? (0, lodash_1.camelCase)(`display-${typeName}-Enum`)
239
- : '',
240
- enumLabelType: isEnum ? result.enumLabelType : '',
241
- });
242
- }
243
- if (this.config.isGenJsonSchemas) {
244
- this.schemaList.push({
245
- typeName: `$${(0, util_1.resolveTypeName)(schemaKey)}`,
246
- type: JSON.stringify((0, patchSchema_1.patchSchema)(schema, (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas)),
247
- });
248
- }
300
+ const isEnum = result.isEnum;
301
+ const typeName = (0, util_1.resolveTypeName)(schemaKey);
302
+ if (typeName) {
303
+ lastTypes.push({
304
+ typeName,
305
+ type: getDefinesType(),
306
+ props: (result.props || []),
307
+ isEnum,
308
+ displayLabelFuncName: isEnum
309
+ ? (0, lodash_1.camelCase)(`display-${typeName}-Enum`)
310
+ : '',
311
+ enumLabelType: isEnum ? result.enumLabelType : '',
312
+ });
313
+ }
314
+ if (this.config.isGenJsonSchemas) {
315
+ this.schemaList.push({
316
+ typeName: `$${(0, util_1.resolveTypeName)(schemaKey)}`,
317
+ type: JSON.stringify((0, patchSchema_1.patchSchema)(schema, (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas)),
318
+ });
249
319
  }
250
320
  });
251
321
  return lastTypes === null || lastTypes === void 0 ? void 0 : lastTypes.sort((a, b) => a.typeName.localeCompare(b.typeName)); // typeName排序
@@ -709,5 +779,58 @@ class ServiceGenerator {
709
779
  }
710
780
  return refObject;
711
781
  }
782
+ log(message) {
783
+ if (this.config.enableLogging) {
784
+ (0, log_1.default)(message);
785
+ }
786
+ }
787
+ generateInfoLog() {
788
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
789
+ this.log(`priorityRule: ${(_a = this.config) === null || _a === void 0 ? void 0 : _a.priorityRule}`);
790
+ if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.includeTags) {
791
+ this.log(`includeTags: ${(_c = this.config) === null || _c === void 0 ? void 0 : _c.includeTags.join(', ')}`);
792
+ }
793
+ if ((_d = this.config) === null || _d === void 0 ? void 0 : _d.excludeTags) {
794
+ this.log(`excludeTags: ${(_e = this.config) === null || _e === void 0 ? void 0 : _e.excludeTags.join(', ')}`);
795
+ }
796
+ if ((_f = this.config) === null || _f === void 0 ? void 0 : _f.includePaths) {
797
+ this.log(`includePaths: ${(_g = this.config) === null || _g === void 0 ? void 0 : _g.includePaths.join(', ')}`);
798
+ }
799
+ if ((_h = this.config) === null || _h === void 0 ? void 0 : _h.excludePaths) {
800
+ this.log(`excludePaths: ${(_j = this.config) === null || _j === void 0 ? void 0 : _j.excludePaths.join(', ')}`);
801
+ }
802
+ }
803
+ /**
804
+ * 校验规则
805
+ * @param regexp 正则数组
806
+ * @param data 数据
807
+ */
808
+ validateRegexp(data, regexp) {
809
+ // 确保 data 是数组
810
+ const dataArray = Array.isArray(data) ? data : [data];
811
+ this.log(`"Data Array:", ${dataArray.join(',')}`);
812
+ this.log(`"Regexp Array:", ${regexp.join(',')}`);
813
+ return dataArray.some((item) => {
814
+ const result = regexp.some((reg) => this.matches(item, reg));
815
+ this.log(`"Item:", ${item}, "Matches:", ${result}`);
816
+ return result;
817
+ });
818
+ }
819
+ /**
820
+ *
821
+ * @param item 数组数据
822
+ * @param reg 规则
823
+ */
824
+ // 提取匹配逻辑到单独的函数
825
+ matches(item, reg) {
826
+ if (typeof reg === 'string') {
827
+ return (0, minimatch_1.minimatch)(item, reg);
828
+ }
829
+ else if (reg instanceof RegExp) {
830
+ reg.lastIndex = 0; // 重置正则表达式的 lastIndex 属性
831
+ return reg.test(item);
832
+ }
833
+ return false; // 对于其他类型,返回 false
834
+ }
712
835
  }
713
836
  exports.default = ServiceGenerator;
@@ -12,7 +12,7 @@ export declare function genDefaultFunctionName(path: string, pathBasePrefix: str
12
12
  export declare function getFinalFileName(s: string): string;
13
13
  export declare function replaceDot(s: string): string;
14
14
  export declare function resolveFunctionName(functionName: string, methodName: string): string;
15
- export declare function markAllowedSchema(schemaStr: string, schemas: ComponentsObject['schemas']): void;
15
+ export declare function markAllowedSchema(schemaStr: string, openAPIData: OpenAPIObject): void;
16
16
  export declare function isReferenceObject(schema: unknown): schema is ReferenceObject;
17
17
  export declare function isSchemaObject(schema: unknown): schema is SchemaObject;
18
18
  export declare function isNonArraySchemaObject(schema: unknown): schema is NonArraySchemaObject;
@@ -287,13 +287,15 @@ function resolveFunctionName(functionName, methodName) {
287
287
  return functionName;
288
288
  }
289
289
  // 标记引用的 $ref 对应的schema
290
- function markAllowedSchema(schemaStr, schemas) {
291
- const refs = schemaStr === null || schemaStr === void 0 ? void 0 : schemaStr.match(/#\/components\/schemas\/([\w%«».-]+)/g);
290
+ function markAllowedSchema(schemaStr, openAPIData) {
291
+ const refs = (0, lodash_1.map)(schemaStr === null || schemaStr === void 0 ? void 0 : schemaStr.match(/"#\/components\/[^"]+"/g), (item) => item.slice(1, -1));
292
292
  (0, lodash_1.forEach)(refs, (ref) => {
293
- const schema = schemas === null || schemas === void 0 ? void 0 : schemas[getLastRefName(ref)];
293
+ // const schema = schemas?.[getLastRefName(ref)] as ICustomSchemaObject;
294
+ const refPaths = ref.split('/');
295
+ const schema = resolveRefs(openAPIData, refPaths.slice(1));
294
296
  if (schema && !schema.isAllowed) {
295
297
  schema.isAllowed = true;
296
- markAllowedSchema(JSON.stringify(schema), schemas);
298
+ markAllowedSchema(JSON.stringify(schema), openAPIData);
297
299
  }
298
300
  });
299
301
  }
package/dist/index.d.ts CHANGED
@@ -18,9 +18,30 @@ export type GenerateServiceProps = {
18
18
  */
19
19
  requestLibPath?: string;
20
20
  /**
21
- * 只解析归属于 tags 集合的api 和 schema
21
+ * 开启日志
22
22
  */
23
- allowedTags?: string[];
23
+ enableLogging?: boolean;
24
+ /**
25
+ /**
26
+ * 优先规则, include(只允许include列表) | exclude(只排除exclude列表) | both(允许include列表,排除exclude列表)
27
+ */
28
+ priorityRule?: string;
29
+ /**
30
+ * 只解析归属于 tags 集合的 api 和 schema
31
+ */
32
+ includeTags?: (string | RegExp)[];
33
+ /**
34
+ * 只解析归属于 paths 集合的 api
35
+ */
36
+ includePaths?: (string | RegExp)[];
37
+ /**
38
+ * 不解析归属于 tags 集合的 api 和 schema
39
+ */
40
+ excludeTags?: (string | RegExp)[];
41
+ /**
42
+ * 不解析归属于 paths 集合的 api
43
+ */
44
+ excludePaths?: (string | RegExp)[];
24
45
  /**
25
46
  * 自定义请求方法 options 参数类型
26
47
  */
@@ -143,4 +164,4 @@ export type GenerateServiceProps = {
143
164
  customFileNames?: (operationObject: OperationObject, apiPath: string, apiMethod: string) => string[] | null;
144
165
  };
145
166
  };
146
- export declare function generateService({ requestLibPath, schemaPath, mockFolder, allowedTags, authorization, isTranslateToEnglishTag, ...rest }: GenerateServiceProps): Promise<void>;
167
+ export declare function generateService({ requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, authorization, isTranslateToEnglishTag, priorityRule, ...rest }: GenerateServiceProps): Promise<void>;
package/dist/index.js CHANGED
@@ -5,11 +5,12 @@ const tslib_1 = require("tslib");
5
5
  const lodash_1 = require("lodash");
6
6
  const mockGenarator_1 = require("./generator/mockGenarator");
7
7
  const serviceGenarator_1 = tslib_1.__importDefault(require("./generator/serviceGenarator"));
8
+ const type_1 = require("./type");
8
9
  const util_1 = require("./util");
9
10
  tslib_1.__exportStar(require("./generator/patchSchema"), exports);
10
11
  function generateService(_a) {
11
12
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
12
- var { requestLibPath, schemaPath, mockFolder, allowedTags, authorization, isTranslateToEnglishTag } = _a, rest = tslib_1.__rest(_a, ["requestLibPath", "schemaPath", "mockFolder", "allowedTags", "authorization", "isTranslateToEnglishTag"]);
13
+ var { requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, authorization, isTranslateToEnglishTag, priorityRule = type_1.PriorityRule.include } = _a, rest = tslib_1.__rest(_a, ["requestLibPath", "schemaPath", "mockFolder", "includeTags", "excludeTags", "authorization", "isTranslateToEnglishTag", "priorityRule"]);
13
14
  if (!schemaPath) {
14
15
  return;
15
16
  }
@@ -21,9 +22,13 @@ function generateService(_a) {
21
22
  yield (0, util_1.translateChineseModuleNodeToEnglish)(openAPI);
22
23
  }
23
24
  const requestImportStatement = (0, util_1.getImportStatement)(requestLibPath);
24
- const serviceGenerator = new serviceGenarator_1.default(Object.assign({ schemaPath, serversPath: './src/apis', requestImportStatement, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', nullable: false, isCamelCase: true, isDisplayTypeLabel: false, isGenJsonSchemas: false, isOnlyGenTypeScriptType: false, allowedTags: allowedTags
25
- ? (0, lodash_1.map)(allowedTags, (item) => item.toLowerCase())
26
- : null }, rest), openAPI);
25
+ const serviceGenerator = new serviceGenarator_1.default(Object.assign({ schemaPath, serversPath: './src/apis', requestImportStatement, enableLogging: false, priorityRule, includeTags: includeTags
26
+ ? (0, lodash_1.map)(includeTags, (item) => typeof item === 'string' ? item.toLowerCase() : item)
27
+ : priorityRule === type_1.PriorityRule.include
28
+ ? [/.*/g]
29
+ : null, excludeTags: excludeTags
30
+ ? (0, lodash_1.map)(excludeTags, (item) => typeof item === 'string' ? item.toLowerCase() : item)
31
+ : null, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', nullable: false, isCamelCase: true, isDisplayTypeLabel: false, isGenJsonSchemas: false, isOnlyGenTypeScriptType: false }, rest), openAPI);
27
32
  serviceGenerator.genFile();
28
33
  if (mockFolder) {
29
34
  (0, mockGenarator_1.mockGenerator)({
package/dist/type.d.ts CHANGED
@@ -73,5 +73,16 @@ export declare enum SchemaObjectType {
73
73
  union = "union",
74
74
  file = "file"
75
75
  }
76
+ export declare enum PriorityRule {
77
+ include = "include",
78
+ exclude = "exclude",
79
+ both = "both"
80
+ }
81
+ export type GenerateRegExp = {
82
+ includeTags: (string | RegExp)[];
83
+ excludeTags: (string | RegExp)[];
84
+ includePaths: (string | RegExp)[];
85
+ excludePaths: (string | RegExp)[];
86
+ };
76
87
  export type ISchemaObjectType = keyof typeof SchemaObjectType;
77
88
  export {};
package/dist/type.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SchemaObjectType = exports.SchemaObjectFormat = void 0;
3
+ exports.PriorityRule = exports.SchemaObjectType = exports.SchemaObjectFormat = void 0;
4
4
  var SchemaObjectFormat;
5
5
  (function (SchemaObjectFormat) {
6
6
  SchemaObjectFormat["int32"] = "int32";
@@ -28,3 +28,9 @@ var SchemaObjectType;
28
28
  SchemaObjectType["union"] = "union";
29
29
  SchemaObjectType["file"] = "file";
30
30
  })(SchemaObjectType || (exports.SchemaObjectType = SchemaObjectType = {}));
31
+ var PriorityRule;
32
+ (function (PriorityRule) {
33
+ PriorityRule["include"] = "include";
34
+ PriorityRule["exclude"] = "exclude";
35
+ PriorityRule["both"] = "both";
36
+ })(PriorityRule || (exports.PriorityRule = PriorityRule = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-ts-request",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "Swagger2/OpenAPI3 to TypeScript, request client, request mock service, enum, type field label, JSON Schemas",
5
5
  "engines": {
6
6
  "node": ">=18.0.0",
@@ -36,6 +36,7 @@
36
36
  "js-yaml": "^4.1.0",
37
37
  "lodash": "^4.17.21",
38
38
  "memoizee": "^0.4.17",
39
+ "minimatch": "^10.0.1",
39
40
  "mockjs": "^1.1.0",
40
41
  "nunjucks": "^3.2.4",
41
42
  "prettier": "^3.3.2",
@@ -64,7 +65,8 @@
64
65
  "husky": "^9.0.11",
65
66
  "lint-staged": "^15.2.5",
66
67
  "openapi-types": "^12.1.3",
67
- "typescript": "5.6.3"
68
+ "ts-node": "^10.9.2",
69
+ "typescript": "5.7.2"
68
70
  },
69
71
  "keywords": [
70
72
  "openapi",