Giter Club home page Giter Club logo

prisma-zod-generator's Introduction

Prisma Zod Generator

npm version npm HitCount npm

Automatically generate Zod schemas from your Prisma Schema, and use them to validate your API endpoints or any other use you have. Updates every time npx prisma generate runs.

Buy Me A Coffee

Table of Contents

Supported Prisma Versions

Prisma 4

  • 0.3.0 and higher

Prisma 2/3

  • 0.2.0 and lower

Installation

Using npm:

 npm install prisma-zod-generator

Using yarn:

 yarn add prisma-zod-generator

Usage

1- Star this repo ๐Ÿ˜‰

2- Add the generator to your Prisma schema

generator zod {
  provider = "prisma-zod-generator"
}

3- Enable strict mode in tsconfig as it is required by Zod, and considered a Typescript best practice

{
  "compilerOptions": {
    "strict": true
  }
}

4- Running npx prisma generate for the following schema.prisma

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  title     String
  content   String?
  published Boolean  @default(false)
  viewCount Int      @default(0)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
  likes     BigInt
}

will generate the following files

Zod Schemas

5- Use generated schemas somewhere in your API logic, like middleware or decorator

import { PostCreateOneSchema } from './prisma/generated/schemas/createOnePost.schema';

app.post('/blog', async (req, res, next) => {
  const { body } = req;
  await PostCreateOneSchema.parse(body);
});

Customizations

Skipping entire models

/// @@Gen.model(hide: true)
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
}

Additional Options

Option Description Type Default
output Output directory for the generated zod schemas string ./generated
isGenerateSelect Enables the generation of Select related schemas and the select property boolean false
isGenerateInclude Enables the generation of Include related schemas and the include property boolean false

Use additional options in the schema.prisma

generator zod {
  provider          = "prisma-zod-generator"
  output            = "./generated-zod-schemas"
  isGenerateSelect  = true
  isGenerateInclude = true
}

prisma-zod-generator's People

Contributors

alitnk avatar altarrok avatar bitphoenix avatar carloschida avatar kristinlindquist avatar lottamus avatar omar-dulaimi avatar revitate avatar scottyeck avatar shahidul1004 avatar stirearlankar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

prisma-zod-generator's Issues

Prisma 5.7.0 upsert opertions

Bug description

I have a following error during compilation when I trying to use types.

  The types of '_type.update' are incompatible between these types.
    Type '(userUpdateWithoutProfileInput | userUncheckedUpdateWithoutProfileInput) & (userUpdateWithoutProfileInput | userUncheckedUpdateWithoutProfileInput | undefined)' is not assignable to type '(Without<userUpdateWithoutProfileInput, userUncheckedUpdateWithoutProfileInput> & userUncheckedUpdateWithoutProfileInput) | (Without<...> & userUpdateWithoutProfileInput)'.
      Type 'userUpdateWithoutProfileInput & userUncheckedUpdateWithoutProfileInput' is not assignable to type '(Without<userUpdateWithoutProfileInput, userUncheckedUpdateWithoutProfileInput> & userUncheckedUpdateWithoutProfileInput) | (Without<...> & userUpdateWithoutProfileInput)'.
        Type 'userUpdateWithoutProfileInput & userUncheckedUpdateWithoutProfileInput' is not assignable to type 'Without<userUncheckedUpdateWithoutProfileInput, userUpdateWithoutProfileInput> & userUpdateWithoutProfileInput'.
          Type 'userUpdateWithoutProfileInput & userUncheckedUpdateWithoutProfileInput' is not assignable to type 'Without<userUncheckedUpdateWithoutProfileInput, userUpdateWithoutProfileInput>'.
            Types of property 'ipdId' are incompatible.
              Type 'string | NullableStringFieldUpdateOperationsInput | null | undefined' is not assignable to type 'undefined'.
                Type 'null' is not assignable to type 'undefined'.ts(2322)

The error happens with this:

  export type NullableStringFieldUpdateOperationsInput = {
    set?: string | null
  }

How to reproduce

Generate with mentioned prisma version and see upsert operation result.

UPD: another case is multiple unique keys in the model - the schema is generated incorrectly. It breaks the compilation.

Expected behavior

No response

Prisma information

Unable to provide

Environment & setup

  • OS:
  • Database:
  • Node.js version:
    Mac, Postgres, latest Node 18

Prisma Version

5.7.0

[feature] Schema of Prisma's Return Value Required

Problem

I am using fastify + fastify-zod.

The fastify-zod required a return schema.

Suggested solution

Would you consider adding the payload schema?

Alternatives

Or I can contribute some code, now the code structure is very clear.

How about generating something called createManyXXXActionResult.schema.ts/findManyXXXActionResult.schema.ts ?

Doesn't work with fieldReference

Bug description

With field reference enabled the reference schemas are not generated. Take a look at BoolFilter.schema.ts

How to reproduce

Add previewFeatures = ["fieldReference"] to schema.prisma

Expected behavior

No response

Prisma information

Environment & setup

  • OS:
  • Database:
  • Node.js version:

Prisma Version


[Error] Strange `ERROR undefined` with `trpc` and `nuxt`

Bug description

When using generated zod types with trpc and nuxt nitro server prints strange info.

Screenshot_20230102_215640

How to reproduce

  1. Create nuxt
  2. add trpc-nuxt
  3. generate prisma-zod-generator
  4. User generated zod type in input for trpc
  5. Check console for nitro server

Expected behavior

There should be no error

Prisma information

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["extendedWhereUnique", "filteredRelationCount", "orderByNulls"]
}

generator zod {
  provider          = "prisma-zod-generator"
  output            = "./generated/zod"
  isGenerateSelect  = false
  isGenerateInclude = false
}

// generator trpc {
//   provider           = "prisma-trpc-generator"
//   output             = "./generated/trpc"
//   contextPath        = "../context"
//   withMiddleware     = false
//   withShield         = false
//   isGenerateSelect   = false
//   isGenerateInclude  = false
// }

datasource db {
  provider     = "postgresql"
  url          = env("DATABASE_URL")
  relationMode = "foreignKeys"
}


model City {
  id              Int             @id @default(autoincrement())
  title           String          @unique
  createdAt       DateTime        @default(now()) @map("created_at") @db.Timestamptz
  updatedAt       DateTime        @default(now()) @map("updated_at") @db.Timestamptz
  venues          Venue[]

  @@map("city")
}

model Venue {
  id        Int      @id @default(autoincrement())
  code      String   @unique
  title     String   @unique
  address   String
  capacity  Int
  available Boolean  @default(true)
  cityId    Int      @map("city_id")
  createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
  updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz
  city      City     @relation(fields: [cityId], references: [id])
  
  @@map("venue")
}

Environment & setup

  • OS: KDE
  • Database: PostgreSQL
  • Node.js version: v19.3.0

Prisma Version

prisma                  : 4.8.0
@prisma/client          : 4.8.0
Current platform        : debian-openssl-3.0.x
Query Engine (Node-API) : libquery-engine d6e67a83f971b175a593ccc12e15c4a757f93ffe (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node)
Migration Engine        : migration-engine-cli d6e67a83f971b175a593ccc12e15c4a757f93ffe (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/migration-engine-debian-openssl-3.0.x)
Introspection Engine    : introspection-core d6e67a83f971b175a593ccc12e15c4a757f93ffe (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/introspection-engine-debian-openssl-3.0.x)
Format Binary           : prisma-fmt d6e67a83f971b175a593ccc12e15c4a757f93ffe (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/prisma-fmt-debian-openssl-3.0.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.8.0-61.d6e67a83f971b175a593ccc12e15c4a757f93ffe
Default Engines Hash    : d6e67a83f971b175a593ccc12e15c4a757f93ffe
Studio                  : 0.479.0
Preview Features        : orderByNulls, filteredRelationCount, extendedWhereUnique

Type error in a self-relation schema

Bug description

There are multiple type errors in my generated schema file TaskCreateOrConnectWithoutSubtasksInput.schema.ts.

I think that this error occurs because this is a self-reference.

โฏ npm run build

> [email protected] build
> next build
- info Linting and checking validity of types ..Failed to compile.

./prisma/generated/schemas/objects/TaskCreateOrConnectWithoutSubtasksInput.schema.ts:8:7
Type error: Type 'ZodObject<{ where: ZodLazy<ZodType<TaskWhereUniqueInput, ZodTypeDef, TaskWhereUniqueInput>>; create: ZodUnion<...>; }, "strict", ZodTypeAny, { ...; }, { ...; }>' is not assignable to type 'ZodType<TaskCreateOrConnectWithoutSubtasksInput, ZodTypeDef, TaskCreateOrConnectWithoutSubtasksInput>'.
  The types of '_type.create' are incompatible between these types.
    Type '(TaskCreateWithoutSubtasksInput | TaskUncheckedCreateWithoutSubtasksInput) & (TaskCreateWithoutSubtasksInput | TaskUncheckedCreateWithoutSubtasksInput | undefined)' is not assignable to type '(Without<TaskCreateWithoutSubtasksInput, TaskUncheckedCreateWithoutSubtasksInput> & TaskUncheckedCreateWithoutSubtasksInput) | (Without<...> & TaskCreateWithoutSubtasksInput)'.
      Type 'TaskCreateWithoutSubtasksInput & TaskUncheckedCreateWithoutSubtasksInput' is not assignable to type '(Without<TaskCreateWithoutSubtasksInput, TaskUncheckedCreateWithoutSubtasksInput> & TaskUncheckedCreateWithoutSubtasksInput) | (Without<...> & TaskCreateWithoutSubtasksInput)'.
        Type 'TaskCreateWithoutSubtasksInput & TaskUncheckedCreateWithoutSubtasksInput' is not assignable to type 'Without<TaskUncheckedCreateWithoutSubtasksInput, TaskCreateWithoutSubtasksInput> & TaskCreateWithoutSubtasksInput'.
          Type 'TaskCreateWithoutSubtasksInput & TaskUncheckedCreateWithoutSubtasksInput' is not assignable to type 'Without<TaskUncheckedCreateWithoutSubtasksInput, TaskCreateWithoutSubtasksInput>'.
            Types of property 'userId' are incompatible.
              Type 'string' is not assignable to type 'undefined'.

   6 | import type { Prisma } from '@prisma/client'
   7 | 
>  8 | const Schema: z.ZodType<Prisma.TaskCreateOrConnectWithoutSubtasksInput> =
     |       ^
   9 |   z
  10 |     .object({
  11 |       where: z.lazy(() => TaskWhereUniqueInputObjectSchema),

How to reproduce

I am not sure. I can help if someone give me any instruction.

Expected behavior

No response

Prisma information

model Task {
  id          String    @id @default(cuid())
  title       String
  user        User      @relation(fields: [userId], references: [id])
  userId      String
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt
  startedAt   DateTime?
  endedAt     DateTime?
  superTaskId String?
  superTask   Task?     @relation(name: "Subtask", fields: [superTaskId], references: [id], onDelete: NoAction, onUpdate: NoAction)
  subtasks    Task[]    @relation(name: "Subtask")
  taskNum     Int?
  tags        Tag[]     @relation(name: "Tags")
  isArchived  Boolean   @default(false)

  @@index([userId])
  @@index([superTaskId])
}

Environment & setup

  • OS: macOS 13.2
  • Database: MySQL
  • Node.js version: v20.1.0

Prisma Version

{Model}Include.schema.ts is generated for models that do not have a relation to any other models

Bug description

Tagging @Shahidul1004 in this one as you might have some good insights here as well

I noticed that {Model}Include.schema.ts is generated for models that do not have a relation to any another model and the result looks something like this:

const Schema: z.ZodType<Prisma.{Model}Include> = z.object({}).strict();

There is an error line under Prisma.{Model}Include because it looks like Prisma only generates a {Model}Include type if the model contains a relation to another model. So the generated {Model}Include.schema.ts is referencing a Prisma type that does not exist ๐Ÿ˜ญ

As a fix, I believe this section in include-helpers needs to be wrapped in an if condition checking for hasRelation, where hasRelation is set to true if we encounter isRelationField === true

...
let hasRelation = false;
...
if (isRelationField) {
  hasRelation = true;
}
...
if (hasRelation) {
  const modelIncludeInputObjectType: DMMF.InputType = {
        name: `${modelName}Include`,
        constraints: {
          maxNumFields: null,
          minNumFields: null,
        },
        fields,
      };
      modelIncludeInputObjectTypes.push(modelIncludeInputObjectType);
}

@Shahidul1004 Curious if you're able to reproduce this and see if the fix works ๐Ÿค”

How to reproduce

Run npm run generate-example with a schema.prisma containing a model with no relation to another model, and look at the generated {Model}Include.schema.ts file that is generated.

model Test {
  id Int @unique
}

Expected behavior

Expected behavior: {Model}Include.schema.ts is not generated for models that don't have relations with any other models.

Prisma information

The schema.prisma in this repo, just including a model that does not have a relation with any other model.

model Test {
  id Int @unique
}

Environment & setup

Mac OS + included schema.prisma if you add a model that does not have a relation with any other model

model Test {
  id Int @unique
}

Prisma Version

N / A

If Prisma model camelCase, prisma-zod-generator generates broken files

Bug description

If the models in the prisma schema are named in camelCase, then the generated files will not have matching import statements.

The filenames in prisma/generated/schemas will have incorrectly formatted camelCase names

The filenames in prisma/generated/schemas/enums will have correctly formatted PascalCase names
The files in prisma/generated/schemas import those enum files with correctly formatted camelCase names

Name mismatch! PascalCase != camelCase.


Notice correctly formatted PascalCase of enum files:
Notice incorrectly formatted camelCase name of red file (it's not the only one):

image

Notice correctly formatted camelCase import of enum file:
Name mismatch! PascalCase != camelCase.

image

How to reproduce

Create and cd into an empy directory.

Run commands:

npm init -y
npm install prisma prisma-zod-generator
npx prisma init

Append to file: prisma/schema.prisma

generator zod {
  provider = "prisma-zod-generator"
}

// Note the camelcase name
model user {
  id   Int     @id @default(autoincrement())
  name String?
}

Run commands:

npx prisma generate

Notice filename: prisma/generated/schemas/findFirstuser.ts doesn't have correct camelCase name.

Open project in vscode, view file: prisma/generated/schemas/findFirstuser.ts

Line 5: import has error: "Cannot find module './enums/userScalarFieldEnum.schema' or its corresponding type declarations."

It can't find it because the enum file is PascalCase, but the import is written in camelCase.

This same error is in several of the generated files.

Expected behavior

I expect the generated files and the imports used in those generated files to be named the same, regardless of the case of the prisma schema models' names.

Prisma information

Entire Prisma schema:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

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

generator zod {
  provider = "prisma-zod-generator"
}

// Note the camelcase name
model user {
  id   Int     @id @default(autoincrement())
  name String?
}

Environment & setup

  • OS: Windows 11, WSL2, Ubuntu 22.04LTS
  • Database: unused (default: PostgreSQL)
  • Node.js version: v16.17.0

Prisma Version

prisma                  : 4.3.1
@prisma/client          : 4.3.1
Current platform        : debian-openssl-3.0.x
Query Engine (Node-API) : libquery-engine c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node)
Migration Engine        : migration-engine-cli c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/migration-engine-debian-openssl-3.0.x)
Introspection Engine    : introspection-core c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/introspection-engine-debian-openssl-3.0.x)
Format Binary           : prisma-fmt c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/prisma-fmt-debian-openssl-3.0.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.3.0-32.c875e43600dfe042452e0b868f7a48b817b9640b
Default Engines Hash    : c875e43600dfe042452e0b868f7a48b817b9640b
Studio                  : 0.473.0

Support extendedWhereUnique preview feature

Bug description

Generated schema for ModelVacancyWhereUniqueInputObjectSchema is invalid.

How to reproduce

  1. Add latest prisma and generator version
  2. run prisma generate
  3. Inspect ModelVacancyWhereUniqueInputObjectSchema file for any model
  4. See error

Screenshot_20221204_221504

Expected behavior

Generated schema should not contain any errors.

Prisma information

generator zod {
  provider          = "prisma-zod-generator"
  output            = "./generated/zod"
  isGenerateSelect  = true
  isGenerateInclude = true
}

Environment & setup

  • OS: Linux ()
  • Database: PostgreSQL
  • Node.js version: v18.4.0

Prisma Version

prisma                  : 4.7.1
@prisma/client          : 4.7.1
Current platform        : debian-openssl-3.0.x
Query Engine (Node-API) : libquery-engine 272861e07ab64f234d3ffc4094e32bd61775599c (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node)
Migration Engine        : migration-engine-cli 272861e07ab64f234d3ffc4094e32bd61775599c (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/migration-engine-debian-openssl-3.0.x)
Introspection Engine    : introspection-core 272861e07ab64f234d3ffc4094e32bd61775599c (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/introspection-engine-debian-openssl-3.0.x)
Format Binary           : prisma-fmt 272861e07ab64f234d3ffc4094e32bd61775599c (at node_modules/.pnpm/@[email protected]/node_modules/@prisma/engines/prisma-fmt-debian-openssl-3.0.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c
Default Engines Hash    : 272861e07ab64f234d3ffc4094e32bd61775599c
Studio                  : 0.477.0

prisma-zod-generator deletes the entire output folder!

Bug description

I changed the output parameter to drop the files inside my src folder just to learn the generator deleted my entire day of work.
Can you please review this behavior? If the output is different from the default, DO NOT WIPE THE OUTPUT FOLDER!

How to reproduce

Change the output option in the generator to:

generator zod {
  provider = "prisma-zod-generator"
  output = "../src"
} 

Expected behavior

Lose a full day of work if you did not commit anything yet.

Prisma information

generator zod {
provider = "prisma-zod-generator"
output = "../src"
}

Environment & setup

  • OS: Windows
  • Database: PostgreSQL
  • Node.js version: v18.12.1

Prisma Version

4.5.0

Prisma 5 compatibility

I forked this repo for my own personal use case and stumbled upon some issues when attempting to upgrade to prisma 5.1.1

Just wanted to leave some notes here of findings thus far.
Feel free to take it over.


[...]CountOutputTypeArgs types have been renamed e.g.
AddressCountOutputTypeArgs becomes AddressCountOutputTypeDefaultArgs
Added this after the isAggregateInputType check in Transformer.generateExportObjectSchemaStatement

    if (name.endsWith('CountOutputTypeArgs')) {
      name = name.replace(/Args$/, 'DefaultArgs')
    }

The one I got stuck on after that was the [...]WhereUniqueInput types.
So where previously a type might look like

  export type AssetWhereUniqueInput = {
    id?: number
    uuid?: string
    checksum?: string
  }

Is now wrapped with a AtLeast<> type utility that requires at least one of the values to be present instead of them all being optional. This conflicts with the the ZodType argument in these type of files:

const Schema: z.ZodType<Prisma.AssetWhereUniqueInput> = 
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I narrowed it down to the fact that extendedWhereUnique is enabled by default in prisma 5.
Here's a related issue to watch: prisma/prisma#20619

I don't know if there's an answer to this with zod?


I don't fully understand the code and how it's all laid out so I got a bit overwhelmed and tapped out, but hopefully this helps if you decide to keep supporting this package (which you should! it's great!)

More granual control over what gets generated, excludeable fields and multiple exported schemas

Problem

This is a three part feature request

This is a great package and I really want it to succeed but there are some really irritating issues that need features to resolve them.

1: More granular control over what gets generated

I posted this issue on your prisma tRPC generator but it seems more relevant here and I'm going to add a bit more detail here on why it's needed and a more detailed solution. A major feature that's lacking from this package is the lack of granularity with what gets generated. For example, our app has about 8 different routes. Only 4 need full CRUD functionality, the rest are mainly for reading, and creation, deletion and update are manually handled by employees using prisma studio. The number of schemas and objects generated by this generator is ludicrous, most simply won't be needed for most use cases. This also makes integrating the codegen process into the development process slower, as you need to manually remove the unnecessary files or manually select all of the useful while leaving the bloat, both of which require with developer time or code to maintain. You should just be able to get what you actually need to use in as close to the way you need to use it as possible. Having more granular control is important to increase the adoption of this package as it will mean people can use it more flexible and generate only what they need for their specific use case

2: Excludeable fields

On this note, some fields are not relevant to the Prisma client and don't need to be type checked. For example, we may have an optional field on the backend for administrative purposes that is manually inputted and checked by our employees and is never going to be submitted by Prisma client, so it just gets in the way being there. This isn't that much of an issue for the prisma client but it is for using tRPC with Zod, and this is one of the biggest issues. The generated schema becomes practically useless as it can't be used to automatically validate incoming requests to tRPC because it contains fields that are never going to be submitted by the client. You have to either then manually edit and cut fields from the schema, which detracts from the usefulness of the codegen in the first place, or add a bunch of omits to the object in the tRPC procedure input, which again isn't ideal, especially if the model has a relation and hence is a z.ZodSchema not a z.object so you can't use omit.

Having control over what fields get generated is crucial for allowing the generation of useful Zod schema. Having complete Prisma schema for every Prisma model and client action is relatively useless if you can't then use those to validate the input your client will actually be sending to your tRPC endpoint. Just one more example here as to why it's necessary, for example, our user may send information like their name, email, address, etc. but will not send things like their user type, which is conditionally added at the API level. However, the generated schema will just fail the request as not being valid because it doesn't contain the user type, which can't be conditional as it is needed in later steps. This leads nicely onto my next point

3: Multiple exported schemas per Model

Given that the creator of this package also manages various tRPC, Zod and Prisma related packages, it seems worthwhile to point out that the main schemas generated by this package won't be that useful for most client's inputs coming into tRPC. Not everyone will be sending their data exactly as it will be stored in the database in their request from the client, so as I stated above, these schemas are not hugely useful or need heavy editing. One potential remedy for this is adding the option to generate two schemas for specific Prisma models, one for Prisma client validation and one for tRPC input validation. I'll explain more below

Suggested solution

Adding a config file

I'm not particularly well versed on the Prisma schema syntax and how it interacts with generators. In an ideal world something like the below would be great

{
      modelName: {
             createOne: true,
             createMany: false,
             findUnique: true,
             ....
      }
}

However, just at a glance I doubt prisma's schema will allow json objects. I'm not sure if you can even do nesting,
something like a YAML like syntax could work if that's possible like

modelName:
      createdOne: true
      createMany: false
      findUnique: true

But, these likely both won't work. Perhaps, one way around this might be to have a separate config file that that is assigned in the prisma.schema and passed to the actual generator file

generator zod {
  provider          = "prisma-zod-generator"
  output            = "./generated-zod-schemas"
  config             = "./zod-generator.json" // zod generator config path goes here
  isGenerateSelect  = true
  isGenerateInclude = true
}

I think this is likely the root of solving all three issues. You pass in your input as a json object, or maybe as yaml, and this is used to conditional transform your code into the correct output. For example,

{
    "models": {
        "User": {
            "generate": true, // potentially redundant
            "prisma": {
                "removeFields": ["createdAt"] // those included are removed
                "includeMethods": ["createdOne"] // only those included are generated
            },
            "trpc": {
                "removeFields": ["createdAt", "userType"] // those included are removed
            }
        }
        "Account": {
            "generate": false // prevents schema model from being generated
        }
        ...moreModels
    },
    ...additionalOptions
}

This is by no means perfect and there's a lot of room to improve the syntax. One potential compliant is that this separates the logic from the prisma.schema, which personally I prefer, as after using zod-prisma, all the comments clog up the file pretty fast. This obviously doesn't include anything about how this would actually be done by the generator, which I imagine is the actual hard part but hopefully this is a helpful start

Additional context

If you can provide some guidance, I'd be happy to assist with some of this

Generator doesn't generate schema from column type decimal

Bug description

A decimal field is not getting generated in the schemas

How to reproduce

Expected behavior

No response

Prisma information

generator client {
  provider               = "prisma-client-js"
  output                 = "./client"
  customPrismaImportPath = "../client"
}

generator trpc {
  provider       = "prisma-trpc-generator"
  withMiddleware = false
  withShield     = false
  contextPath    = "../../../../src/context"
  output         = "./trpc"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator zod {
  provider = "zod-prisma"
  output   = "./zod" // (default) the directory where generated zod schemas will be saved

  relationModel = true // (default) Create and export both plain and related models.
  // relationModel         = "default" // Do not export model without relations.
  // relationModel         = false // Do not generate related model

  // modelCase                = "PascalCase" // (default) Output models using pascal case (ex. UserModel, PostModel)
  modelCase = "camelCase" // Output models using camel case (ex. userModel, postModel)

  modelSuffix = "Model" // (default) Suffix to apply to your prisma models when naming Zod schemas

  // useDecimalJs          = false // (default) represent the prisma Decimal type using as a JS number
  useDecimalJs = true // represent the prisma Decimal type using Decimal.js (as Prisma does)

  // https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-by-null-values
  prismaJsonNullability = true // (default) uses prisma's scheme for JSON field nullability
  // prismaJsonNullability = false // allows null assignment to optional JSON fields
}

model Test {
  id        Int      @id @default(autoincrement())
  name      String?
  amount    Decimal? @db.Decimal(9, 2)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Environment & setup

  • OS: Mac OS
  • Database: MySQL
  • Node.js version: 14.7.3

Prisma Version

prisma                  : 4.1.1
@prisma/client          : 4.1.1
Current platform        : darwin-arm64
Query Engine (Node-API) : libquery-engine 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at ../../node_modules/prisma/node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Migration Engine        : migration-engine-cli 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at ../../node_modules/prisma/node_modules/@prisma/engines/migration-engine-darwin-arm64)
Introspection Engine    : introspection-core 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at ../../node_modules/prisma/node_modules/@prisma/engines/introspection-engine-darwin-arm64)
Format Binary           : prisma-fmt 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at ../../node_modules/prisma/node_modules/@prisma/engines/prisma-fmt-darwin-arm64)
Default Engines Hash    : 8d8414deb360336e4698a65aa45a1fbaf1ce13d8
Studio                  : 0.469.0

"Expected date, received string" on DateTime type

Bug description

When try parse schemas with fields "DateTime" strings like: "YYYY-MM-DD" or "2023-01-10T00:00:00.000Z" throw this exception Expected date, received string.

Works if update generated files with z.coerce.date()

How to reproduce

Create a model like this:

generator zod {
provider = "prisma-zod-generator"
output = "../../node_modules/.prisma/zod/client"
isGenerateSelect = true
isGenerateInclude = true
}

model HostMetric {
metric_at DateTime @id @unique @default(now())
host Host @relation(fields: [host_id], references: [id])
host_id Int
version String
mem_used Int /// Megabytes
mem_total Int /// Megabytes
cpu_used Int /// Percentage
cpu_total Int? /// Percentage
disk_used Int? /// Megabytes
disk_total Int? /// Megabytes
process_count Int

@@Map("host_metrics")
}

Try parse using fastify
import { HostMetricUncheckedCreateInputObjectSchema } from "../../node_modules/.prisma/zod/client";
let worker = HostMetricUncheckedCreateInputObjectSchema.parse(body);

the response error
"Expected date, received string" on field metric_at

Expected behavior

When send this body expected a new line inserted

{
"metric_at": "2023-01-10T00:00:00.000Z",
"host_id": 1,
"version": "1.23",
"mem_used": 2000,
"mem_total": 8000,
"cpu_used": 1500,
"cpu_total": 4000,
"disk_used": 33000,
"disk_total": 100000,
"process_count": 1
}

Prisma information

Model:

generator zod {
provider = "prisma-zod-generator"
output = "../../node_modules/.prisma/zod/client"
isGenerateSelect = true
isGenerateInclude = true
}

model HostMetric {
metric_at DateTime @id @unique @default(now())
host Host @relation(fields: [host_id], references: [id])
host_id Int
version String
mem_used Int /// Megabytes
mem_total Int /// Megabytes
cpu_used Int /// Percentage
cpu_total Int? /// Percentage
disk_used Int? /// Megabytes
disk_total Int? /// Megabytes
process_count Int

@@Map("host_metrics")
}

Environment & setup

  • OS: Mac OS
  • Database: PostgreSQL
  • Node.js version: 18

Prisma Version

prisma                  : 4.13.0
@prisma/client          : 4.13.0
prisma-zod-generator: 0.8.11

Add `index.ts` with all the exported members

Problem

Currently what the generator doing is just creating the schema files but they are all not exported in one file causing issue with use in monorepo

Suggested solution

Just add an index.ts with all the exported members

[prisma v2.x] Types for createOne / updateOne may be incomplete

Bug description

Disclaimer: Not yet sure if this is a capital-b BUG as I'm new to the prisma ecosystem, but figure this is a decent place to put this discussion as Discussions is pretty empty here. Please push back if there's a better place to put this.

TLDR - It's possible that the schemas generated for createOneFoo and updateOneFoo are intended to be a union between FooUpdateInput and FooUncheckedUpdateInput, whereas right now they are simply FooUpdateInput.

Notable that I'm using [email protected] so this may be specific to that older version. Uncertain, but figured I'd share in case it's helpful.

How to reproduce

I'm using [email protected] and the prisma-client generator generates the following types for a User update-client:

// node_modules/.prisma/client/index.d.ts
  /**
   * User update
   */
  export type UserUpdateArgs = {
    /**
     * Select specific fields to fetch from the User
     * 
    **/
    select?: UserSelect | null
    /**
     * Choose, which related nodes to fetch as well.
     * 
    **/
    include?: UserInclude | null
    /**
     * The data needed to update a User.
     * 
    **/
    data: XOR<UserUpdateInput, UserUncheckedUpdateInput>
    /**
     * Choose, which User to update.
     * 
    **/
    where: UserWhereUniqueInput
  }

We're then using prisma-trpc-generator, and the zod-schema that gets generated under the hood looks like this:

// generated/schemas/updateOneUser.schema.ts
import { z } from "zod";
import { UserUpdateInputObjectSchema } from "./objects/UserUpdateInput.schema";
import { UserWhereUniqueInputObjectSchema } from "./objects/UserWhereUniqueInput.schema";

export const UserUpdateOneSchema = z.object({
  data: UserUpdateInputObjectSchema,
  where: UserWhereUniqueInputObjectSchema,
});

I'm fairly certain there's a mismatch here? If I use the client where data is of the shape UserUncheckedUpdateInput, prisma accepts the input and updates the entity as desired, but the zod validator gets in the way and tells me that it's looking for UserUpdateInputObjectSchema.

Expected behavior

I'd expect for the schema to look like this.

// generated/schemas/updateOneUser.schema.ts
import { z } from "zod";
import { UserUpdateInputObjectSchema } from "./objects/UserUpdateInput.schema";
import { UserUncheckedUpdateInputObjectSchema } from "./objects/UserUncheckedUpdateInput.schema";
import { UserWhereUniqueInputObjectSchema } from "./objects/UserWhereUniqueInput.schema";

export const UserUpdateOneSchema = z.object({
  data: z.union([UserUpdateInputObjectSchema, UserUncheckedUpdateInputObjectSchema]),
  where: UserWhereUniqueInputObjectSchema,
});

I'm currently using a fork of prisma-zod-generator where I've modified the generator to output the desired union type for data to match the XOR<...>.

Prisma information

Environment & setup

  • OS: Mac OS
  • Database: PostgreSQL
  • Node.js version: 16.15.1

Prisma Version

prisma                : 2.30.3
@prisma/client        : 2.30.3
Current platform      : darwin-arm64
Query Engine (Binary) : query-engine b8c35d44de987a9691890b3ddf3e2e7effb9bf20 (at node_modules/@prisma/engines/query-engine-darwin-arm64)
Migration Engine      : migration-engine-cli b8c35d44de987a9691890b3ddf3e2e7effb9bf20 (at node_modules/@prisma/engines/migration-engine-darwin-arm64)
Introspection Engine  : introspection-core b8c35d44de987a9691890b3ddf3e2e7effb9bf20 (at node_modules/@prisma/engines/introspection-engine-darwin-arm64)
Format Binary         : prisma-fmt b8c35d44de987a9691890b3ddf3e2e7effb9bf20 (at node_modules/@prisma/engines/prisma-fmt-darwin-arm64)
Default Engines Hash  : b8c35d44de987a9691890b3ddf3e2e7effb9bf20
Studio                : 0.423.0

Give an option to opt out type down-casting

First I need to thank for this great library. It bridges the typing of database and api, which is revolutionary.

Problem

Schema.shape is not accessible when using schema.

I have the following generated code:

import { z } from 'zod';

import type { Prisma } from '@prisma/client';

const Schema: z.ZodType<Prisma.UserCreateInput> l= z
  .object({
    email: z.string(),
    hashedPassword: z.string(),
    lastLogin: z.date().optional(),
    createdAt: z.date().optional(),
    updatedAt: z.date().optional(),
  })
  .strict();

export const UserCreateInputObjectSchema = Schema;

Seems I cannot access Schema.shape because it is not on z.ZodType<Prisma.UserCreateInput>. After removing it, I get

type Schema = z.ZodObject<{
    email: z.ZodString;
    hashedPassword: z.ZodString;
    lastLogin: z.ZodOptional<z.ZodDate>;
    createdAt: z.ZodOptional<z.ZodDate>;
    updatedAt: z.ZodOptional<z.ZodDate>;
}, "strict", z.ZodTypeAny, {
    ...;
}, {
    ...;
}>

and Schema.shape =

(property) ZodObject<{ email: ZodString; hashedPassword: ZodString; lastLogin: ZodOptional<ZodDate>; createdAt: ZodOptional<ZodDate>; updatedAt: ZodOptional<...>; }, "strict", ZodTypeAny, { ...; }, { ...; }>.shape: {
    email: z.ZodString;
    hashedPassword: z.ZodString;
    lastLogin: z.ZodOptional<z.ZodDate>;
    createdAt: z.ZodOptional<z.ZodDate>;
    updatedAt: z.ZodOptional<z.ZodDate>;
}

With this, we can access metadata when defining the database. However, this leads to more complicated type and might not work on bigger projects.

Suggested solution

Provide a way to remove the type annotation on Schema

z.ZodType<Prisma.UserCreateInput>

Alternatives

Additional context

Validation prevents multiple relationship actions

Bug description

In order to do a nested upsert/set of N-to-Many entities, one needs to tell prisma to do something like this:

ctx.prisma.entity.update({
  where: { id },
  data: {
    nestedEntities: {
      deleteMany: {
        parentId: id,
      },
      createMany: {
        data: [{...}]
      },
    },
  },
})

(e.g. prisma/prisma#2255 (comment))

The deleteMany removes all the nested entities, and then the createMany creates all of them again. While this doesn't seem to be terribly efficient, I don't know of another way to handle a nested N-to-Many write in which you may be adding and updating existing entities.

...But, this generator prevents one from specifying more than one verb in a given data object by outputting validation like this:

const Schema: z.ZodType<Prisma.NestedEntityUpdateManyWithoutParentEntityNestedInput> =
  z.union([
    z
      .object({
        deleteMany: z
          .union([
            z.lazy(() => NestedEntityScalarWhereInputObjectSchema),
            z.lazy(() => NestedEntityScalarWhereInputObjectSchema).array(),
          ])
          .optional(),
      })
      .strict(),
    z
      .object({
        createMany: z
          .lazy(() => NestedEntityCreateManyParentEntityInputEnvelopeObjectSchema)
          .optional(),
      })
      .strict(),
     ...
])

which is a union of single attribute objects. The resultant validation error is something like this:

Failure to save filter TRPCClientError: [
  {
    "code": "unrecognized_keys",
    "keys": [
      "deleteMany",
      "createMany"
    ],
    "path": [
      "create",
      "filters"
    ],
    "message": "Unrecognized key(s) in object: 'deleteMany', 'createMany'"
  },
...
]

How to reproduce

Attempt to use more than one verb for a nested entity, e.g. deleteMany and createMany.

Expected behavior

Verbs like deleteMany and createMany can be used together.

Prisma information

n/a

Environment & setup

  • OS: MacOS
  • Database: PostgreSQL
  • Node.js version: v16.15.1

Prisma Version

prisma                  : 4.6.1
@prisma/client          : 4.6.1
Current platform        : darwin
Query Engine (Node-API) : libquery-engine 694eea289a8462c80264df36757e4fdc129b1b32 (at node_modules/@prisma/engines/libquery_engine-darwin.dylib.node)
Migration Engine        : migration-engine-cli 694eea289a8462c80264df36757e4fdc129b1b32 (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine    : introspection-core 694eea289a8462c80264df36757e4fdc129b1b32 (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary           : prisma-fmt 694eea289a8462c80264df36757e4fdc129b1b32 (at node_modules/@prisma/engines/prisma-fmt-darwin)
Format Wasm             : @prisma/prisma-fmt-wasm 4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32
Default Engines Hash    : 694eea289a8462c80264df36757e4fdc129b1b32
Studio                  : 0.476.0

nullable is reversed on json type

Bug description

In Prisma schema, I defined a field as a Json nullable type, but the generated result from Zod is not nullable.

How to reproduce

column is not nullable in prisma schema, but the generated type is not nullable

schema.prisma

model User {
  bio  Json?
}

then run prisma migrate dev

prisma/generated/zod/index.ts

export const UserSchema = z.object({
  bio: JsonValueSchema,
})

column is nullable in prisma schema, but the generated type is nullable

schema.prisma

model User {
  bio  Json
}

then run prisma migrate dev

prisma/generated/zod/index.ts

export const UserSchema = z.object({
  bio: JsonValueSchema.nullable(),
})

Expected behavior

No response

Prisma information

schema.prisma

model User {
  bio  Json?
}

Environment & setup

  • OS: macOS 12.3
  • Database: PostgreSQL
  • Node.js version: 20.8.1

Prisma Version

5.1.1

minimal option

Problem

I would love it if there was an option to only generate CRUD schemas

Suggested solution

add a minimal option which would only generate CRUD operations

Module not found: Can't resolve './BytesFieldRefInput.schema'

Bug description

I have model in prisma. Reading, creation objects works fine. Zod schemas generated right.

// It works
import { MyModelCreateOneSchema } from "./database/prisma/generated/schemas/createOneMyModel.schema"

But when I attempting to import:

import { MyModelUpdateOneSchema } from "./database/prisma/generated/schemas/updateOneMyModel.schema"

I got error

../../packages/database/prisma/generated/schemas/objects/BytesFilter.schema.ts:2:0
Module not found: Can't resolve './BytesFieldRefInput.schema'
  1 | import { z } from "zod"
> 2 | import { BytesFieldRefInputObjectSchema } from "./BytesFieldRefInput.schema"
  3 | import { ListBytesFieldRefInputObjectSchema } from "./ListBytesFieldRefInput.schema"
  4 | import { NestedBytesFilterObjectSchema } from "./NestedBytesFilter.schema"
  5 | 

MyModel has relation to other models, one of this using Bytes

How to reproduce

Expected behavior

No response

Prisma information

Environment & setup

  • OS:
  • Database:
  • Node.js version:

Prisma Version

4.7.1

Property hiding

Problem

Currently you are able to hide whole models by using /// @@Gen.model(hide: true) doc string. There's no ability to hide individual properties on demand.

Suggested solution

User should be able to add a doc string to a property to hide that property, similarly to the model hiding:

model SomeModel {
  id String @id 
  /// @@Gen.property(hide: true)
  hiddenField String
}

Which would generate zod schema with just id:

const SomeModel = z.object({
  id: z.string()
});

Alternatives

This solution follows the same approach as the model hiding does, so I don't have alternative solutions here.

Additional context

I've already implemented this feature in a fork, there will be a PR for this.

Bad prisma-client import

Bug description

Generated object schemas have a bad prisma-client import when client output is "../src/generated/prisma-client" and zod output is "../src/generated/zod" in Windows:

import type { Prisma } from '......prisma-client';

How to reproduce

  1. add output = "../src/generated/prisma-client" to client generator config in schema.prisma
  2. add output = "../src/generated/zod" to zod generator config in schema.prisma
  3. Run yarn prisma generate
  4. Go to src\generated\zod\schemas\objects\XCreateInput.schema.ts
  5. See import type { Prisma } from '......prisma-client';

Expected behavior

import type { Prisma } from '../../../prisma-client';

Prisma information

generator client {
provider = "prisma-client-js"
output = "../src/generated/prisma-client"
binaryTargets = ["native", "rhel-openssl-1.0.x"]
}

generator zod {
provider = "prisma-zod-generator"
output = "../src/generated/zod"
}

datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}

model X {
id String @id @default(auto()) @Map("_id") @db.ObjectId
}

Environment & setup

  • OS: Windows
  • Database: Mongo
  • Node.js version: v18.6.0

Prisma Version

prisma                  : 4.1.0
@prisma/client          : 4.1.0
Current platform        : windows
Query Engine (Node-API) : libquery-engine 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at node_modules\@prisma\engines\query_engine-windows.dll.node)
Migration Engine        : migration-engine-cli 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at node_modules\@prisma\engines\migration-engine-windows.exe)
Introspection Engine    : introspection-core 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at node_modules\@prisma\engines\introspection-engine-windows.exe)
Format Binary           : prisma-fmt 8d8414deb360336e4698a65aa45a1fbaf1ce13d8 (at node_modules\@prisma\engines\prisma-fmt-windows.exe)
Default Engines Hash    : 8d8414deb360336e4698a65aa45a1fbaf1ce13d8
Studio                  : 0.467.

Re-exports for all schemas

Problem

Currently, each schema has to be imported from its own file. Which is inconvenience.

Suggested solution

Add re-sports for each directory. This will make it easy to import schema from only one import.

Alternatives

A similar option also exists in prisma-nestjs-graphql re-exports

Additional context

Thanks for maintaining such an awesome project.

Aggregate Input Schema not generated

Bug description

For Models without any type of number the {model}AvgAggregateInputObjectSchema and {model}SumAggregateInputObjectSchema are imported in the aggregate{Model}.schema.ts file but these schemas are not created.

How to reproduce

  1. clone this repo
  2. use the schema.prisma file provided below
  3. run prisma generate
  4. open generated/schemas/aggregateUser.schema.ts

Expected behavior

import { UserAvgAggregateInputObjectSchema } from './objects/UserAvgAggregateInput.schema';
import { UserSumAggregateInputObjectSchema } from './objects/UserSumAggregateInput.schema';

are not imported and:

  _avg: UserAvgAggregateInputObjectSchema.optional(),
  _sum: UserSumAggregateInputObjectSchema.optional(),

are not defined in UserAggregateSchema = z.object({})

Prisma information

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

datasource db {
provider = "sqlite"
url = "file:./dev.db"
}

generator zod {
provider = "node ./lib/generator.js"
output = "./generated"
isGenerateSelect = true
}

model User {
id String @id @default(cuid())
email String @unique
name String?
}

Environment & setup

  • OS: MacOS
  • Database: SQLite
  • Node.js version: v18.11.0

Prisma Version

prisma                  : 4.3.1
@prisma/client          : 4.3.1
Current platform        : darwin-arm64
Query Engine (Node-API) : libquery-engine c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Migration Engine        : migration-engine-cli c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/migration-engine-darwin-arm64)
Introspection Engine    : introspection-core c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/introspection-engine-darwin-arm64)
Format Binary           : prisma-fmt c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/@prisma/engines/prisma-fmt-darwin-arm64)
Format Wasm             : @prisma/prisma-fmt-wasm 4.3.0-32.c875e43600dfe042452e0b868f7a48b817b9640b
Default Engines Hash    : c875e43600dfe042452e0b868f7a48b817b9640b
Studio                  : 0.473.0

Optional typing in unions strips all properties

Bug description

Generated types for relationships leverage zod union types, but when all the constituent components are optional the parsed output forcefully becomes an empty object {}.

For the prisma schema provided further below, the generated WidgetCreateInputObjectSchema looks like this:

const Schema: z.ZodType<Prisma.WidgetCreateInput> = z
  .object({
    version: z.lazy(() => FormVersionCreateNestedOneWithoutWidgetsInputObjectSchema),
    step: z.lazy(() => StepCreateNestedOneWithoutWidgetsInputObjectSchema),
  })
  .strict();

And the nested version schema is a zod union like this:

const Schema: z.ZodType<Prisma.FormVersionCreateNestedOneWithoutWidgetsInput> = z.union([
  z.object({
    create: z
      .union([
        z.lazy(() => FormVersionCreateWithoutWidgetsInputObjectSchema),
        z.lazy(() => FormVersionUncheckedCreateWithoutWidgetsInputObjectSchema),
      ])
      .optional(),
  }),
  z.object({
    connectOrCreate: z.lazy(() => FormVersionCreateOrConnectWithoutWidgetsInputObjectSchema).optional(),
  }),
  z.object({
    connect: z.lazy(() => FormVersionWhereUniqueInputObjectSchema).optional(),
  }),
]);

This looks fine at first glance, but making all of create, connectOrCreate, and connect optional makes parse return an empty object {}.

console.log(
    WidgetCreateInputObjectSchema.parse({
      step: { connect: { id: 1 } },
      version: { connect: { id: 2 } },
    }),
  );
// { "version": {}, "step": {} }

However if you drop the .optional off any (or all, realistically) of the union types:

const schema = z
    .object({
      version: z.lazy(() =>
        z.union([
          z.object({
            create: z.union([
              z.lazy(() => FormVersionCreateWithoutWidgetsInputObjectSchema),
              z.lazy(() => FormVersionUncheckedCreateWithoutWidgetsInputObjectSchema),
            ]),
          }),
          z.object({
            connectOrCreate: z.lazy(() => FormVersionCreateOrConnectWithoutWidgetsInputObjectSchema),
          }),
          z.object({
            connect: z.lazy(() =>
              z
                .object({
                  id: z.number(),
                })
                .strict(),
            ),
          }),
        ]),
      ),
      step: z.lazy(() => StepCreateNestedOneWithoutWidgetsInputObjectSchema),
    })
    .strict();

then the output works as expected:

console.log(
    schema.parse({
      step: { connect: { id: 1 } },
      version: { connect: { id: 2 } },
    }),
  );
// { "version": { "connect": { "id": 2 } }, "step": {} }

How to reproduce

See above.

Expected behavior

Parsing correctly structured input should not return an empty object.

Prisma information

model Form {
  id    Int @id @default(autoincrement())
}

model Step {
  // Identifier Fields
  id      Int @id @default(autoincrement())
  formid  Int

  // 1:N Relationships
  form    Form        @relation(fields: [formId], references: [id], onDelete: Cascade)
  widgets Widget[]
}

model Widget {
  // Identifier Fields
  id        Int @id @default(autoincrement())
  versionId Int
  stepId    Int

  // 1:N Relationships
  form   Form @relation(fields: [formid], references: [id], onDelete: Cascade)
  step   Step  @relation(fields: [stepId], references: [id], onDelete: Cascade)
}

Environment & setup

  • OS: MacOS
  • Database: PostgreSQL
  • Node.js version: 16.13.2

Prisma Version

4.2.1

<ModelName>CreateManySchema, data expects object and not array.

Bug description

When creating schemas for a model ("MyModel") the MyModelCreateManySchema schema will have a data property that points to the schema MyModelCreateManyInputObjectSchema.

MyModelCreateManyInputObjectSchema is defined to be an object with the model fields and not an array of objects.

As the name implies I'm expecting this to be the input that corresponds to the prisma model.createMany input. But they do not match since the zod-schema does not accept array of objects.

How to reproduce

  1. Create any Prisma model.
  2. Generate schemas.
  3. Look in generated/schemas/createMany<modelname>.schema.ts and generated/schemas/objects/<modelname>CreateManyInput.schema

Expected behavior

<modelname>CreateManyInputObjectSchema should be a schema for an array of objects of type

Prisma information

Not specific for my schema will be same for any.

Environment & setup

  • OS: Windows
  • Database: Postgres
  • Node.js version: 18.12.1

Prisma Version

4.7.0

Extra validation on generated output - e.g minlength of string

Bug description

Given a user model like

model User{
   email string
}

produces the generated class

const UserCreateOneSchema = z.object({ email: z.string() });

However, using validation against this schema on a formSubmit coerces undefined into an empty string, or inputs with no data become empty strings and this validation succeeds.

Ideally email isn't: ''

Would be handy to have some sort of way of specify minLength

How to reproduce

  1. validate using schema in a form onsubmit method

Expected behavior

  1. Some way of specifying validation requirements

Prisma information

Prisma v4

Environment & setup

macOs

Prisma Version

4

Pure model schema?

Problem

Does this library generate pure model schema? It should be, for example, the output of findUnique (not the argument of findUnique). I try to find this, but cannot find any file having such thing (probably missed in tons of files).

Suggested solution

Just generate the zod based on the model itself. Similar to the output of zod-prisma.

Buffer/bytes not supported

Bug description

When a schema has type Bytes, the resulting zod schema excludes the column.

// prisma types
  export type UserCreateManyInput = {
    id?: string
    phone_hash: Buffer
  }
// result
const Schema: z.ZodType<Prisma.UserCreateManyInput> = z
  .object({
    id: z.string().optional(),
  })
  .strict();

How to reproduce

Use a schema that has Bytes as a type, run the generator, see it not included

Expected behavior

It should support Bytes

Prisma information

model User {
  id                         String                   @id @default(uuid())
  phone_hash        Bytes                   @unique
}

Environment & setup

  • OS: MacOs
  • Database: PostgreSQL
  • Node.js version: v16.13.0

Prisma Version

prisma                  : 4.3.1
@prisma/client          : 4.4.0
Current platform        : darwin-arm64
Query Engine (Node-API) : libquery-engine c875e43600dfe042452e0b868f7a48b817b9640b (at ../../../../../../.config/yarn/global/node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Migration Engine        : migration-engine-cli c875e43600dfe042452e0b868f7a48b817b9640b (at ../../../../../../.config/yarn/global/node_modules/@prisma/engines/migration-engine-darwin-arm64)
Introspection Engine    : introspection-core c875e43600dfe042452e0b868f7a48b817b9640b (at ../../../../../../.config/yarn/global/node_modules/@prisma/engines/introspection-engine-darwin-arm64)
Format Binary           : prisma-fmt c875e43600dfe042452e0b868f7a48b817b9640b (at ../../../../../../.config/yarn/global/node_modules/@prisma/engines/prisma-fmt-darwin-arm64)
Format Wasm             : @prisma/prisma-fmt-wasm 4.3.0-32.c875e43600dfe042452e0b868f7a48b817b9640b
Default Engines Hash    : c875e43600dfe042452e0b868f7a48b817b9640b
Studio                  : 0.473.0

Drop the explicit types and let the ts infer types

Problem

When using this library (as an alternative to zod-prisma), I want to get the zod schemas of my database models and to achieve that I use the CreateInputs but the issue is that currently we lose some of the abilities of the type inference when we explicitly set the type.

Eg

import { z } from 'zod';

import type { Prisma } from '@prisma/client';

const Schema: z.ZodType<Prisma.UserSettingsCreateInput> = z
  .object({
    deactivated: z.boolean(),
    language: z.string(),
  })
  .strict();

export const UserSettingsCreateInputObjectSchema = Schema;

As stated in the docs for generic functions (but it applies here as well) when using z.ZodType<T>, this is the toplevel type that all zod types inherit from, meaning we lose the individual functions of the types. For example you cannot extend or merge on an z.object

Suggested solution

If we just drop the explicit z.ZodType<T> the typescript will infer it correctly for us and all of the functionality for the specific zod type will be available. N

import { z } from 'zod';

const Schema = z
  .object({
    deactivated: z.boolean(),
    language: z.string(),
  })
  .strict();

export const UserSettingsCreateInputObjectSchema = Schema;

Not sure if this would break something else but it seems redundant to specify the type here instead of letting the TS infer it

Doesn't work for ESM modules

Bug description

All the imports would need to end with .js extension.

How to reproduce

Try to use in a ESM module.

Expected behavior

No response

Prisma information

Environment & setup

  • OS:
  • Database:
  • Node.js version:

Prisma Version


Re-use Zod Schemas as a z.ZodObject not z.ZodType

Problem

Generated schemas are not reusable (pick/omit/extend/etc) because the schema infers a type and is not considered a ZodObject anymore. An example...

const Schema: z.ZodType<Prisma.TodoCreateInput> = z.object({
  title: z.union([
    z.string(),
    z.lazy(() => StringFieldUpdateOperationsInputObjectSchema),
  ])
}).strict();
export const TodoCreateInput = Schema;

In the above, it is impossible to use TodoCreateInput.extend(), etc because the type z.ZodType<...> is being inferred.

Suggested solution

There was a similar discussion in the Zod repo in 1192 and a solution in 1495.

One solution is to change the example above to resolve like the one below. I haven't fully tested this but it seems to work with my simple examples:

const Schema = z.object({
  title: z.union([
    z.string(),
    z.lazy(() => StringFieldUpdateOperationsInputObjectSchema),
  ])
}).strict() satisfies z.ZodType<Prisma.TodoCreateInput>;
export const TodoCreateInput = Schema;

Alternatives

Alternatively, the Schema could be created as a ZodObject and exported as such, and then the ZodType exported separately. This way we can do what we want with the schema or export it as a type. Best of both worlds.

export const TodoCreateInputSchema = z.object({
  title: z.union([
    z.string(),
    z.lazy(() => StringFieldUpdateOperationsInputObjectSchema),
  ])
}).strict();
export const TodoCreateInputSchemaType: z.ZodType<Prisma.TodoCreateInput> = Schema;

Additional context

No other context.

Typescript errors in the generated router

Bug description

The generated router at generated/routers/Post.router.ts

 createOnePost: protectedProcedure
    .input(PostCreateOneSchema).mutation(async ({ ctx, input }) => {
      const createOnePost = await ctx.prisma.post.create(input);
      return createOnePost;
    }),

has the following error

Argument of type '{ data: (PostCreateInput | PostUncheckedCreateInput) & (PostCreateInput | PostUncheckedCreateInput | undefined); }' is not assignable to parameter of type '{ select?: PostSelect | null | undefined; include?: PostInclude | null | undefined; data: (Without<PostCreateInput, PostUncheckedCreateInput> & PostUncheckedCreateInput) | (Without<...> & PostCreateInput); }'.
  Types of property 'data' are incompatible.
    Type '(PostCreateInput | PostUncheckedCreateInput) & (PostCreateInput | PostUncheckedCreateInput | undefined)' is not assignable to type '(Without<PostCreateInput, PostUncheckedCreateInput> & PostUncheckedCreateInput) | (Without<...> & PostCreateInput)'.
      Type 'PostCreateInput & PostUncheckedCreateInput' is not assignable to type '(Without<PostCreateInput, PostUncheckedCreateInput> & PostUncheckedCreateInput) | (Without<...> & PostCreateInput)'.
        Type 'PostCreateInput & PostUncheckedCreateInput' is not assignable to type 'Without<PostUncheckedCreateInput, PostCreateInput> & PostCreateInput'.
          Type 'PostCreateInput & PostUncheckedCreateInput' is not assignable to type 'Without<PostUncheckedCreateInput, PostCreateInput>'.
            Types of property 'id' are incompatible.
              Type 'number | undefined' is not assignable to type 'undefined'.
                Type 'number' is not assignable to type 'undefined'.ts(2345)

How to reproduce

  1. Use the sample schema

Expected behavior

No response

Prisma information

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

generator trpc {
provider = "prisma-trpc-generator"
// output = "../../trpc/init/src/generated"
output = "./generated"
withMiddleware = "../../trpc/init/src/middleware"
withShield = false
contextPath = "../../trpc/init/src/context"
trpcOptionsPath = "../../trpc/init/src/trpcOptions"
}

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

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
books Book[]
}

model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
content String?
published Boolean @default(false)
viewCount Int @default(0)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
likes BigInt
}

/// @@Gen.model(hide: true)
model Book {
id Int @unique
title String
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}

model Map {
key String @id
value String
}

Environment & setup

  • OS: MacOS
  • Database: Postgres
  • Node.js version:18

Prisma Version

4.11.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.