diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index df5e1f2a4e3a0318f9a9025046eda3bc638fc28b..c453503d315e9bd096f81d66d8a3be8ae13130ca 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,8 +11,8 @@ assignees: '' - [ ] Have you provided a full/minimal spec to reproduce the issue? - [ ] Have you validated the input using an OpenAPI validator ([example](https://apidevtools.org/swagger-parser/online/))? -- [ ] Have you [tested with the latest master](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) to confirm the issuue still exists? -- [ ] Have you search for related issues/PRs? +- [ ] Have you [tested with the latest master](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) to confirm the issue still exists? +- [ ] Have you searched for related issues/PRs? - [ ] What's the actual output vs expected output? - [ ] [Optional] Sponsorship to speed up the bug fix or feature request ([example](https://github.com/OpenAPITools/openapi-generator/issues/6178)) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java index 6c6ba19bb120b762d517095f2f0df7bef7a6fa59..e463c4bb7989a06eb402a3fd8a79bbc92c171520 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java @@ -771,7 +771,9 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co @Override protected boolean needToImport(String type) { // provides extra protection against improperly trying to import language primitives and java types - boolean imports = !type.startsWith("kotlin.") && !type.startsWith("java.") && !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type); + boolean imports = !type.startsWith("kotlin.") && !type.startsWith("java.") && + !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type) && + !type.contains("."); return imports; } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java index 7cd75706b27d4caabd44b783953a7997835f888e..83b823c705fcbd17fbeceda057230cdc3e758cd1 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java @@ -690,18 +690,35 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp case original: return name; case camelCase: - return camelize(name, true); + return camelize(prepareEnumString(name), true); case PascalCase: - return camelize(name); + return camelize(prepareEnumString(name)); case snake_case: return underscore(name); case UPPERCASE: - return name.toUpperCase(Locale.ROOT); + return prepareEnumString(name).toUpperCase(Locale.ROOT); default: throw new IllegalArgumentException("Unsupported enum property naming: '" + name); } } + private String prepareEnumString(String name) { + if (name == null || name.isEmpty()) { + return name; + } + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(name.charAt(0)); + for (int i = 1; i < name.length(); i++) { + if (Character.isLowerCase(name.charAt(i - 1)) && Character.isUpperCase(name.charAt(i))) { + stringBuilder.append('_').append(name.charAt(i)); + } else { + stringBuilder.append(name.charAt(i)); + } + } + return stringBuilder.toString().toLowerCase(); + } + @Override protected void addImport(CodegenModel m, String type) { if (type == null) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index 1b5f74bed475033745e18965de2ddefbaf056305..5e624585126e9b7234fa0ded4b83610e2bd54b58 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -41,8 +41,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.io.FileUtils; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URI; +import java.net.URLDecoder; import java.util.*; import java.util.Map.Entry; import java.util.stream.Collectors; @@ -73,7 +75,7 @@ public class ModelUtils { JSON_MAPPER = ObjectMapperFactory.createJson(); YAML_MAPPER = ObjectMapperFactory.createYaml(); } - + public static void setDisallowAdditionalPropertiesIfNotPresent(boolean value) { GlobalSettings.setProperty(disallowAdditionalPropertiesIfNotPresent, Boolean.toString(value)); } @@ -388,6 +390,18 @@ public class ModelUtils { } + try { + ref = URLDecoder.decode(ref, "UTF-8"); + } catch (UnsupportedEncodingException ignored) { + } + + // see https://tools.ietf.org/html/rfc6901#section-3 + // Because the characters '~' (%x7E) and '/' (%x2F) have special meanings in + // JSON Pointer, '~' needs to be encoded as '~0' and '/' needs to be encoded + // as '~1' when these characters appear in a reference token. + // This reverses that encoding. + ref = ref.replace("~1", "/").replace("~0", "~"); + return ref; } @@ -1087,7 +1101,7 @@ public class ModelUtils { /** * Returns the additionalProperties Schema for the specified input schema. - * + * * The additionalProperties keyword is used to control the handling of additional, undeclared * properties, that is, properties whose names are not listed in the properties keyword. * The additionalProperties keyword may be either a boolean or an object. @@ -1095,7 +1109,7 @@ public class ModelUtils { * By default when the additionalProperties keyword is not specified in the input schema, * any additional properties are allowed. This is equivalent to setting additionalProperties * to the boolean value True or setting additionalProperties: {} - * + * * @param openAPI the object that encapsulates the OAS document. * @param schema the input schema that may or may not have the additionalProperties keyword. * @return the Schema of the additionalProperties. The null value is returned if no additional @@ -1151,7 +1165,7 @@ public class ModelUtils { } return null; } - + public static Header getReferencedHeader(OpenAPI openAPI, Header header) { if (header != null && StringUtils.isNotEmpty(header.get$ref())) { String name = getSimpleRef(header.get$ref()); @@ -1488,12 +1502,12 @@ public class ModelUtils { /** * Parse and return a JsonNode representation of the input OAS document. - * + * * @param location the URL of the OAS document. * @param auths the list of authorization values to access the remote URL. - * + * * @throws java.lang.Exception if an error occurs while retrieving the OpenAPI document. - * + * * @return A JsonNode representation of the input OAS document. */ public static JsonNode readWithInfo(String location, List<AuthorizationValue> auths) throws Exception { @@ -1521,14 +1535,14 @@ public class ModelUtils { /** * Parse the OAS document at the specified location, get the swagger or openapi version * as specified in the source document, and return the version. - * + * * For OAS 2.0 documents, return the value of the 'swagger' attribute. * For OAS 3.x documents, return the value of the 'openapi' attribute. - * + * * @param openAPI the object that encapsulates the OAS document. * @param location the URL of the OAS document. * @param auths the list of authorization values to access the remote URL. - * + * * @return the version of the OpenAPI document. */ public static SemVer getOpenApiVersion(OpenAPI openAPI, String location, List<AuthorizationValue> auths) { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptAxiosClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptAxiosClientCodegenTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d81c16b4529c57d0c0d1646a5da9cebb8512bf2d --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptAxiosClientCodegenTest.java @@ -0,0 +1,81 @@ +package org.openapitools.codegen.typescript; + +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.languages.TypeScriptAxiosClientCodegen; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +public class TypeScriptAxiosClientCodegenTest { + + TypeScriptAxiosClientCodegen codegen = new TypeScriptAxiosClientCodegen(); + + @Test + public void testToEnumVarNameOriginalNamingType() { + codegen.additionalProperties().put(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.original.name()); + codegen.processOpts(); + assertEquals(codegen.toEnumVarName("SCIENCE", "string"), "SCIENCE"); + assertEquals(codegen.toEnumVarName("SCIENCE_FICTION", "string"), "SCIENCE_FICTION"); + assertEquals(codegen.toEnumVarName("science", "string"), "science"); + assertEquals(codegen.toEnumVarName("science_fiction", "string"), "science_fiction"); + assertEquals(codegen.toEnumVarName("scienceFiction", "string"), "scienceFiction"); + assertEquals(codegen.toEnumVarName("ScienceFiction", "string"), "ScienceFiction"); + assertEquals(codegen.toEnumVarName("A", "string"), "A"); + assertEquals(codegen.toEnumVarName("b", "string"), "b"); + } + + @Test + public void testToEnumVarNameCamelCaseNamingType() { + codegen.additionalProperties().put(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase.name()); + codegen.processOpts(); + assertEquals(codegen.toEnumVarName("SCIENCE", "string"), "science"); + assertEquals(codegen.toEnumVarName("SCIENCE_FICTION", "string"), "scienceFiction"); + assertEquals(codegen.toEnumVarName("science", "string"), "science"); + assertEquals(codegen.toEnumVarName("science_fiction", "string"), "scienceFiction"); + assertEquals(codegen.toEnumVarName("scienceFiction", "string"), "scienceFiction"); + assertEquals(codegen.toEnumVarName("ScienceFiction", "string"), "scienceFiction"); + } + + @Test + public void testToEnumVarNamePascalCaseNamingType() { + codegen.additionalProperties().put(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.PascalCase.name()); + codegen.processOpts(); + assertEquals(codegen.toEnumVarName("SCIENCE", "string"), "Science"); + assertEquals(codegen.toEnumVarName("SCIENCE_FICTION", "string"), "ScienceFiction"); + assertEquals(codegen.toEnumVarName("science", "string"), "Science"); + assertEquals(codegen.toEnumVarName("science_fiction", "string"), "ScienceFiction"); + assertEquals(codegen.toEnumVarName("scienceFiction", "string"), "ScienceFiction"); + assertEquals(codegen.toEnumVarName("ScienceFiction", "string"), "ScienceFiction"); + assertEquals(codegen.toEnumVarName("A", "string"), "A"); + assertEquals(codegen.toEnumVarName("b", "string"), "B"); + } + + @Test + public void testToEnumVarNameSnakeCaseNamingType() { + codegen.additionalProperties().put(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.snake_case.name()); + codegen.processOpts(); + assertEquals(codegen.toEnumVarName("SCIENCE", "string"), "science"); + assertEquals(codegen.toEnumVarName("SCIENCE_FICTION", "string"), "science_fiction"); + assertEquals(codegen.toEnumVarName("science", "string"), "science"); + assertEquals(codegen.toEnumVarName("science_fiction", "string"), "science_fiction"); + assertEquals(codegen.toEnumVarName("scienceFiction", "string"), "science_fiction"); + assertEquals(codegen.toEnumVarName("ScienceFiction", "string"), "science_fiction"); + assertEquals(codegen.toEnumVarName("A", "string"), "a"); + assertEquals(codegen.toEnumVarName("b", "string"), "b"); + } + + @Test + public void testToEnumVarNameUpperCaseNamingType() { + codegen.additionalProperties().put(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.UPPERCASE.name()); + codegen.processOpts(); + assertEquals(codegen.toEnumVarName("SCIENCE", "string"), "SCIENCE"); + assertEquals(codegen.toEnumVarName("SCIENCE_FICTION", "string"), "SCIENCE_FICTION"); + assertEquals(codegen.toEnumVarName("science", "string"), "SCIENCE"); + assertEquals(codegen.toEnumVarName("science_fiction", "string"), "SCIENCE_FICTION"); + assertEquals(codegen.toEnumVarName("scienceFiction", "string"), "SCIENCE_FICTION"); + assertEquals(codegen.toEnumVarName("ScienceFiction", "string"), "SCIENCE_FICTION"); + assertEquals(codegen.toEnumVarName("A", "string"), "A"); + assertEquals(codegen.toEnumVarName("b", "string"), "B"); + } + +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java index e0e67ceb4fdc576880737a4e6badc753e107c020..a8ed4e34bbe221d7f9dd04425b483ad024c7109d 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java @@ -280,4 +280,10 @@ public class ModelUtilsTest { ArraySchema as = null; Assert.assertFalse(ModelUtils.isSet(as)); } -} \ No newline at end of file + + @Test + public void testSimpleRefDecoding() { + String decoded = ModelUtils.getSimpleRef("#/components/~01%20Hallo~1Welt"); + Assert.assertEquals(decoded, "~1 Hallo/Welt"); + } +} diff --git a/website/src/dynamic/users.yml b/website/src/dynamic/users.yml index 084ca39d2f2901c32606545a25df59b8ec3c5285..843ef43179df11c0cc904023b0d69b8a28e12cb9 100644 --- a/website/src/dynamic/users.yml +++ b/website/src/dynamic/users.yml @@ -399,7 +399,7 @@ infoLink: "https://vouchery.io" pinned: false - - caption: wbt-solutions UG + caption: wbt-solutions image: "img/companies/wbt_solutions.png" infoLink: "https://www.wbt-solutions.de/" pinned: false