diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index a53d9655a74a..c443c8a302b1 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -855,6 +855,20 @@ protected void normalizeProperties(Map properties, Set v } for (Map.Entry propertiesEntry : properties.entrySet()) { Schema property = propertiesEntry.getValue(); + + // remove x-internal if needed (same logic as normalizeComponentsSchemas) + if (property.getExtensions() != null && getRule(REMOVE_X_INTERNAL)) { + Object xInternalValue = property.getExtensions().get(X_INTERNAL); + boolean isInternal = false; + if (xInternalValue instanceof Boolean) { + isInternal = (Boolean) xInternalValue; + } else if (xInternalValue instanceof String) { + isInternal = Boolean.parseBoolean((String) xInternalValue); + } + if (isInternal) { + property.getExtensions().remove(X_INTERNAL); + } + } Schema newProperty = normalizeSchema(property, new HashSet<>()); propertiesEntry.setValue(newProperty); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 3ea7f1ce8727..833f991c9f60 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -1153,6 +1153,42 @@ public void testNormalizerClass() { assertEquals(requiredProperties.getRequired(), null); } + + @Test + public void testRemoveXInternalFromInlineProperties() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/inline_x_internal_test.yaml"); + Schema parentSchema = openAPI.getComponents().getSchemas().get("ParentSchema"); + Schema inlineProperty = (Schema) parentSchema.getProperties().get("inlineXInternalProperty"); + + // Before normalization: x-internal should be present on inline property + assertNotNull(inlineProperty.getExtensions()); + assertEquals(inlineProperty.getExtensions().get("x-internal"), true); + + // Run normalizer with REMOVE_X_INTERNAL=true + Map options = new HashMap<>(); + options.put("REMOVE_X_INTERNAL", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + // After normalization: x-internal should be removed from inline property + Schema parentSchemaAfter = openAPI.getComponents().getSchemas().get("ParentSchema"); + Schema inlinePropertyAfter = (Schema) parentSchemaAfter.getProperties().get("inlineXInternalProperty"); + + // x-internal extension should be removed (null or not present in map) + if (inlinePropertyAfter.getExtensions() != null) { + assertNull(inlinePropertyAfter.getExtensions().get("x-internal")); + } + + // The property itself should still exist (we're removing the flag, not the property) + assertNotNull(inlinePropertyAfter); + assertEquals(inlinePropertyAfter.getType(), "object"); + + // Nested properties should still exist + assertNotNull(inlinePropertyAfter.getProperties()); + assertNotNull(inlinePropertyAfter.getProperties().get("nestedField")); + assertNotNull(inlinePropertyAfter.getProperties().get("nestedNumber")); + } + public static class RemoveRequiredNormalizer extends OpenAPINormalizer { public RemoveRequiredNormalizer(OpenAPI openAPI, Map inputRules) { diff --git a/modules/openapi-generator/src/test/resources/3_0/inline_x_internal_test.yaml b/modules/openapi-generator/src/test/resources/3_0/inline_x_internal_test.yaml new file mode 100644 index 000000000000..d5a07461f1d5 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/inline_x_internal_test.yaml @@ -0,0 +1,24 @@ +openapi: 3.0.0 +info: + version: 1.0.0 + title: Test inline x-internal +components: + schemas: + ParentSchema: + description: Schema with inline x-internal property + type: object + properties: + normalProperty: + type: string + description: A normal property without x-internal + inlineXInternalProperty: + x-internal: true + description: Inline object property marked as x-internal + type: object + properties: + nestedField: + type: string + description: A field inside the inline x-internal object + nestedNumber: + type: integer + description: Another field inside the inline object