openapi-ts-request 1.11.0 → 1.12.1

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.
@@ -15,6 +15,7 @@ const config_2 = require("./config");
15
15
  const file_1 = require("./file");
16
16
  const merge_1 = require("./merge");
17
17
  const patchSchema_1 = require("./patchSchema");
18
+ const Helper = tslib_1.__importStar(require("./serviceGeneratorHelper"));
18
19
  const util_2 = require("./util");
19
20
  class ServiceGenerator {
20
21
  constructor(config, openAPIData) {
@@ -23,6 +24,8 @@ class ServiceGenerator {
23
24
  this.classNameList = [];
24
25
  this.schemaList = [];
25
26
  this.interfaceTPConfigs = [];
27
+ // 记录每个类型被哪些模块使用(用于拆分类型文件)
28
+ this.typeModuleMap = new Map();
26
29
  this.config = Object.assign({ templatesFolder: (0, path_1.join)(__dirname, '../../', 'templates') }, config);
27
30
  this.generateInfoLog();
28
31
  const includeTags = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.includeTags) || [];
@@ -183,10 +186,56 @@ class ServiceGenerator {
183
186
  (0, util_2.handleDuplicateTypeNames)(this.interfaceTPConfigs);
184
187
  // 生成 ts 类型声明
185
188
  if (!isGenJavaScript) {
186
- this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
187
- nullable: this.config.nullable,
188
- list: this.interfaceTPConfigs,
189
- });
189
+ if (this.config.isSplitTypesByModule) {
190
+ // 按模块拆分类型文件
191
+ const { moduleTypes, commonTypes, enumTypes } = this.groupTypesByModule();
192
+ // 生成枚举文件
193
+ if (enumTypes.length > 0) {
194
+ this.genFileFromTemplate(`${config_2.enumFileName}.ts`, config_2.TypescriptFileType.enum, {
195
+ list: enumTypes,
196
+ });
197
+ }
198
+ // 生成公共类型文件
199
+ if (commonTypes.length > 0) {
200
+ // 分析公共类型需要导入的枚举
201
+ const { enumImports } = this.getModuleImports(commonTypes, [], // 公共类型不依赖其他公共类型
202
+ enumTypes);
203
+ this.genFileFromTemplate(`${config_2.commonTypeFileName}.ts`, config_2.TypescriptFileType.moduleType, {
204
+ nullable: this.config.nullable,
205
+ list: commonTypes,
206
+ enumImports, // 公共类型需要导入的枚举
207
+ });
208
+ }
209
+ // 生成每个模块的类型文件
210
+ moduleTypes.forEach((types, moduleName) => {
211
+ if (types.length > 0) {
212
+ // 分析该模块需要导入哪些类型
213
+ const { commonImports, enumImports } = this.getModuleImports(types, commonTypes, enumTypes);
214
+ this.genFileFromTemplate(`${moduleName}.type.ts`, config_2.TypescriptFileType.moduleType, {
215
+ nullable: this.config.nullable,
216
+ list: types,
217
+ commonImports, // 需要导入的公共类型
218
+ enumImports, // 需要导入的枚举类型
219
+ });
220
+ }
221
+ });
222
+ // 生成 types.ts 作为统一导出入口
223
+ this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.typeIndex, {
224
+ hasEnumTypes: enumTypes.length > 0,
225
+ hasCommonTypes: commonTypes.length > 0,
226
+ moduleList: Array.from(moduleTypes.keys()).filter((moduleName) => {
227
+ const types = moduleTypes.get(moduleName);
228
+ return types ? types.length > 0 : false;
229
+ }),
230
+ });
231
+ }
232
+ else {
233
+ // 传统方式:所有类型在一个文件
234
+ this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
235
+ nullable: this.config.nullable,
236
+ list: this.interfaceTPConfigs,
237
+ });
238
+ }
190
239
  }
191
240
  // 生成枚举翻译
192
241
  const enums = (0, lodash_1.filter)(this.interfaceTPConfigs, (item) => item.isEnum);
@@ -257,6 +306,8 @@ class ServiceGenerator {
257
306
  const lastTypes = this.interfaceTPConfigs;
258
307
  const includeTags = ((_b = this.config) === null || _b === void 0 ? void 0 : _b.includeTags) || [];
259
308
  const includePaths = ((_c = this.config) === null || _c === void 0 ? void 0 : _c.includePaths) || [];
309
+ // 记录每个 schema 被哪些模块使用(用于拆分类型)
310
+ const schemaUsageMap = new Map();
260
311
  // 强行替换掉请求参数params的类型,生成方法对应的 xxxxParams 类型
261
312
  (0, lodash_1.keys)(this.openAPIData.paths).forEach((pathKey) => {
262
313
  const pathItem = this.openAPIData.paths[pathKey];
@@ -280,6 +331,36 @@ class ServiceGenerator {
280
331
  }
281
332
  // 筛选出 pathItem 包含的 $ref 对应的schema
282
333
  (0, util_2.markAllowedSchema)(JSON.stringify(pathItem), this.openAPIData);
334
+ // 如果启用了类型拆分,记录每个 schema 被哪些模块使用
335
+ if (this.config.isSplitTypesByModule) {
336
+ const pathItemStr = JSON.stringify(pathItem);
337
+ const refRegex = /"\$ref":\s*"#\/components\/schemas\/([^"]+)"/g;
338
+ let match;
339
+ while ((match = refRegex.exec(pathItemStr)) !== null) {
340
+ const schemaName = match[1];
341
+ if (!schemaName)
342
+ continue;
343
+ tags.forEach((tag) => {
344
+ var _a;
345
+ if (tag) {
346
+ const tagTypeName = (0, util_2.resolveTypeName)(tag);
347
+ const tagKey = this.config.isCamelCase
348
+ ? (0, util_1.camelCase)(tagTypeName)
349
+ : (0, lodash_1.lowerFirst)(tagTypeName);
350
+ const className = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customClassName)
351
+ ? this.config.hook.customClassName(tag)
352
+ : (0, util_2.replaceDot)(tagKey);
353
+ if (!schemaUsageMap.has(schemaName)) {
354
+ schemaUsageMap.set(schemaName, new Set());
355
+ }
356
+ const moduleSet = schemaUsageMap.get(schemaName);
357
+ if (moduleSet) {
358
+ moduleSet.add(className);
359
+ }
360
+ }
361
+ });
362
+ }
363
+ }
283
364
  operationObject.parameters = (_b = operationObject.parameters) === null || _b === void 0 ? void 0 : _b.filter((item) => {
284
365
  const parameter = this.resolveParameterRef(item);
285
366
  return (parameter === null || parameter === void 0 ? void 0 : parameter.in) !== `${config_2.parametersInsEnum.header}`;
@@ -318,6 +399,22 @@ class ServiceGenerator {
318
399
  props: [props],
319
400
  isEnum: false,
320
401
  });
402
+ // 记录 Params 类型归属(属于对应的 tag/module)
403
+ if (this.config.isSplitTypesByModule) {
404
+ tags.forEach((tag) => {
405
+ var _a;
406
+ if (tag) {
407
+ const tagTypeName = (0, util_2.resolveTypeName)(tag);
408
+ const tagKey = this.config.isCamelCase
409
+ ? (0, util_1.camelCase)(tagTypeName)
410
+ : (0, lodash_1.lowerFirst)(tagTypeName);
411
+ const className = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customClassName)
412
+ ? this.config.hook.customClassName(tag)
413
+ : (0, util_2.replaceDot)(tagKey);
414
+ this.markTypeUsedByModule(typeName, className);
415
+ }
416
+ });
417
+ }
321
418
  }
322
419
  });
323
420
  });
@@ -344,8 +441,9 @@ class ServiceGenerator {
344
441
  (0, lodash_1.forEach)(result.props[0], (item) => {
345
442
  if (item.enum) {
346
443
  const enumObj = this.resolveEnumObject(item);
444
+ const enumTypeName = `${(0, lodash_1.upperFirst)(item.name)}Enum`;
347
445
  lastTypes.push({
348
- typeName: `${(0, lodash_1.upperFirst)(item.name)}Enum`,
446
+ typeName: enumTypeName,
349
447
  type: enumObj.type,
350
448
  props: [],
351
449
  isEnum: enumObj.isEnum,
@@ -353,6 +451,16 @@ class ServiceGenerator {
353
451
  enumLabelType: enumObj.enumLabelType,
354
452
  description: enumObj.description,
355
453
  });
454
+ // 记录枚举类型归属(继承父 schema 的归属)
455
+ if (this.config.isSplitTypesByModule &&
456
+ schemaUsageMap.has(schemaKey)) {
457
+ const moduleSet = schemaUsageMap.get(schemaKey);
458
+ if (moduleSet) {
459
+ moduleSet.forEach((className) => {
460
+ this.markTypeUsedByModule(enumTypeName, className);
461
+ });
462
+ }
463
+ }
356
464
  }
357
465
  });
358
466
  }
@@ -370,6 +478,15 @@ class ServiceGenerator {
370
478
  enumLabelType: isEnum ? result.enumLabelType : '',
371
479
  description: result.description,
372
480
  });
481
+ // 记录 schema 类型归属
482
+ if (this.config.isSplitTypesByModule && schemaUsageMap.has(schemaKey)) {
483
+ const moduleSet = schemaUsageMap.get(schemaKey);
484
+ if (moduleSet) {
485
+ moduleSet.forEach((className) => {
486
+ this.markTypeUsedByModule(typeName, className);
487
+ });
488
+ }
489
+ }
373
490
  }
374
491
  if (this.config.isGenJsonSchemas) {
375
492
  this.schemaList.push({
@@ -386,6 +503,11 @@ class ServiceGenerator {
386
503
  var _a, _b;
387
504
  // functionName tag 级别防重
388
505
  const tmpFunctionRD = {};
506
+ // 获取当前模块的 className (用于记录类型归属)
507
+ const fileName = (0, util_2.replaceDot)(tag) || `api${index}`;
508
+ const className = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customClassName)
509
+ ? this.config.hook.customClassName(tag)
510
+ : fileName;
389
511
  const genParams = this.apiData[tag]
390
512
  .filter((api) =>
391
513
  // 暂不支持变量, path 需要普通前缀请使用例如: apiPrefix: "`api`", path 需要变量前缀请使用例如: apiPrefix: "api"
@@ -418,6 +540,10 @@ class ServiceGenerator {
418
540
  isEnum: false,
419
541
  props: [],
420
542
  });
543
+ // 记录类型归属
544
+ if (this.config.isSplitTypesByModule) {
545
+ this.markTypeUsedByModule(bodyName, className);
546
+ }
421
547
  body.type = `${this.config.namespace}.${bodyName}`;
422
548
  }
423
549
  if (response === null || response === void 0 ? void 0 : response.isAnonymous) {
@@ -432,17 +558,26 @@ class ServiceGenerator {
432
558
  isEnum: false,
433
559
  props: [],
434
560
  });
561
+ // 记录类型归属
562
+ if (this.config.isSplitTypesByModule) {
563
+ this.markTypeUsedByModule(responseName, className);
564
+ }
435
565
  response.type = `${this.config.namespace}.${responseName}`;
436
566
  }
437
567
  const responsesType = this.getResponsesType(newApi.responses, functionName);
438
568
  // 如果有多个响应类型,生成对应的类型定义
439
569
  if (responsesType) {
570
+ const responsesTypeName = (0, lodash_1.upperFirst)(`${functionName}Responses`);
440
571
  this.interfaceTPConfigs.push({
441
- typeName: (0, lodash_1.upperFirst)(`${functionName}Responses`),
572
+ typeName: responsesTypeName,
442
573
  type: responsesType,
443
574
  isEnum: false,
444
575
  props: [],
445
576
  });
577
+ // 记录类型归属
578
+ if (this.config.isSplitTypesByModule) {
579
+ this.markTypeUsedByModule(responsesTypeName, className);
580
+ }
446
581
  }
447
582
  let formattedPath = newApi.path.replace(/:([^/]*)|{([^}]*)}/gi, (_, str, str2) => `$\{${str || str2}}`);
448
583
  // 为 path 中的 params 添加 alias
@@ -514,11 +649,7 @@ class ServiceGenerator {
514
649
  })
515
650
  // 排序下,防止git乱
516
651
  .sort((a, b) => a.path.localeCompare(b.path));
517
- const fileName = (0, util_2.replaceDot)(tag) || `api${index}`;
518
- let className = fileName;
519
- if ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customClassName) {
520
- className = this.config.hook.customClassName(tag);
521
- }
652
+ // fileName className 已在方法开始时声明
522
653
  if (genParams.length) {
523
654
  this.classNameList.push({
524
655
  fileName: className,
@@ -706,28 +837,10 @@ class ServiceGenerator {
706
837
  return null;
707
838
  }
708
839
  resolveFileTP(obj) {
709
- var _a;
710
- let ret = [];
711
- const resolved = this.resolveObject(obj);
712
- const props = (((_a = resolved.props) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
713
- resolved.props[0].filter((p) => p.format === 'binary' ||
714
- p.format === 'base64' ||
715
- (0, util_2.isBinaryArraySchemaObject)(p))) ||
716
- [];
717
- if (props.length > 0) {
718
- ret = props.map((p) => {
719
- // 这里 p.type 是自定义type, 注意别混淆
720
- return {
721
- title: p.name,
722
- multiple: p.type === `${config_1.SchemaObjectType.array}` ||
723
- p.type === `${config_1.SchemaObjectType.stringArray}`,
724
- };
725
- });
726
- }
727
- if (resolved.type) {
728
- ret = [...ret, ...this.resolveFileTP(resolved.type)];
729
- }
730
- return ret;
840
+ return Helper.resolveFileTP({
841
+ obj,
842
+ resolveObjectFunc: (schemaObject) => this.resolveObject(schemaObject),
843
+ });
731
844
  }
732
845
  getResponseTP(responses = {}) {
733
846
  var _a;
@@ -804,47 +917,13 @@ class ServiceGenerator {
804
917
  * @returns 多状态码响应类型定义字符串,如果没有响应则返回 null
805
918
  */
806
919
  getResponsesType(responses = {}, functionName) {
807
- if ((0, lodash_1.isEmpty)(responses) ||
808
- ~(0, lodash_1.findIndex)(this.interfaceTPConfigs, (item) => item.typeName === (0, lodash_1.upperFirst)(`${functionName}Responses`))) {
809
- return null;
810
- }
811
- const { components } = this.openAPIData;
812
- // 生成主响应类型名称
813
- const mainResponseTypeName = (0, lodash_1.upperFirst)(`${functionName}Response`);
814
- const responseEntries = this.parseResponseEntries(responses, components);
815
- const responseTypes = responseEntries.map(({ statusCode, type, description = '' }) => {
816
- var _a;
817
- // 检查是否已存在对应的主响应类型,如果存在则复用,避免重复定义
818
- const existType = this.interfaceTPConfigs.find((item) => item.typeName === mainResponseTypeName);
819
- const lastType = existType ? mainResponseTypeName : type;
820
- // 格式化描述文本,让描述支持换行
821
- const formattedDescription = config_2.lineBreakReg.test(description)
822
- ? (_a = description.split('\n')) === null || _a === void 0 ? void 0 : _a.join('\n * ')
823
- : description;
824
- // 生成带注释的类型定义
825
- return formattedDescription
826
- ? ` /**\n * ${formattedDescription}\n */\n ${statusCode}: ${lastType};`
827
- : ` ${statusCode}: ${lastType};`;
828
- });
829
- // 返回完整的对象类型定义
830
- return `{\n${responseTypes.join('\n')}\n}`;
831
- }
832
- /**
833
- * 解析响应条目,提取每个状态码对应的类型和描述信息
834
- *
835
- * @param responses OpenAPI 响应对象
836
- * @param components OpenAPI 组件对象,用于解析引用类型
837
- * @returns 响应条目数组,包含状态码、类型和描述
838
- */
839
- parseResponseEntries(responses, components) {
840
- return (0, lodash_1.keys)(responses).map((statusCode) => {
841
- const response = this.resolveRefObject(responses[statusCode]);
842
- if (!response) {
843
- return { statusCode, type: 'unknown', description: '' };
844
- }
845
- const responseType = this.getResponseTypeFromContent(response, components);
846
- const description = response.description || '';
847
- return { statusCode, type: responseType, description };
920
+ return Helper.getResponsesType({
921
+ responses,
922
+ functionName,
923
+ interfaceTPConfigs: this.interfaceTPConfigs,
924
+ components: this.openAPIData.components,
925
+ getResponseTypeFromContentFunc: (params) => this.getResponseTypeFromContent(params.response, params.components),
926
+ resolveRefObjectFunc: (refObject) => this.resolveRefObject(refObject),
848
927
  });
849
928
  }
850
929
  /**
@@ -856,90 +935,22 @@ class ServiceGenerator {
856
935
  * @returns TypeScript 类型字符串
857
936
  */
858
937
  getResponseTypeFromContent(response, components) {
859
- var _a;
860
- if (!response.content) {
861
- return 'unknown';
862
- }
863
- const resContent = response.content;
864
- const resContentMediaTypes = (0, lodash_1.keys)(resContent);
865
- // 检测二进制流媒体类型
866
- const binaryMediaTypes = (0, util_2.getBinaryMediaTypes)(this.config.binaryMediaTypes);
867
- const binaryMediaType = resContentMediaTypes.find((mediaType) => (0, util_2.isBinaryMediaType)(mediaType, binaryMediaTypes));
868
- const mediaType = resContentMediaTypes.includes('application/json')
869
- ? 'application/json'
870
- : binaryMediaType || resContentMediaTypes[0];
871
- if (!(0, lodash_1.isObject)(resContent) || !mediaType) {
872
- return 'unknown';
873
- }
874
- // 如果是二进制媒体类型,直接返回二进制类型
875
- if ((0, util_2.isBinaryMediaType)(mediaType, binaryMediaTypes)) {
876
- return (0, util_2.getBinaryResponseType)();
877
- }
878
- let schema = (resContent[mediaType].schema ||
879
- config_2.DEFAULT_SCHEMA);
880
- if ((0, util_2.isReferenceObject)(schema)) {
881
- const refName = (0, util_2.getLastRefName)(schema.$ref);
882
- const childrenSchema = components.schemas[refName];
883
- // 如果配置了 dataFields,尝试从指定字段提取类型
884
- if ((0, util_2.isNonArraySchemaObject)(childrenSchema) && this.config.dataFields) {
885
- schema = (((_a = this.config.dataFields
886
- .map((field) => childrenSchema.properties[field])
887
- .filter(Boolean)) === null || _a === void 0 ? void 0 : _a[0]) ||
888
- resContent[mediaType].schema ||
889
- config_2.DEFAULT_SCHEMA);
890
- }
891
- return this.getType(schema);
892
- }
893
- else if ((0, util_2.isSchemaObject)(schema)) {
894
- // 设置属性的 required 状态
895
- (0, lodash_1.keys)(schema.properties).map((fieldName) => {
896
- var _a, _b;
897
- schema.properties[fieldName]['required'] =
898
- (_b = (_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(fieldName)) !== null && _b !== void 0 ? _b : false;
899
- });
900
- return this.getType(schema);
901
- }
902
- else {
903
- return this.getType(schema);
904
- }
938
+ return Helper.getResponseTypeFromContent({
939
+ response,
940
+ components,
941
+ config: this.config,
942
+ getType: (schema) => this.getType(schema),
943
+ });
905
944
  }
906
945
  getParamsTP(parameters = [], path = null) {
907
- const templateParams = {};
908
- if (parameters === null || parameters === void 0 ? void 0 : parameters.length) {
909
- (0, lodash_1.forEach)(config_2.parametersIn, (source) => {
910
- const params = parameters
911
- .map((p) => this.resolveRefObject(p))
912
- .filter((p) => p.in === source)
913
- .map((p) => {
914
- var _a, _b, _c, _d, _e;
915
- const isDirectObject = (((_a = p.schema) === null || _a === void 0 ? void 0 : _a.type) === 'object' ||
916
- p.type) === 'object';
917
- const refName = (0, util_2.getLastRefName)(((_b = p.schema) === null || _b === void 0 ? void 0 : _b.$ref) ||
918
- p.$ref);
919
- const deRefObj = (0, lodash_1.entries)((_c = this.openAPIData.components) === null || _c === void 0 ? void 0 : _c.schemas).find(([k]) => k === refName) || [];
920
- const isRefObject = ((_d = deRefObj[1]) === null || _d === void 0 ? void 0 : _d.type) === 'object' &&
921
- !(0, lodash_1.isEmpty)((_e = deRefObj[1]) === null || _e === void 0 ? void 0 : _e.properties);
922
- return Object.assign(Object.assign({}, p), { isObject: isDirectObject || isRefObject, type: this.getType(p.schema || config_2.DEFAULT_SCHEMA, this.config.namespace) });
923
- });
924
- if (params.length) {
925
- templateParams[source] = params;
926
- }
927
- });
928
- }
929
- if (path && path.length > 0) {
930
- const regex = /\{(\w+)\}/g;
931
- templateParams.path = templateParams.path || [];
932
- let match = null;
933
- while ((match = regex.exec(path))) {
934
- if (!templateParams.path.some((p) => p.name === match[1])) {
935
- templateParams.path.push(Object.assign(Object.assign({}, config_2.DEFAULT_PATH_PARAM), { name: match[1] }));
936
- }
937
- }
938
- // 如果 path 没有内容,则将删除 path 参数,避免影响后续的 hasParams 判断
939
- if (!templateParams.path.length)
940
- delete templateParams.path;
941
- }
942
- return templateParams;
946
+ return Helper.getParamsTP({
947
+ parameters,
948
+ path,
949
+ namespace: this.config.namespace,
950
+ openAPIData: this.openAPIData,
951
+ getType: (schema, namespace) => this.getType(schema, namespace),
952
+ resolveParameterRefFunc: (params) => this.resolveParameterRef(params.param),
953
+ });
943
954
  }
944
955
  resolveObject(schemaObject) {
945
956
  // 不使用 schemaObject: ISchemaObject = {}
@@ -967,158 +978,54 @@ class ServiceGenerator {
967
978
  return schemaObject;
968
979
  }
969
980
  resolveArray(schemaObject) {
970
- var _a;
971
- if ((0, util_2.isReferenceObject)(schemaObject.items)) {
972
- const refName = (0, util_2.getRefName)(schemaObject.items);
973
- return {
974
- type: `${refName}[]`,
975
- };
976
- }
977
- else if ((_a = schemaObject.items) === null || _a === void 0 ? void 0 : _a.enum) {
978
- return {
979
- type: this.getType(schemaObject, this.config.namespace),
980
- };
981
- }
982
- // 这里需要解析出具体属性,但由于 parser 层还不确定,所以暂时先返回 unknown[]
983
- return { type: 'unknown[]' };
981
+ return Helper.resolveArray({
982
+ schemaObject,
983
+ namespace: this.config.namespace,
984
+ getType: (schema, namespace) => this.getType(schema, namespace),
985
+ });
984
986
  }
985
987
  resolveProperties(schemaObject) {
986
- return {
987
- props: [this.getProps(schemaObject)],
988
- };
988
+ return Helper.resolveProperties({
989
+ schemaObject,
990
+ getProps: (schema) => this.getProps(schema),
991
+ });
989
992
  }
990
993
  resolveEnumObject(schemaObject) {
991
- var _a;
992
- const enumArray = schemaObject.enum;
993
- let enumStr = '';
994
- let enumLabelTypeStr = '';
995
- if (config_2.numberEnum.includes(schemaObject.type) || (0, util_2.isAllNumber)(enumArray)) {
996
- if (this.config.isSupportParseEnumDesc && schemaObject.description) {
997
- const enumMap = (0, util_2.parseDescriptionEnum)(schemaObject.description);
998
- enumStr = `{${(0, lodash_1.map)(enumArray, (value) => {
999
- const enumLabel = enumMap.get(Number(value));
1000
- return `${enumLabel}=${Number(value)}`;
1001
- }).join(',')}}`;
1002
- }
1003
- else {
1004
- enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"NUMBER_${value}"=${Number(value)}`).join(',')}}`;
1005
- }
1006
- }
1007
- else if ((0, util_2.isAllNumeric)(enumArray)) {
1008
- enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"STRING_NUMBER_${value}"="${value}"`).join(',')}}`;
1009
- }
1010
- else {
1011
- enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}"="${value}"`).join(',')}}`;
1012
- }
1013
- // 翻译枚举
1014
- if (schemaObject['x-enum-varnames'] && schemaObject['x-enum-comments']) {
1015
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value, index) => {
1016
- const enumKey = schemaObject['x-enum-varnames'][index];
1017
- return `${value}:"${schemaObject['x-enum-comments'][enumKey]}"`;
1018
- }).join(',')}}`;
1019
- }
1020
- else if ((_a = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject['x-apifox']) === null || _a === void 0 ? void 0 : _a['enumDescriptions']) {
1021
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => {
1022
- const enumLabel = schemaObject['x-apifox']['enumDescriptions'][value];
1023
- return `${value}:"${enumLabel}"`;
1024
- }).join(',')}}`;
1025
- }
1026
- else if (schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject['x-apifox-enum']) {
1027
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => {
1028
- var _a;
1029
- const enumLabel = (_a = (0, lodash_1.find)(schemaObject['x-apifox-enum'], (item) => item.value === value)) === null || _a === void 0 ? void 0 : _a.description;
1030
- return `${value}:"${enumLabel}"`;
1031
- }).join(',')}}`;
1032
- }
1033
- else {
1034
- if (config_2.numberEnum.includes(schemaObject.type) || (0, util_2.isAllNumber)(enumArray)) {
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);
1041
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => {
1042
- const enumLabel = enumMap.get(Number(value));
1043
- return `${Number(value)}:"${enumLabel}"`;
1044
- }).join(',')}}`;
1045
- }
1046
- else {
1047
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `${Number(value) >= 0 ? Number(value) : `"${value}"`}:"NUMBER_${value}"`).join(',')}}`;
1048
- }
1049
- }
1050
- else if ((0, util_2.isAllNumeric)(enumArray)) {
1051
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}":"STRING_NUMBER_${value}"`).join(',')}}`;
1052
- }
1053
- else {
1054
- enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}":"${value}"`).join(',')}}`;
1055
- }
1056
- }
1057
- return {
1058
- isEnum: true,
1059
- type: Array.isArray(enumArray) ? enumStr : 'string',
1060
- enumLabelType: enumLabelTypeStr,
1061
- description: schemaObject.description,
1062
- };
994
+ return Helper.resolveEnumObject({
995
+ schemaObject,
996
+ config: {
997
+ isSupportParseEnumDesc: this.config.isSupportParseEnumDesc,
998
+ supportParseEnumDescByReg: this.config.supportParseEnumDescByReg,
999
+ },
1000
+ });
1063
1001
  }
1064
1002
  resolveAllOfObject(schemaObject) {
1065
- const props = (0, lodash_1.map)(schemaObject.allOf, (item) => {
1066
- return (0, util_2.isReferenceObject)(item)
1067
- ? [Object.assign(Object.assign({}, item), { type: this.getType(item) })]
1068
- : this.getProps(item);
1003
+ return Helper.resolveAllOfObject({
1004
+ schemaObject,
1005
+ getType: (schema, namespace) => this.getType(schema, namespace),
1006
+ getProps: (schema) => this.getProps(schema),
1069
1007
  });
1070
- if (schemaObject.properties) {
1071
- const extProps = this.getProps(schemaObject);
1072
- return { props: [...props, extProps] };
1073
- }
1074
- return { props };
1075
1008
  }
1076
1009
  // 获取 TS 类型的属性列表
1077
1010
  getProps(schemaObject) {
1078
- var _a;
1079
- const requiredPropKeys = (_a = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.required) !== null && _a !== void 0 ? _a : false;
1080
- const properties = schemaObject.properties;
1081
- return (0, lodash_1.keys)(properties).map((propKey) => {
1082
- const schema = ((properties === null || properties === void 0 ? void 0 : properties[propKey]) || config_2.DEFAULT_SCHEMA);
1083
- // 剔除属性键值中的特殊符号,因为函数入参变量存在特殊符号会导致解析文件失败
1084
- // eslint-disable-next-line no-useless-escape
1085
- propKey = propKey.replace(/[\[|\]]/g, '');
1086
- // 复用 schema 部分字段
1087
- return Object.assign(Object.assign({}, schema), { name: propKey, type: this.getType(schema), desc: [schema.title, schema.description]
1088
- .filter((item) => item)
1089
- .join(' ')
1090
- .replace(config_2.lineBreakReg, ''),
1091
- // 如果没有 required 信息,默认全部是非必填
1092
- required: requiredPropKeys
1093
- ? requiredPropKeys.some((key) => key === propKey)
1094
- : false });
1011
+ return Helper.getProps({
1012
+ schemaObject,
1013
+ getType: (schema, namespace) => this.getType(schema, namespace),
1014
+ openAPIData: this.openAPIData,
1095
1015
  });
1096
1016
  }
1097
1017
  resolveParameterRef(param) {
1098
- var _a, _b;
1099
- if (!(0, util_2.isReferenceObject)(param)) {
1100
- return param;
1101
- }
1102
- // 解析 $ref 引用,从 components.parameters 中获取实际定义
1103
- const refName = (0, util_2.getLastRefName)(param.$ref);
1104
- const parameter = (_b = (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.parameters) === null || _b === void 0 ? void 0 : _b[refName];
1105
- return parameter || null;
1018
+ return Helper.resolveParameterRef({
1019
+ param,
1020
+ openAPIData: this.openAPIData,
1021
+ });
1106
1022
  }
1107
1023
  resolveRefObject(refObject) {
1108
- if (!(0, util_2.isReferenceObject)(refObject)) {
1109
- return refObject;
1110
- }
1111
- const refPaths = refObject.$ref.split('/');
1112
- if (refPaths[0] === '#') {
1113
- const schema = (0, util_2.resolveRefs)(this.openAPIData, refPaths.slice(1));
1114
- if (!schema) {
1115
- throw new Error(`[GenSDK] Data Error! Notfoud: ${refObject.$ref}`);
1116
- }
1117
- return Object.assign(Object.assign({}, (this.resolveRefObject(schema) || {})), { type: (0, util_2.isReferenceObject)(schema)
1118
- ? this.resolveRefObject(schema).type
1119
- : schema.type });
1120
- }
1121
- return refObject;
1024
+ return Helper.resolveRefObject({
1025
+ refObject,
1026
+ openAPIData: this.openAPIData,
1027
+ resolveRefObjectFunc: (params) => this.resolveRefObject(params.refObject),
1028
+ });
1122
1029
  }
1123
1030
  log(message) {
1124
1031
  if (this.config.enableLogging) {
@@ -1175,5 +1082,78 @@ class ServiceGenerator {
1175
1082
  }
1176
1083
  return false; // 对于其他类型,返回 false
1177
1084
  }
1085
+ /**
1086
+ * 记录类型被某个模块使用
1087
+ * @param typeName 类型名称
1088
+ * @param moduleName 模块名称
1089
+ */
1090
+ markTypeUsedByModule(typeName, moduleName) {
1091
+ if (!this.typeModuleMap.has(typeName)) {
1092
+ this.typeModuleMap.set(typeName, new Set());
1093
+ }
1094
+ const moduleSet = this.typeModuleMap.get(typeName);
1095
+ if (moduleSet) {
1096
+ moduleSet.add(moduleName);
1097
+ }
1098
+ }
1099
+ /**
1100
+ * 获取模块需要导入的类型
1101
+ * @param moduleTypes 模块类型列表
1102
+ * @param commonTypes 公共类型列表
1103
+ * @param enumTypes 枚举类型列表
1104
+ * @returns 导入信息
1105
+ */
1106
+ getModuleImports(moduleTypes, commonTypes, enumTypes) {
1107
+ return Helper.getModuleImports({
1108
+ moduleTypes,
1109
+ commonTypes,
1110
+ enumTypes,
1111
+ });
1112
+ }
1113
+ /**
1114
+ * 分组类型:按模块、公共类型和枚举
1115
+ * @returns 分组后的类型
1116
+ */
1117
+ groupTypesByModule() {
1118
+ const moduleTypes = new Map();
1119
+ const commonTypes = [];
1120
+ const enumTypes = [];
1121
+ // 初始化每个模块的类型数组
1122
+ this.classNameList.forEach((controller) => {
1123
+ moduleTypes.set(controller.fileName, []);
1124
+ });
1125
+ // 遍历所有类型,根据使用情况分组
1126
+ this.interfaceTPConfigs.forEach((typeItem) => {
1127
+ // 枚举类型单独处理,放入 enumTypes
1128
+ if (typeItem.isEnum) {
1129
+ enumTypes.push(typeItem);
1130
+ return;
1131
+ }
1132
+ const modules = this.typeModuleMap.get(typeItem.typeName);
1133
+ if (!modules || modules.size === 0) {
1134
+ // 未被任何模块使用的类型,放入公共类型
1135
+ commonTypes.push(typeItem);
1136
+ }
1137
+ else if (modules.size === 1) {
1138
+ // 只被一个模块使用,放入该模块
1139
+ const moduleName = Array.from(modules)[0];
1140
+ const moduleTypeList = moduleTypes.get(moduleName);
1141
+ if (moduleTypeList) {
1142
+ moduleTypeList.push(typeItem);
1143
+ }
1144
+ else {
1145
+ // 如果模块不存在(可能是因为过滤),放入公共类型
1146
+ commonTypes.push(typeItem);
1147
+ }
1148
+ }
1149
+ else {
1150
+ // 被多个模块使用,放入公共类型
1151
+ commonTypes.push(typeItem);
1152
+ }
1153
+ });
1154
+ // 处理公共类型的依赖:如果公共类型依赖某个模块类型,将该类型也移到公共类型
1155
+ Helper.moveCommonTypeDependenciesToCommon({ moduleTypes, commonTypes });
1156
+ return { moduleTypes, commonTypes, enumTypes };
1157
+ }
1178
1158
  }
1179
1159
  exports.default = ServiceGenerator;