zenstackhq / zenstack

Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
https://zenstack.dev
MIT License
2.07k stars 88 forks source link

Create operation does not accept undefined value #765

Closed iksemot closed 11 months ago

iksemot commented 12 months ago

Description and expected behavior

Method create errors because of undefined as the value of relation.

The workaround is to use {} but undefined is valid and allowed in pure PrismaClient.

Environment (please complete the following information):

Additional context

Given data model:

// 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 = "sqlite"
  url      = env("DATABASE_URL")
}

model User {
  id    Int     @id @default(autoincrement())
  name  String

  post   Post? @relation(fields: [postId], references: [id])
  postId Int?

  @@allow('all', true)
}

model Post {
  id    Int    @id @default(autoincrement())
  title String
  User  User[]

  @@allow('all', true)
}

Following code:

const prisma = enhance(new PrismaClient(), {})

const user = await prisma.user.create({
  data: {
    name: 'Me',
    post: undefined
  }
})

Errors with:

Error calling enhanced Prisma method `create`: Cannot convert undefined or null to object
    at C:\Users\tomas\workspace\playground\zenstack_\src\zenstack.ts:9:32,
    at Generator.next (<anonymous>),
    at C:\Users\tomas\workspace\playground\zenstack_\src\zenstack.ts:8:71,
    at new Promise (<anonymous>),
    at __awaiter (C:\Users\tomas\workspace\playground\zenstack_\src\zenstack.ts:4:12),
    at main (C:\Users\tomas\workspace\playground\zenstack_\src\zenstack.ts:16:12),
    at Object.<anonymous> (C:\Users\tomas\workspace\playground\zenstack_\src\zenstack.ts:36:3),
    at Module._compile (node:internal/modules/cjs/loader:1256:14),
    at Module.m._compile (C:\Users\tomas\workspace\playground\zenstack_\node_modules\ts-node\src\index.ts:1618:23) {
  internalStack: 'TypeError: Cannot convert undefined or null to object\n' +
    '    at Function.entries (<anonymous>)\n' +
    '    at NestedWriteVisitor.<anonymous> (C:\\Users\\tomas\\workspace\\playground\\zenstack_\\node_modules\\@zenstackhq\\src\\enhancements\\nested-write-visitor.ts:327:59)\n' +
    '    at Generator.next (<anonymous>)\n' +
    '    at C:\\Users\\tomas\\workspace\\playground\\zenstack_\\node_modules\\@zenstackhq\\runtime\\enhancements\\nested-write-visitor.js:10:71\n' +
    '    at new Promise (<anonymous>)\n' +
    '    at __awaiter (C:\\Users\\tomas\\workspace\\playground\\zenstack_\\node_modules\\@zenstackhq\\runtime\\enhancements\\nested-write-visitor.js:6:12)\n' +
    '    at NestedWriteVisitor.visitSubPayload (C:\\Users\\tomas\\workspace\\playground\\zenstack_\\node_modules\\@zenstackhq\\runtime\\enhancements\\nested-write-visitor.js:208:16)\n' +
    '    at NestedWriteVisitor.<anonymous> (C:\\Users\\tomas\\workspace\\playground\\zenstack_\\node_modules\\@zenstackhq\\src\\enhancements\\nested-write-visitor.ts:154:36)\n' +
    '    at Generator.next (<anonymous>)\n' +
    '    at fulfilled (C:\\Users\\tomas\\workspace\\playground\\zenstack_\\node_modules\\@zenstackhq\\runtime\\enhancements\\nested-write-visitor.js:7:58)'
}
ymc9 commented 12 months ago

And this one too!

Azzerty23 commented 11 months ago

I have a similar issue (if not the same), but just in case it can help :

// 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 = "sqlite"
  url      = env("DATABASE_URL")
}

model User {
  id  String     @id @default(autoincrement())
  name  String

  createdPosts  Post[] @relation("CreatedPosts")

  @@allow('all', true)
}

model Post {
  id    Int    @id @default(autoincrement())
  title String
  createdBy String?

  creator  User?  @relation("CreatedPosts", fields: [createdBy], references: [id], onDelete: Cascade)

  @@allow('all', true)
}

Following code:

const prisma = enhance(new PrismaClient(), {})

const post = await prisma.post.create({
  data: {
    title: 'Title',
    creator: {
          connect: {
            id: undefined,
          },
        },
  }
})

Errors with:

Uncaught (in promise) TRPCClientError: 
Invalid `this.prisma[this.model].create()` invocation in
/Users/augustin/Documents/Dev/Perso/schools/node_modules/@zenstackhq/runtime/enhancements/proxy.js:64:53

  61 create(args) {
  62     return __awaiter(this, void 0, void 0, function* () {
  63         args = yield this.preprocessArgs('create', args);
→ 64         const r = yield this.prisma[this.model].create({
               data: {
                 title: "",
                 creator: {
                   connect: {
                     id: undefined,
             ?       email?: String,
             ?       AND?: UserWhereInput | UserWhereInput[],
             ?       OR?: UserWhereInput[],
             ?       NOT?: UserWhereInput | UserWhereInput[],
             ?       name?: StringFilter | String,
             ?       createdPosts?: PostListRelationFilter,
                   }
                 }
               },
               select: {
                 id: true
               }
             })

Argument `connect` of type UserWhereUniqueInput needs at least one of `id` or `email` arguments. Available options are marked with ?.
    at TRPCClientError.from (transformResult-6fb67924.mjs:4:1)
    at eval (httpBatchLink.mjs:190:40)
ymc9 commented 11 months ago

Got it @Azzerty23 . Thanks! Working on a fix now 😄

ymc9 commented 11 months ago

Fixed in v1.1.1