omar-dulaimi / prisma-zod-generator

Prisma 2+ generator to emit Zod schemas from your Prisma schema
MIT License
535 stars 45 forks source link

Validation prevents multiple relationship actions #48

Closed kristinlindquist closed 1 year ago

kristinlindquist commented 1 year ago

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. https://github.com/prisma/prisma/issues/2255#issuecomment-683811551)

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

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
Shahidul1004 commented 1 year ago

I am working on this issue. Hopefully, we will have a PR soon

Shahidul1004 commented 1 year ago

I find out that z.union is responsible for this problem. As we are wrapping the schemas inside z.union, we can not use multiple fields inside it. So in general, this problem will arise not only for deleteMany and createMany but also for any fields if we want to use multiple fields.

@omar-dulaimi, Could you please tell us why we need to wrap the schemas with z.union if the fields contain connectOrCreate: or connect: inside the addFinalWrappers function during generating object schemas? What is the insight of it? If I remove this logic and simply wrap the whole schemas with z.object, then I am not getting any issues. Screenshot from 2022-12-01 06-56-34

omar-dulaimi commented 1 year ago

@Shahidul1004 I remember it was for an old bug, but I guess it was solved with the later changes. I'll give your changes a try and see if it works well.

omar-dulaimi commented 1 year ago

Released in https://github.com/omar-dulaimi/prisma-zod-generator/releases/tag/0.8.2