swagger icon indicating copy to clipboard operation
swagger copied to clipboard

fix(schema): preserve items schema when metadata.items is already defined

Open bas0N opened this issue 1 month ago • 1 comments

fix(schema): preserve items schema when metadata.items is already defined

Fixes transformToArraySchemaProperty overwriting existing items schema from zod-openapi generated classes, ensuring correct OpenAPI schemas.

PR Checklist

Please check if your PR fulfills the following requirements:

  • [x] The commit message follows our guidelines: https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md
  • [x] Tests for the changes have been added (for bug fixes / features)
  • [ ] Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • [x] Bugfix
  • [ ] Feature
  • [ ] Code style update (formatting, local variables)
  • [ ] Refactoring (no functional changes, no api changes)
  • [ ] Build related changes
  • [ ] CI related changes
  • [ ] Other... Please describe:

What is the current behavior?

When using @ApiQuery({ type: SomeClass }) where SomeClass is generated by libraries like @anatine/zod-openapi that pre-define items schema in metadata, transformToArraySchemaProperty was overwriting the existing items schema with { type: 'array' } instead of preserving it.

This occurred because when type parameter is the string 'array', the function would create new items from the type parameter, ignoring the existing metadata.items that contained the correct schema definition.

Example of incorrect output:

{
  "schema": {
    "type": "array",
    "items": { "type": "array" } 
  }
}

Issue Number: #3624

The transformToArraySchemaProperty method now checks if metadata.items exists first. If it does, it preserves the existing items schema and merges it with moved properties (format, min/max, etc.). This ensures that pre-defined items schemas from zod-openapi and similar libraries are correctly preserved in the OpenAPI output.

Example of correct output:

{
  "schema": {
    "type": "array",
    "items": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "enum": ["asc", "desc"]
      }
    } 
  }
}

The fix is backward compatible - when metadata.items is not defined, it falls back to the original behavior of creating items from the type parameter.

Does this PR introduce a breaking change?

  • [ ] Yes
  • [x] No

Other information

Test coverage:

  • Added 3 test cases in test/services/schema-object-factory.spec.ts:
    1. Preserves items schema when metadata.items is already defined and type is string
    2. Uses type parameter when metadata.items is not defined (backward compatibility)
    3. Uses type object when provided

bas0N avatar Nov 21 '25 00:11 bas0N

@kamilmysliwiec could you please review/merge when you have a moment? thanks!

bas0N avatar Nov 21 '25 13:11 bas0N