-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DtoCastType is being ignored #54
Comments
Currently, the Do you need it to be cast only for the class property type, only for the ApiProperty type, or for both? |
Assuming a service flattens the data and returns an instance satisfying the entity type, casting the property type and the ApiProperty type is the way to go in this case (I mainly need all entities to be present in the DMMF which is not the case with relation tables of many-to-many relationships in prisma by default). Only casting the ApiProperty type would mean that a service returns an instance of the explicit many-to-many relation, while the API returns the implicit version. Further, this would mean that the conversion needs to happen within a controller which is most definitely the wrong place for it 🤔. All other property types are consistent with the type of their ApiProperty type, correct? It would be unexpected behavior for the types to differ if a cast is used. |
I think, the reason that the DtoCastType annotation only applies to the property type is that it was designed to cast the type to something from an external package. Whereas for ApiProperty type, it would have made no sense, since the imported type or class doesn't have any swagger decorators or anything alike, or would even break it. In the original PR (#12) we were only talking about Json fields that would be properly typed after casting. So, I'm not sure, if changing the behavior such that also ApiProperty type is casted, if it would break anything. Or if it needs some special annotation that has this different behavior (e.g. |
Is there a reason why this only applies to scalars? I don't see many ways this could lead to unexpected errors as the annotation needs to be provided explicitly for the cast to happen. If the user wants to override the type of a relation to something else explicitly, why not let them?
I think it would be a good idea to split up the overrides for the property type and the ApiProperty type into two separate annotations. This would provide maximum flexibility depending on the use case. Could be named |
Yes, overriding the property type shouldn't break anything. As I said, the only reason, for which the current behavior is as it is now, is that the original PR was only focusing on Json fields. So overriding the relation fields should be no problem in general. My only concern above was the (automatic) override of the ApiProperty types.
These are better (or more precise) namings of the annotations. Also better than |
Would be highly appreciated as I currently don't have the resources to provide a PR. Thank you very much. |
You can now please test 1.24.0-beta2. It should now work for all fields including relation fields with both new annotations as stated above. However, there is some not very clear behavior when it comes to relation fields with annotions like |
Thanks a bunch! I will hopefully get around to testing within the next week. |
Did you find some time to test it? |
add DtoApiOverrideType annotation refactor makeImports
Hello! Sorry for the delay - I am finally getting to test this. Here are my first findings: The following model is used for the provided test cases: model Team {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String
about String?
thumbnailUrl String?
photoUrl String?
externalId String?
externalHost ExternalHostType?
/// @DtoApiHidden
registrations TeamRegistration[]
members PlayerOnTeam[]
@@unique([externalId, externalHost])
} Test case 1 - using @DtoOverrideType isolated: /// @DtoOverrideType(Player, ./player.entity)
members PlayerOnTeam[] Produces correct result. @ApiProperty({
type: () => PlayerOnTeam,
isArray: true,
required: false,
})
members?: Player[]; Test case 2 - using @DtoApiOverrideType isolated: /// @DtoApiOverrideType(Player, ./player.entity)
members PlayerOnTeam[] Produces correct result. @ApiProperty({
type: Player,
isArray: true,
required: false,
})
members?: PlayerOnTeam[]; Test case 3 - using @DtoOverrideType and @DtoOverrideApiType in combination: /// @DtoOverrideType(Player, ./player.entity)
/// @DtoApiOverrideType(Player, ./player.entity)
members PlayerOnTeam[] Produces correct result. @ApiProperty({
type: Player,
isArray: true,
required: false,
})
members?: Player[]; Summary:
|
Thanks! However, it's not |
Ah, my bad... One shouldn't do stuff like this in a rush 🙃 - I will update my comment. Regarding the name: I would keep it consistent with whatever other annotations you have concerning Maybe |
Also on an unrelated note: /// @DtoOverrideType(Player, ./player.entity)
/// @DtoApiOverrideType(Player, ./player.entity)
members PlayerOnTeam[] will generate @ApiProperty({
type: Player,
isArray: true,
required: false,
})
members?: Player[]; which will then again produce "members": {
"type": "array",
"items": {
"required": false,
"type": "array",
"items": {
"$ref": "#/components/schemas/Player"
}
}
} in comparison to if I add no annotations at all @ApiProperty({
type: () => PlayerOnTeam,
isArray: true,
required: false,
})
members?: PlayerOnTeam[]; which produces "members": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PlayerOnTeam"
}
} It would seem like overriding the type from a function to providing the class explicitly will mess up the typing, exposing the data type as a two-dimensional array, which is incorrect. Manually changing the @ApiProperty({
type: () => Player,
isArray: true,
required: false,
})
members?: Player[]; produces the correct result: "members": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Player"
}
} |
I changed the annotation to |
Awesome - the overrides seem to work now! I have one more question regarding the use of the /// @DtoRelationRequired
/// @DtoOverrideApiPropertyType(Player, ./player.entity)
members PlayerOnTeam[] generates @ApiProperty({
type: () => Player,
isArray: true,
required: false,
})
members?: PlayerOnTeam[]; Using |
I actually haven't touched the |
Did you perchance have the time to look at |
Sorry for the late respone. November was quite busy. So yes, for me it looked like a bug. Please try 1.24.0-beta6 |
* brakebein/main: version 1.24.1 fix Decimal type definition Brakebein#63 version 1.24.0 update readme deprecate outputApiPropertyType fix @DtoRelationRequired Brakebein#54 change DtoApiOverrideType to DtoOverrideApiPropertyType Brakebein#54 fix encapsulateString for null Brakebein#58 fix encapsulateString for date strings Brakebein#58 add @DtoCreateRequired decorator Brakebein#55 replace DtoCastType with DtoOverrrideType Brakebein#54 fix don't generate enums.ts if there are no enums defined add flag to show fields with default attribute by default Brakebein#51 add enumName to ApiProperty Brakebein#52 generate enums if noDependencies = true Brakebein#48 wrap relations as type to fix circular dependencies Brakebein#49 shorten duplicate code checks on double imports sort all imports shorten duplicate code to make class-validator imports fix ApiProperty default value if field is a list
Hello! Could it be that @DtoCastType is currently broken? During my tests, the following schema snippet will result in the cast being ignored. It seems like the cast import is generated correctly, but the type annotation is not updated.
Due to internal reasons, I need to express my m2m explicitly - they are transformed to the implicit counterpart for the API response, however. Therefore, I need a way to adjust the OpenAPI response model for the generated docs, which is why I would like to cast the m2m relation fields. I am thankful for any help on this matter!
The text was updated successfully, but these errors were encountered: