diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java index 38a512afc947..251e4f25140a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java @@ -184,6 +184,11 @@ public Map postProcessAllModels(Map objs) for (ModelMap mo : entry.getModels()) { CodegenModel cm = mo.getModel(); + // Filter out primitive types from parent property + if (cm.parent != null && isPrimitiveType(cm.parent)) { + cm.parent = null; + } + // Add additional filename information for imports mo.put("tsImports", toTsImports(cm, cm.imports)); } @@ -289,6 +294,26 @@ private boolean isLanguagePrimitive(String type) { return languageSpecificPrimitives.contains(type); } + /** + * Check if a type is a primitive TypeScript type (string, boolean, number). + * This is used to filter out primitive types from the parent property. + * + * @param type the type to check + * @return true if the type is a primitive type + */ + private boolean isPrimitiveType(String type) { + if (type == null) { + return false; + } + // Check for primitive types (case-insensitive) + String lowerType = type.toLowerCase(Locale.ROOT); + return "string".equals(lowerType) || + "boolean".equals(lowerType) || + "number".equals(lowerType) || + "any".equals(lowerType) || + "array".equals(lowerType); + } + // Determines if the given type is a generic/templated type (ie. ArrayList) private boolean isLanguageGenericType(String type) { for (String genericType : languageGenericTypes) { @@ -323,6 +348,15 @@ private String removeModelPrefixSuffix(String name) { return result; } + @Override + protected void addParentFromContainer(CodegenModel model, Schema schema) { + super.addParentFromContainer(model, schema); + // Filter out primitive types from parent property + if (model.parent != null && isPrimitiveType(model.parent)) { + model.parent = null; + } + } + @Override protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) { super.addAdditionPropertiesToCodeGenModel(codegenModel, schema); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java index 23e342f4bc27..73da32e0f435 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java @@ -354,4 +354,35 @@ public void mappedFromModelTest() { Assert.assertEquals(cm.name, "ApiResponse"); Assert.assertEquals(cm.classFilename, mappedName); } + + @Test(description = "should exclude TypeScript primitive types from parent property") + public void modelShouldExcludePrimitiveTypesFromParentPropertyTest() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/model_with_additional_properties.yaml"); + final DefaultCodegen codegen = new TypeScriptNodeClientCodegen(); + codegen.setOpenAPI(openAPI); + + // Check that all models with primitive additionalProperties don't have parent property set + for (String modelName : openAPI.getComponents().getSchemas().keySet()) { + final Schema schema = openAPI.getComponents().getSchemas().get(modelName); + final CodegenModel model = codegen.fromModel(modelName, schema); + Assert.assertNull(model.parent, "Model " + modelName + " should not have a parent property"); + } + } + + @Test(description = "should extend from parent") + public void shouldExtendFromParentTest() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/allOf.yaml"); + final DefaultCodegen codegen = new TypeScriptNodeClientCodegen(); + codegen.setOpenAPI(openAPI); + + // Check that Child model extends Person + final Schema childSchema = openAPI.getComponents().getSchemas().get("Child"); + final CodegenModel childModel = codegen.fromModel("Child", childSchema); + Assert.assertEquals(childModel.parent, "Person"); + + // Check that Adult model extends Person + final Schema adultSchema = openAPI.getComponents().getSchemas().get("Adult"); + final CodegenModel adultModel = codegen.fromModel("Adult", adultSchema); + Assert.assertEquals(adultModel.parent, "Person"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/model_with_additional_properties.yaml b/modules/openapi-generator/src/test/resources/3_0/model_with_additional_properties.yaml new file mode 100644 index 000000000000..c2a6e64e30e6 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/model_with_additional_properties.yaml @@ -0,0 +1,65 @@ +openapi: 3.0.0 +info: + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +paths: + /pet: + get: + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' +components: + schemas: + Pet: + title: a Pet with string additionalProperties + type: object + properties: + id: + type: integer + format: int64 + additionalProperties: + type: string + PetBoolean: + title: a Pet with boolean additionalProperties + type: object + properties: + id: + type: integer + format: int64 + additionalProperties: + type: boolean + PetNumber: + title: a Pet with number additionalProperties + type: object + properties: + id: + type: integer + format: int64 + additionalProperties: + type: number + PetAny: + title: a Pet with any additionalProperties + type: object + properties: + id: + type: integer + format: int64 + additionalProperties: true + PetArray: + title: a Pet with array additionalProperties + type: object + properties: + id: + type: integer + format: int64 + additionalProperties: + type: array + items: + type: string