|
17 | 17 |
|
18 | 18 | package org.openapitools.codegen.languages; |
19 | 19 |
|
20 | | -import io.swagger.v3.oas.models.OpenAPI; |
21 | | -import io.swagger.v3.oas.models.media.Schema; |
22 | | -import io.swagger.v3.oas.models.parameters.Parameter; |
23 | | -import lombok.Getter; |
24 | | -import lombok.Setter; |
| 20 | +import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.form; |
| 21 | +import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.simple; |
| 22 | +import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; |
| 23 | +import static org.openapitools.codegen.utils.StringUtils.camelize; |
| 24 | +import static org.openapitools.codegen.utils.StringUtils.underscore; |
| 25 | + |
| 26 | +import java.io.File; |
| 27 | +import java.text.SimpleDateFormat; |
| 28 | +import java.util.ArrayList; |
| 29 | +import java.util.Arrays; |
| 30 | +import java.util.Collections; |
| 31 | +import java.util.Date; |
| 32 | +import java.util.EnumSet; |
| 33 | +import java.util.HashMap; |
| 34 | +import java.util.HashSet; |
| 35 | +import java.util.List; |
| 36 | +import java.util.Locale; |
| 37 | +import java.util.Map; |
| 38 | +import java.util.Set; |
| 39 | +import java.util.TreeSet; |
| 40 | +import java.util.function.BiPredicate; |
| 41 | +import java.util.function.Function; |
| 42 | +import java.util.regex.Pattern; |
| 43 | +import java.util.stream.Collectors; |
| 44 | +import java.util.stream.Stream; |
| 45 | + |
25 | 46 | import org.apache.commons.io.FilenameUtils; |
26 | 47 | import org.apache.commons.lang3.StringUtils; |
27 | 48 | import org.checkerframework.checker.nullness.qual.Nullable; |
28 | | -import org.openapitools.codegen.*; |
| 49 | +import org.openapitools.codegen.CliOption; |
| 50 | +import org.openapitools.codegen.CodegenConfig; |
| 51 | +import org.openapitools.codegen.CodegenConstants; |
29 | 52 | import org.openapitools.codegen.CodegenConstants.ENUM_PROPERTY_NAMING_TYPE; |
30 | 53 | import org.openapitools.codegen.CodegenConstants.MODEL_PROPERTY_NAMING_TYPE; |
31 | 54 | import org.openapitools.codegen.CodegenConstants.PARAM_NAMING_TYPE; |
32 | | -import org.openapitools.codegen.meta.features.*; |
| 55 | +import org.openapitools.codegen.CodegenModel; |
| 56 | +import org.openapitools.codegen.CodegenOperation; |
| 57 | +import org.openapitools.codegen.CodegenParameter; |
| 58 | +import org.openapitools.codegen.CodegenProperty; |
| 59 | +import org.openapitools.codegen.CodegenType; |
| 60 | +import org.openapitools.codegen.DefaultCodegen; |
| 61 | +import org.openapitools.codegen.GeneratorLanguage; |
| 62 | +import org.openapitools.codegen.meta.features.ClientModificationFeature; |
| 63 | +import org.openapitools.codegen.meta.features.DocumentationFeature; |
| 64 | +import org.openapitools.codegen.meta.features.GlobalFeature; |
| 65 | +import org.openapitools.codegen.meta.features.SchemaSupportFeature; |
| 66 | +import org.openapitools.codegen.meta.features.SecurityFeature; |
| 67 | +import org.openapitools.codegen.meta.features.WireFormatFeature; |
33 | 68 | import org.openapitools.codegen.model.ModelMap; |
34 | 69 | import org.openapitools.codegen.model.ModelsMap; |
35 | 70 | import org.openapitools.codegen.utils.ModelUtils; |
36 | 71 | import org.slf4j.Logger; |
37 | 72 | import org.slf4j.LoggerFactory; |
38 | 73 |
|
39 | | -import java.io.File; |
40 | | -import java.text.SimpleDateFormat; |
41 | | -import java.util.*; |
42 | | -import java.util.function.BiPredicate; |
43 | | -import java.util.function.Function; |
44 | | -import java.util.regex.Pattern; |
45 | | -import java.util.stream.Collectors; |
46 | | -import java.util.stream.Stream; |
47 | | - |
48 | | -import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.form; |
49 | | -import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.simple; |
50 | | -import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; |
51 | | -import static org.openapitools.codegen.utils.StringUtils.camelize; |
52 | | -import static org.openapitools.codegen.utils.StringUtils.underscore; |
| 74 | +import io.swagger.v3.oas.models.OpenAPI; |
| 75 | +import io.swagger.v3.oas.models.media.Schema; |
| 76 | +import io.swagger.v3.oas.models.parameters.Parameter; |
| 77 | +import lombok.Getter; |
| 78 | +import lombok.Setter; |
53 | 79 |
|
54 | 80 | public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig { |
55 | 81 |
|
@@ -1023,22 +1049,104 @@ protected void addImport(CodegenModel m, String type) { |
1023 | 1049 | } |
1024 | 1050 | } |
1025 | 1051 |
|
| 1052 | + /** |
| 1053 | + * Override to fix the inner enum naming issue for maps/arrays of enums. |
| 1054 | + * <p> |
| 1055 | + * The parent implementation uses toEnumName(baseItem) which produces a generic name |
| 1056 | + * like "InnerEnum" based on the inner item's name. This override first calculates |
| 1057 | + * the correct property.enumName, then uses it in the datatypeWithEnum replacement. |
| 1058 | + * </p> |
| 1059 | + * |
| 1060 | + * @param property Codegen property |
| 1061 | + */ |
| 1062 | + @Override |
| 1063 | + protected void updateDataTypeWithEnumForArray(CodegenProperty property) { |
| 1064 | + CodegenProperty baseItem = property.items; |
| 1065 | + while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMap) |
| 1066 | + || Boolean.TRUE.equals(baseItem.isArray))) { |
| 1067 | + baseItem = baseItem.items; |
| 1068 | + } |
| 1069 | + |
| 1070 | + if (baseItem != null) { |
| 1071 | + // First, set the property's enumName using the property itself (not the inner item) |
| 1072 | + // This ensures the correct enum name (e.g., "OptionsEnum") is used |
| 1073 | + // instead of the generic inner item name (e.g., "InnerEnum") |
| 1074 | + property.enumName = toEnumName(property); |
| 1075 | + |
| 1076 | + // Now use property.enumName for datatypeWithEnum |
| 1077 | + property.datatypeWithEnum = property.datatypeWithEnum.replace(baseItem.baseType, property.enumName); |
| 1078 | + |
| 1079 | + // set default value for variable with inner enum |
| 1080 | + if (property.defaultValue != null) { |
| 1081 | + property.defaultValue = property.defaultValue.replace(baseItem.baseType, property.enumName); |
| 1082 | + } |
| 1083 | + |
| 1084 | + updateCodegenPropertyEnum(property); |
| 1085 | + } |
| 1086 | + } |
| 1087 | + |
| 1088 | + /** |
| 1089 | + * Override to fix the inner enum naming issue for map properties. |
| 1090 | + * <p> |
| 1091 | + * The parent implementation uses {@code toEnumName(baseItem)} which produces "InnerEnum" |
| 1092 | + * for properties whose inner item has a generic name like "inner". We instead |
| 1093 | + * calculate the enumName from the property itself first, then use it in the replacement. |
| 1094 | + * </p> |
| 1095 | + * |
| 1096 | + * @param property Codegen property |
| 1097 | + */ |
| 1098 | + @Override |
| 1099 | + protected void updateDataTypeWithEnumForMap(CodegenProperty property) { |
| 1100 | + CodegenProperty baseItem = property.items; |
| 1101 | + while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMap) |
| 1102 | + || Boolean.TRUE.equals(baseItem.isArray))) { |
| 1103 | + baseItem = baseItem.items; |
| 1104 | + } |
| 1105 | + |
| 1106 | + if (baseItem != null) { |
| 1107 | + // First, set the property's enumName using the property itself (not the inner item) |
| 1108 | + property.enumName = toEnumName(property); |
| 1109 | + |
| 1110 | + // Replace only the LAST occurrence of baseType with enumName. |
| 1111 | + // In map types, the value type appears last (after the key type), |
| 1112 | + // so this approach is template-agnostic. |
| 1113 | + String datatypeWithEnum = property.datatypeWithEnum; |
| 1114 | + int lastIndex = datatypeWithEnum.lastIndexOf(baseItem.baseType); |
| 1115 | + if (lastIndex >= 0) { |
| 1116 | + property.datatypeWithEnum = datatypeWithEnum.substring(0, lastIndex) |
| 1117 | + + property.enumName |
| 1118 | + + datatypeWithEnum.substring(lastIndex + baseItem.baseType.length()); |
| 1119 | + } |
| 1120 | + LOGGER.info("Updated datatypeWithEnum for map property '{}': {}", property.name, property.datatypeWithEnum); |
| 1121 | + |
| 1122 | + // set default value for variable with inner enum |
| 1123 | + if (property.defaultValue != null) { |
| 1124 | + property.defaultValue = property.defaultValue.replace(baseItem.baseType, property.enumName); |
| 1125 | + } |
| 1126 | + |
| 1127 | + updateCodegenPropertyEnum(property); |
| 1128 | + } |
| 1129 | + } |
| 1130 | + |
1026 | 1131 | @Override |
1027 | 1132 | public ModelsMap postProcessModels(ModelsMap objs) { |
1028 | 1133 | // process enum in models |
1029 | 1134 | List<ModelMap> models = postProcessModelsEnum(objs).getModels(); |
1030 | 1135 | for (ModelMap mo : models) { |
1031 | 1136 | CodegenModel cm = mo.getModel(); |
1032 | 1137 | cm.imports = new TreeSet<>(cm.imports); |
| 1138 | + |
1033 | 1139 | // name enum with model name, e.g. StatusEnum => Pet.StatusEnum |
| 1140 | + // This applies to both direct enum properties (isEnum) and properties containing |
| 1141 | + // inner enums (isInnerEnum) like maps or arrays of enums. |
1034 | 1142 | for (CodegenProperty var : cm.vars) { |
1035 | | - if (Boolean.TRUE.equals(var.isEnum)) { |
| 1143 | + if (Boolean.TRUE.equals(var.isEnum) || Boolean.TRUE.equals(var.isInnerEnum)) { |
1036 | 1144 | var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + classEnumSeparator + var.enumName); |
1037 | 1145 | } |
1038 | 1146 | } |
1039 | 1147 | if (cm.parent != null) { |
1040 | 1148 | for (CodegenProperty var : cm.allVars) { |
1041 | | - if (Boolean.TRUE.equals(var.isEnum)) { |
| 1149 | + if (Boolean.TRUE.equals(var.isEnum) || Boolean.TRUE.equals(var.isInnerEnum)) { |
1042 | 1150 | var.datatypeWithEnum = var.datatypeWithEnum |
1043 | 1151 | .replace(var.enumName, cm.classname + classEnumSeparator + var.enumName); |
1044 | 1152 | } |
|
0 commit comments