zod-prisma-types icon indicating copy to clipboard operation
zod-prisma-types copied to clipboard

Type errors when defining models with lowercase names

Open kevin-dp opened this issue 2 years ago • 11 comments
trafficstars

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.

kevin-dp avatar Apr 03 '23 12:04 kevin-dp

@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. 🤔

chrishoermann avatar Apr 03 '23 18:04 chrishoermann

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 avatar Apr 03 '23 19:04 kevin-dp

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.

kevin-dp avatar Apr 04 '23 09:04 kevin-dp

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.

fotoflo avatar Apr 07 '23 05:04 fotoflo

@fotoflo I have experienced similar issues indeed.

So there are 2 problems:

  • Prisma does not seem to be consistent in their naming. For most types they keep the capitalization of the original model, but for some types they capitalize the first letter if it is lowercase. This is not catched by the current implementation of zod-prisma-types so it would be good to fix this such that it capitalizes types the same way Prisma does.
  • Some of the generated schema names are not capitalized correctly as pointed out by @fotoflo above.

@chrishoermann

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?

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).

kevin-dp avatar Apr 07 '23 08:04 kevin-dp

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

fotoflo avatar Apr 07 '23 08:04 fotoflo

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!

kevin-dp avatar Apr 07 '23 08:04 kevin-dp

@fotoflo @kevin-dp

  • Have you tried using uppercase in your model names to see if the error persists?
  • sometimes deleting the node_modules or the generated prisma client folder also solves issues like that. I had a few times where the schema changes hadn't been reflected to the prisma index.d.ts.

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

  • in case someone does not know: the information the generator relies on is stored in the prisma dmmf. That's a huge object that is provided by prisma via tools from the prisma/internals and/or prisma/generator-helper packages. This dmmf contains all the information about models, types, therelations, fields, etc.
  • since this dmmf is the single source of truth when it comes to representing the schema content, we as generator maintainers/creators need to trust that the information provided in the dmmf is valid.

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.

chrishoermann avatar Apr 07 '23 18:04 chrishoermann

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.

kevin-dp avatar Apr 07 '23 21:04 kevin-dp

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 :)

Huh-David avatar Aug 28 '24 13:08 Huh-David

running into the same problem here

hammer0x419 avatar Jan 20 '25 19:01 hammer0x419