swagger
swagger copied to clipboard
feat(IntersectionType): add support for composing multiple classes
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)
- Potentially the OpenAPI / Mapped Types / Intersection docs and example could be updated to show that the updated
IntersectionType
mapper now supports multiple classes. - Happy to open another PR for the docs.nestjs.com repo if that would be desirable.
- Potentially the OpenAPI / Mapped Types / Intersection docs and example could be updated to show that the updated
PR Type
What kind of change does this PR introduce?
- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, local variables)
- [x] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Other... Please describe:
What is the current behavior?
Issue Number: N/A
The current Swagger IntersectionType
mapper only supports passing 2 classes eg.
class CreateUserDto {
@ApiProperty({ required: true })
@IsEmail()
login: string
@ApiProperty({ required: true })
@MinLength(8)
password: string
}
class UserDto {
@ApiProperty({ required: true })
@IsString()
firstName: string
@ApiProperty({ required: true })
@IsString()
lastName: string
}
class UpdateUserDto extends IntersectionType(UserDto, CreateUserDto)
You cannot pass more than 2 classes eg.
class MappedClass1 extends IntersectionType(Class1, Class2, Class3) // Expected 2 arguments, but got 3.
class MappedClass2 extends IntersectionType(Class1, Class2, Class3, Class4) // Expected 2 arguments, but got 4.
What is the new behavior?
- The updated Swagger
IntersectionType
mapper supports 2-8 classes
class MappedClass1 extends IntersectionType(Class1, Class2) // sure
class MappedClass2 extends IntersectionType(Class1, Class2, Class3) // nice
class MappedClass3 extends IntersectionType(Class1, Class2, Class3, Class4) // keep going
class MappedClass4 extends IntersectionType(Class1, Class2, Class3, Class4, Class5, Class6, Class7, Class8) // no sweat
The implementation actually supports an infinite number of classes (just like @nestjs/mapped-types
does) ...however I have only added interfaces for up to 8 classes...hopefully that will be suffice!
Does this PR introduce a breaking change?
- [ ] Yes
- [x] No
Other information
I have leveraged the IntersectionType
mapper function from @nestjs/mapped-types
rather than rewriting that logic as it had been implemented previously.
The upside to this approach is it reduces the surface area of the Swagger IntersectionType
mapper—leveraging the existing implementation and test suite.
The downside is that there are a couple of loops over the passed classes—one for the call to the mapped-types IntersectionType
mapper and another to add the Swagger OpenAPI decorators in this IntersectionType
mapper.
However this really is a moot point given that the number of classes will be at most 8 😅
Essentially this solution just augments the target class with the Swagger/OpenAPI related decorators. It leaves the validation and transformation inheritance to the IntersectionType
function from mapped-types
.
Finally, I have added another test to validate that the class-validator
decorators are working as expected when composing 3 classes together. This is somewhat duplicative of the tests in mapped-types
but I don't think it hurts to be extra safe!
Would this be the same as IntersectionType(IntersectionType(Class1, Class2), Class3)
etc?
@jmcdo29 correct ✅
https://github.com/nestjs/swagger/pull/2227