chrishoermann / zod-prisma-types

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

Type errors when defining models with lowercase names #121

Open kevin-dp opened 1 year ago

kevin-dp commented 1 year ago

When defining Prisma models with lowercase names, some of the generated types are wrong because Prisma capitalizes the model names. Here is a very simple model:

model items {
  value String @id
}

And a snippet from the generated code:

export const itemsFindUniqueArgsSchema: z.ZodType<Prisma.itemsFindUniqueArgs> = z.object({
  select: itemsSelectSchema.optional(),
  where: itemsWhereUniqueInputSchema,
}).strict()

The generated Prisma type is Prisma.itemsFindUniqueArgs but Prisma capitalizes the model name, the correct type would be Prisma.ItemsFindUniqueArgs.

I know that Prisma advocates for capitalizing model names, but still, it would be good to fix this minor issue.

chrishoermann commented 1 year ago

@kevin-dp If I understand this correctly you'd suggest that we capitalize the first letter in each model regardless of the casing of the actual model?

This would definitely be possible but I don't know if this would introduce some other bugs or if it would be easier to stick with the capitalized model names that prisma propagates. 🤔

kevin-dp commented 1 year ago

Hi Chris, ignore what i said above. I was experimenting with different models and I must have seen some old state (probably forgot to re-generate). Prisma does not seem to capitalize model names, i.e. Prisma.itemsFindUniqueArgs is indeed the correct type in the example above. My bad!

kevin-dp commented 1 year ago

Sorry for the confusion, the problem i describe above does occur, but not for itemsFindUniqueArgs (that was my IDE being confused). The problem occurs on Prisma.itemsAggregateArgs and Prisma.itemsGroupByArgs.

See here the complete Prisma schema:

datasource db {
  provider = "postgresql"
  url      = env("PRISMA_DB_URL")
}

generator client {
  provider = "prisma-client-js"
}

generator zod {
  provider      = "zod-prisma-types"
  output        = "./zod"
  addSelectType = true
  relationModel = true
}

model items {
  value String @id
}

And a snippet from the generated schemas:

export const itemsFindManyArgsSchema: z.ZodType<Prisma.itemsFindManyArgs> = z.object({
  select: itemsSelectSchema.optional(),
  where: itemsWhereInputSchema.optional(),
  orderBy: z.union([ itemsOrderByWithRelationInputSchema.array(),itemsOrderByWithRelationInputSchema ]).optional(),
  cursor: itemsWhereUniqueInputSchema.optional(),
  take: z.number().optional(),
  skip: z.number().optional(),
  distinct: ItemsScalarFieldEnumSchema.array().optional(),
}).strict()

export const itemsAggregateArgsSchema: z.ZodType<Prisma.itemsAggregateArgs> = z.object({
  where: itemsWhereInputSchema.optional(),
  orderBy: z.union([ itemsOrderByWithRelationInputSchema.array(),itemsOrderByWithRelationInputSchema ]).optional(),
  cursor: itemsWhereUniqueInputSchema.optional(),
  take: z.number().optional(),
  skip: z.number().optional(),
}).strict()

export const itemsGroupByArgsSchema: z.ZodType<Prisma.itemsGroupByArgs> = z.object({
  where: itemsWhereInputSchema.optional(),
  orderBy: z.union([ itemsOrderByWithAggregationInputSchema.array(),itemsOrderByWithAggregationInputSchema ]).optional(),
  by: ItemsScalarFieldEnumSchema.array(),
  having: itemsScalarWhereWithAggregatesInputSchema.optional(),
  take: z.number().optional(),
  skip: z.number().optional(),
}).strict()

Note the types of the schemas: z.ZodType<Prisma.itemsFindManyArgs>, z.ZodType<Prisma.itemsAggregateArgs>, and z.ZodType<Prisma.itemsGroupByArgs>.

When looking at the generated Prisma client, we notice that the Prisma.itemsFindManyArgs type exists but Prisma.itemsAggregateArgs and Prisma.itemsGroupByArgs do not exist as they are called Prisma.ItemsAggregateArgs and Prisma.ItemsGroupByArgs.

fotoflo commented 1 year ago

I'm having the same error. This is the first time Im compiling this project to deploy to Vercel and I get this error:

./prisma/generated/zod/index.ts:586:45
Type error: Cannot find name 'UrlsCountOutputTypeArgsSchema'. Did you mean 'urlsCountOutputTypeArgsSchema'?

  584 |   userUrlNotifications: z.union([z.boolean(),z.lazy(() => userUrlNotificationsFindManyArgsSchema)]).optional(),
  585 |   userUrlVisits: z.union([z.boolean(),z.lazy(() => userUrlVisitsFindManyArgsSchema)]).optional(),
> 586 |   _count: z.union([z.boolean(),z.lazy(() => UrlsCountOutputTypeArgsSchema)]).optional(),

The generated file looks like this: image

my schema uses lowercase:

model urls {
  id                      String                    @id @default(cuid())

@chrishoermann said

If I understand this correctly you'd suggest that we capitalize the first letter in each model regardless of the casing of the actual model?

This would definitely be possible but I don't know if this would introduce some other bugs or if it would be easier to stick with the capitalized model names that prisma propagates. 🤔

I think it looks like you're just not following the capitalization from my model? I suggest you just follow that capitalization?

mean time... i gotta figure out how to deploy.

kevin-dp commented 1 year ago

@fotoflo I have experienced similar issues indeed.

So there are 2 problems:

I would not automatically capitalize all model names because that might simply not match the table names in the database. I would suggest that we fix the generator such that it capitalizes types the same way Prisma does (even though Prisma is a bit inconsistent on that matter).

fotoflo commented 1 year ago

Are you in the prisma slack? They're pretty good about supporting people - if you want to ask them how their capitalization works In pretty sure they'd tell you

kevin-dp commented 1 year ago

Are you in the prisma slack? They're pretty good about supporting people - if you want to ask them how their capitalization works In pretty sure they'd tell you

I'm not but perhaps i should consider joining, thanks!

chrishoermann commented 1 year ago

@fotoflo @kevin-dp

If none of this helps this can get a bit more complicated:

The mentioned types above are stored in a deeply nested and entagled structure in the dmmf where it is very difficult or nearly impossible to fix an issue like the ones mentioned above in a reasonable amount of time, with a reasonable amout of effort or even at all. This is because we do not have insights in how this dmmf is generated and there is also no documentation, since the dmmf was initially intended to only be used internally in the prisma team.

@fotoflo said:

I think it looks like you're just not following the capitalization from my model? I suggest you just follow that capitalization?

since the information is stored in the dmmf and the generator only reads out this information , the problem my be found somewhere in the dmmf?

I'd suggest we open an issue or (as mentiond by @fotoflo) ask in the slack channel if this is a known problem, if this is intended behaviour, if lowercase names are not recommended or if the prisma team even advice against using them.

kevin-dp commented 1 year ago

Have you tried using uppercase in your model names to see if the error persists?

I've not encountered such issues on models starting with an uppercase letter.

The mentioned types above are stored in a deeply nested and entagled structure in the dmmf

I see, i was not aware that the types themselves are also stored in the dmmf. Although it's a bit weird that some of the types that are stored in the dmmf do not match the generated types in the Prisma client. Will indeed need to discuss on Prisma slack or open an issue on their github.

Regarding @fotoflo's problem, that problem arises in the names of the generated Zod schemas and in references to those schemas. Therefore it looks like a problem of the generator and not the dmmf? Perhaps i'm missing something here.

Huh-David commented 1 month ago

I have had some problems while using TimeScaleDB which requires table names to be lowercase. After adjusting the table name, prisma did some weird things to the names: Code - Insiders 2024-08-28 15 02 01

Some names are lowercase and some uppercase in the beginning. The generated index.ts was pretty consistent with lowercase (which should be right I guess). Also deleted the node_modules multiple times to be sure about that.

Some workaround for this issue:

model LocationHistory {
  latitude   Float
  longitude  Float
  voltage    Float?
  // ...
  recordedAt DateTime @default(now())
  locationId Int
  location   Location @relation(fields: [locationId], references: [id])

  @@unique([locationId, recordedAt], name: "locationId_recordedAt")
  @@map("location_history")
}

With this mapping I can use TimeScaleDB without a problem and have consistent naming across all prisma schemas.

Maybe this helps others :)