chrishoermann / zod-prisma-types

Generator creates zod types for your prisma models with advanced validation
Other
626 stars 47 forks source link

WIP Optional Default Relations #117

Closed MichaelOren closed 1 year ago

MichaelOren commented 1 year ago

Hey Chris,

I was using Relations that had defaults in them which I wanted to be Optional

I assumed having both of the following would do this by default 🤔

  createOptionalDefaultValuesTypes  = true
  createRelationValuesTypes = true

I gave updating the code a go but got stuck 😂

import { type PostWithRelations, PostWithRelationsSchema, PostOptionalDefaultsWithRelationsSchema } from './PostSchema'
import { type ProfileWithRelations, ProfileWithRelationsSchema, ProfileOptionalDefaultsWithRelationsSchema } from './ProfileSchema'
import { type LocationWithRelations, LocationWithRelationsSchema, LocationOptionalDefaultsWithRelationsSchema } from './LocationSchema'

The issue with the code below is that if there is a relation model without any default fields in it, we should not point to the OptionalDefaultsRelation (LocationOptionalDefaultsWithRelationsSchema in this case)

If you have a workaround that would be great 🙏

Otherwise if it is not possible, I am happy to close this PR 😄

The current workaround is to enable partial types, so that the id in the relation is optional that way

chrishoermann commented 1 year ago

@MichaelOren thanks for digging into this. I think I undestand the problem:

for example a schema like this:

export type UserOptionalDefaultsWithRelations = z.infer<typeof UserOptionalDefaultsSchema> & UserRelations

export const UserOptionalDefaultsWithRelationsSchema: z.ZodType<UserOptionalDefaultsWithRelations> = UserOptionalDefaultsSchema.merge(z.object({
  posts: z.lazy(() => PostWithRelationsSchema).array().length(2, { message: "error" }).min(1).max(2).nonempty({ message: "error" }),
  profile: z.lazy(() => ProfileWithRelationsSchema).nullable(),
  location: z.lazy(() => LocationWithRelationsSchema).nullable(),
}))

should look like this:

export type UserOptionalDefaultsWithRelations = z.infer<typeof UserOptionalDefaultsSchema> & UserRelations

export const UserOptionalDefaultsWithRelationsSchema: z.ZodType<UserOptionalDefaultsWithRelations> = UserOptionalDefaultsSchema.merge(z.object({
  posts: z.lazy(() => PostOptionalDefaultsWithRelationsSchema).array().length(2, { message: "error" }).min(1).max(2).nonempty({ message: "error" }),
  profile: z.lazy(() => ProfileOptionalDefaultsWithRelationsSchema).nullable(),
  location: z.lazy(() => LocationOptionalDefaultsWithRelationsSchema).nullable(),
}))

acutally it was my intention to use this type. So this is a mistake on my end. I'll see to it. 😅

chrishoermann commented 1 year ago

I'm closing this since I have implemented/fixed the behaviour that on [modelType]OptionalDefaultWithRelationsSchema the OptionalDefaultWithRelations types are used in the relations in 2.5.4.