swagger icon indicating copy to clipboard operation
swagger copied to clipboard

Enum arrays are broken in plugin-generated metadata

Open ArielPrevu3D opened this issue 2 years ago • 3 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Current behavior

When a model's property is an array of an enum, the plugin never sets isArray to true in the metadata. The faulty metadata is then merged with the ApiProperty decorator metadata, resulting in a broken schema.

Resulting schema:

  {
      ...
      "OrganizationResponseDto": {
        "type": "object",
        "properties": {
          "featureFlags": {
            "enum": ["SAMLIdP"],
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["SAMLIdP"]
            }
          }
       }
      ...
  }

This happens because isArrayType is always set to false when isEnumMember is true. The original enum type definition is never going to be an array. https://github.com/nestjs/swagger/blob/aba3038c9b1f68e53ed51c4f41121aac68562edc/lib/plugin/visitors/model-class.visitor.ts#L354

Commenting that line was enough to fix the issue.

Minimum reproduction code

https://github.com/nestjs/swagger/

Steps to reproduce

  1. Create a DTO with an enum array that's imported from another module
import {
  OrganizationFeature,
} from '../entities/organization.entity';
export class OrganizationResponseDto {
  id: string;
  @ApiProperty({
    enum: OrganizationFeature,
    isArray: true,
  })
  featureFlags: Array<OrganizationFeature>;
}
  1. Configure nest-cli.json to enable nestjs/swagger plugin
{
  "compilerOptions": {
    "plugins": [{
        "name": "@nestjs/swagger",
        "options": {
          "classValidatorShim": false,
          "introspectComments": false,
          "dtoFileNameSuffix": ".dto.ts"
        }
      }
    ]
  }
}
  1. Compile and observe the resulting _OPENAPI_METADATA_FACTORY generated by the plugin in the dto's .js file

Expected behavior

The resulting _OPENAPI_METADATA_FACTORY generated by the plugin should set isArray to true when the corresponding property is an array of enum.

Package version

4.8.2

NestJS version

7.6.18

Node.js version

14.16.1

In which operating systems have you tested?

  • [ ] macOS
  • [X] Windows
  • [X] Linux

Other

No response

ArielPrevu3D avatar Nov 17 '21 21:11 ArielPrevu3D

Would you like to create a PR to address this issue?

kamilmysliwiec avatar Nov 18 '21 09:11 kamilmysliwiec

I created a PR https://github.com/nestjs/swagger/pull/1696

I will check back to fix your comments whenever I have some downtime

ArielPrevu3D avatar Nov 24 '21 22:11 ArielPrevu3D

I'm not sure if my problem is connected, I'm experiencing something similar with @ApiQuery, the following only produces a singular enum query param:

@ApiQuery({
    name: 'fieldName',
    required: false,
    isArray: true,
    enum: MyEnum,
    enumName: 'MyEnum',
  })

BUT if I add any value for type it works. Maybe isArray is only considered when type is also present?

KiwiKilian avatar Dec 23 '21 10:12 KiwiKilian

https://github.com/nestjs/swagger/pull/1696

kamilmysliwiec avatar Nov 08 '23 10:11 kamilmysliwiec