Repository: nestjs/swagger
Pull request #2553 (2023-08-05 09:01:50)

fix(plugin): Fix nullable enum not having a proper enum type
## 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?

<!-- Please check the one that applies to this PR using "x". -->
- [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?
Currently when having a nullable enum `SomeEnum | null`, the generated output from the plugin is missing the `enum` attribute. It looks like this in the unit test:

```typescript
...
nullableEnumValue: { required: true, nullable: true }
...
```

This would further down the line crash the application start with this error: https://github.com/nestjs/swagger/blob/655528509192b9ecbc18f50ba32252b0bf520677/lib/services/schema-object-factory.ts#L330-L332

My usual workaround was to manually annotate these cases, however, I implemented a fix with this PR for the plugin.

## What is the new behavior?
With this fix, the generated output look as expected:

```typescript
...
nullableEnumValue: { required: true, nullable: true, enum: OneValueEnum }
...
```


## Does this PR introduce a breaking change?
- [ ] Yes
- [x] No

<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->


## Other information



Patch:
diff --git a/lib/plugin/utils/plugin-utils.ts b/lib/plugin/utils/plugin-utils.ts
index 2bf55a59..3608931f 100644
--- a/lib/plugin/utils/plugin-utils.ts
+++ b/lib/plugin/utils/plugin-utils.ts
@@ -246,7 +246,7 @@ export function isAutoGeneratedEnumUnion(
       return undefined;
     }
     const undefinedTypeIndex = type.types.findIndex(
-      (type: any) => type.intrinsicName === 'undefined'
+      (type: any) => type.intrinsicName === 'undefined' || type.intrinsicName === 'null'
     );
     if (undefinedTypeIndex < 0) {
       return undefined;


Test patch:
diff --git a/test/plugin/fixtures/nullable.dto.ts b/test/plugin/fixtures/nullable.dto.ts
index c94ea481..86572b2c 100644
--- a/test/plugin/fixtures/nullable.dto.ts
+++ b/test/plugin/fixtures/nullable.dto.ts
@@ -1,4 +1,8 @@
 export const nullableDtoText = `
+enum OneValueEnum {
+    ONE
+}
+
 export class NullableDto {
   @ApiProperty()
   stringValue: string | null;
@@ -8,13 +12,23 @@ export class NullableDto {
   optionalString?: string;
   @ApiProperty()
   undefinedString: string | undefined;
+  @ApiProperty()
+  nullableEnumValue: OneValueEnum | null;
+  @ApiProperty()
+  optionalEnumValue?: OneValueEnum;
+  @ApiProperty()
+  undefinedEnumValue: OneValueEnum | undefined;
 }
 `;
 
 export const nullableDtoTextTranspiled = `import * as openapi from "@nestjs/swagger";
+var OneValueEnum;
+(function (OneValueEnum) {
+    OneValueEnum[OneValueEnum["ONE"] = 0] = "ONE";
+})(OneValueEnum || (OneValueEnum = {}));
 export class NullableDto {
     static _OPENAPI_METADATA_FACTORY() {
-        return { stringValue: { required: true, type: () => String, nullable: true }, stringArr: { required: true, type: () => [String], nullable: true }, optionalString: { required: false, type: () => String }, undefinedString: { required: true, type: () => String } };
+        return { stringValue: { required: true, type: () => String, nullable: true }, stringArr: { required: true, type: () => [String], nullable: true }, optionalString: { required: false, type: () => String }, undefinedString: { required: true, type: () => String }, nullableEnumValue: { required: true, nullable: true, enum: OneValueEnum }, optionalEnumValue: { required: false, enum: OneValueEnum }, undefinedEnumValue: { required: true, enum: OneValueEnum } };
     }
 }
 __decorate([
@@ -29,4 +43,13 @@ __decorate([
 __decorate([
     ApiProperty()
 ], NullableDto.prototype, "undefinedString", void 0);
+__decorate([
+    ApiProperty()
+], NullableDto.prototype, "nullableEnumValue", void 0);
+__decorate([
+    ApiProperty()
+], NullableDto.prototype, "optionalEnumValue", void 0);
+__decorate([
+    ApiProperty()
+], NullableDto.prototype, "undefinedEnumValue", void 0);
 `;