chrishoermann / zod-prisma-types

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

[BUG] Incompatibility with prisma-json-types-generator #282

Open RicSala opened 1 month ago

RicSala commented 1 month ago

Describe the bug

(Not sure if it's a bug or a feature, but here it goes...) When trying to combine both libraries, zod-prisma-types does not take into account the typed json fields, thus generating more general type (json) that cannot be assign to the narrower file generated by prisma with the prisma-json-types-generator

Package versions (please complete the following information): "zod": "^3.23.8" "prisma": "^5.17.0", "prisma-json-types-generator": "^3.1.1",

and then I use "npx zod-prisma-types" in the provider configuration.

Additional context It's the recommended generator for json files from prisma: https://www.prisma.io/docs/orm/prisma-client/special-fields-and-types/working-with-json-fields#using-prisma-json-types-generator

If there is a way to achieve the same result only using zod-prisma-types, I would love to know how.

Thanks, the library is pretty useful!

aqos156 commented 3 weeks ago

Hello @RicSala, I have successfully circumvented this problem using custom imports:

model FormType {
  /// [FormTypeFeatures]
  features  Json /// @zod.import(["import { formTypeFeaturesZod } from '../../../validation/formTypeFeatures'"]).custom.use(formTypeFeaturesZod)
}

And in the PrismaJson namespace:

declare global {
  namespace PrismaJson {
    type FormTypeFeatures = PrismaValidation.FormTypeFeatures
  }
}

Where PrismaValidation.FormTypeFeatures is z.infer<typeof formTypeFeaturesZod>. The validation directory contains the custom zod validator for the JSON field.

And to safe check persisting the data I also use:

const prismaClientSingleton = () => {
  return new PrismaClient({
    log: ["info", "error"],
  }).$extends({
    query: {
      formType: {
        create({ args, query }) {
          args.data.features = PrismaValidation.formTypeFeaturesZod.parse(
            args.data.features,
          )
          return query(args)
        },
      },
    },
  })
}

However, I am not sure if the create extension is executed on nested inserts. I think I read something like that in the Prisma docs.

RicSala commented 2 weeks ago

@aqos156 I did exactly that too! But in my case that's not doing the trick, as I get the following generated schema (example with UserCreateInputSchema ):

export const UserCreateInputSchema: z.ZodType<Prisma.UserCreateInput> = z.object({
  ...
  customImage: z.union([ z.lazy(() => JsonNullValueInputSchema),filesUploadedSchema ]),
  ...
  }).strict();

The problem is that I am getting that union with JsonNullValueInputSchema, when it should only be "filesUploadedSchema (I mean, the "JsonNull" is unexpected and causin the issue).

The type created by the library "prisma-json-types-generator" is generating the correct type for "customImage", which does not include a "null".

As the generic in the type notation (Prisma.UserCreateInput) does not fit the inferred type of the schema (because of the null option) it's throwing an error.

Are you doing something different? Are you getting that "jsonNull" too? If so, how come it's not problematic for you?

Cheers!