Brakebein / prisma-generator-nestjs-dto

Generates NestJS DTO classes from Prisma Schema
Apache License 2.0
51 stars 28 forks source link

Add @DtoCreateRequired decorator #55

Open gwesterman opened 1 month ago

gwesterman commented 1 month ago

I need to generate a CreateDTO that contains a required field for the id of an optional relation that can be set to null after the entry is created. This would typically happen via onDelete: SetNull.

My use-case is a chat in which messages require a reference to a user/author on creation, but this reference can be null once the user is deleted, which in turn should not cause the message to be deleted.

In the model below this works well for Channel, which is a non-optional reference. The channelId field on the CreateMessageDto is required. But this is not the case for authorId.

This is a simplified/partial version of my model:

// schema.prisma
model User {
   id        String   @id @unique
   createdAt DateTime @default(now())
   updatedAt DateTime @updatedAt

   name      String

   messages  Message[]
}

model Message {
   id        String   @id @default(cuid())
   createdAt DateTime @default(now())
   updatedAt DateTime @updatedAt

   author    User?   @relation(fields: [authorId], references: [id], onDelete: SetNull)
   /// @DtoRelationIncludeId
   /// @IsRequired
   authorId  String?

   channel   Channel @relation(fields: [channelId], references: [id], onDelete: Cascade)
   /// @DtoRelationIncludeId
   /// @IsRequired
   channelId String

   content   String
}

The generated CreateMessageDto looks like this:

// create-message.dto
export class CreateMessageDto {
   @ApiProperty({
      type: 'string',
      required: false,
      nullable: true
   })
   @IsOptional()
   @IsString()
   authorId?: string | null;
   @ApiProperty({
      type: 'string'
   })
   @IsNotEmpty()
   @IsString()
   channelId!: string;
   @ApiProperty({
      type: 'string'
   })
   @IsNotEmpty()
   @IsString()
   content!: string;
}

I've tried different combinations of decorators, but cannot get it to work. Am I missing something?

Could a new decorator, for example @DtoCreateRequired help in this case?

Brakebein commented 4 weeks ago

Yes, similar to the @DtoUpdateRequired annotation there should be an equivalent annotation for the CreateDto. I will add it within the next days.

Brakebein commented 3 weeks ago

@DtoCreateRequired annotation has been added in 1.24.0-beta3.

(I'm waiting for some feedback on other features before releasing the next proper version.)

gwesterman commented 3 weeks ago

Thank you for implementing this so quickly!

I can confirm, that @DtoCreateRequired is working for me, but only in conjunction with @DtoRelationIncludeId. Is this intended?

Brakebein commented 3 weeks ago

Currently, each annotation fulfills a different task: @DtoRelationIncludeId only makes the ID field visible, which is otherwise hidden by default. @DtoCreateRequired only turns an optional field to required.

But if I think about it, you are probably right. similar to @DtoCreateOptional which unhides an omitted field, you would expect that @DtoCreateRequired unhides the field as well.

What I need to check is, if @DtoCreateOptional only works for normal fields, but also for relation-related fields making @DtoRelationIncludeId kind of redundant?