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

[Feature Request] Custom zod validations #771

Closed olehmelnyk closed 10 months ago

olehmelnyk commented 11 months ago

Is your feature request related to a problem? Please describe. Can we extend zod generation with custom rules like this library - https://www.npmjs.com/package/zod-prisma-types#field-validators does with /// comments

ymc9 commented 11 months ago

Hey @olehmelnyk , ZenStack already has a built-in feature called field validation: https://zenstack.dev/docs/reference/zmodel-language#field-validation

Is it something you're looking for?

olehmelnyk commented 11 months ago

@ymc9 not really, Current prisma-to-zod can generate only basic zod validations - such as type (string/number/boolean) if the field is required and probably that's it... zod allows us to make even more advanced validations - like min/max length, regexp checks, transformation, validate one field based on another, etc. However, it's not possible to generate those additional checks from the Prisma schema. So there was another prisma-to-zod validation plugin created, that allows adding those additional zod-checks via Prisma comments ///

check this example - https://www.npmjs.com/package/zod-prisma-types#field-validators - this is the generator/plugin that works with native prisma. I want to work with ZenStack.

ymc9 commented 11 months ago

Hi @olehmelnyk , I might have some misunderstanding here, but my current feeling is what ZenStack's field validation feature does is pretty close to "zod-prisma-types"'s field validators, but with syntax native to ZModel. It supports basic type validation (min/max, regex, email, url, etc.), as well as custom refinement).

A sample usage looks like:

model Signup {
  id Int @id @default(autoincrement())
  name String
  email String @email @endsWith("@zenstack.dev", 'Must be a @zenstack.dev email')
  adult Boolean
  beverage String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@allow('create,read', true)

  @@validate(beverage in ['SODA', 'COFFEE', 'BEER', 'COCKTAIL'], 'Please choose a valid beverage')
  @@validate(adult || beverage in ['SODA', 'COFFEE'], 'You must be an adult to drink alcohol')
}

Here's a blog post explaining a usage scenario: https://zenstack.dev/blog/form-validation

If you have a concrete validation to implement, I can help check if it's possible with the current feature set.

ymc9 commented 10 months ago

Closing for now