Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BREAKINGCHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
1. `check()` ORM api has been removed
1. non-optional to-one relation doesn't automatically filter parent read when evaluating access policies
1. `@omit` and `@password` attributes have been removed
1. SWR plugin is removed
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "zenstack-v3",
"version": "3.0.0-beta.14",
"description": "ZenStack",
"packageManager": "pnpm@10.12.1",
"packageManager": "pnpm@10.20.0",
"scripts": {
"build": "turbo run build",
"watch": "turbo run watch build",
Expand Down
2 changes: 1 addition & 1 deletion packages/orm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@
"@zenstackhq/typescript-config": "workspace:*",
"@zenstackhq/vitest-config": "workspace:*",
"tsx": "^4.19.2",
"zod": "~3.25.0"
"zod": "^4.1.0"
}
}
16 changes: 8 additions & 8 deletions packages/orm/src/client/crud/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { enumerate, invariant } from '@zenstackhq/common-helpers';
import Decimal from 'decimal.js';
import stableStringify from 'json-stable-stringify';
import { match, P } from 'ts-pattern';
import { z, ZodSchema, ZodType } from 'zod';
import { z, ZodType } from 'zod';
import {
type AttributeApplication,
type BuiltinType,
Expand Down Expand Up @@ -830,7 +830,7 @@ export class InputValidator<Schema extends SchemaDef> {

private makeCreateSchema(model: string) {
const dataSchema = this.makeCreateDataSchema(model, false);
let schema: ZodSchema = z.strictObject({
let schema: ZodType = z.strictObject({
data: dataSchema,
select: this.makeSelectSchema(model).optional(),
include: this.makeIncludeSchema(model).optional(),
Expand Down Expand Up @@ -1107,7 +1107,7 @@ export class InputValidator<Schema extends SchemaDef> {
// #region Update

private makeUpdateSchema(model: string) {
let schema: ZodSchema = z.strictObject({
let schema: ZodType = z.strictObject({
where: this.makeWhereSchema(model, true),
data: this.makeUpdateDataSchema(model),
select: this.makeSelectSchema(model).optional(),
Expand All @@ -1129,7 +1129,7 @@ export class InputValidator<Schema extends SchemaDef> {

private makeUpdateManyAndReturnSchema(model: string) {
const base = this.makeUpdateManySchema(model);
let schema: ZodSchema = base.extend({
let schema: ZodType = base.extend({
select: this.makeSelectSchema(model).optional(),
omit: this.makeOmitSchema(model).optional(),
});
Expand All @@ -1138,7 +1138,7 @@ export class InputValidator<Schema extends SchemaDef> {
}

private makeUpsertSchema(model: string) {
let schema: ZodSchema = z.strictObject({
let schema: ZodType = z.strictObject({
where: this.makeWhereSchema(model, true),
create: this.makeCreateDataSchema(model, false),
update: this.makeUpdateDataSchema(model),
Expand Down Expand Up @@ -1257,7 +1257,7 @@ export class InputValidator<Schema extends SchemaDef> {
// #region Delete

private makeDeleteSchema(model: GetModels<Schema>) {
let schema: ZodSchema = z.strictObject({
let schema: ZodType = z.strictObject({
where: this.makeWhereSchema(model, true),
select: this.makeSelectSchema(model).optional(),
include: this.makeIncludeSchema(model).optional(),
Expand Down Expand Up @@ -1387,7 +1387,7 @@ export class InputValidator<Schema extends SchemaDef> {
});

// fields used in `having` must be either in the `by` list, or aggregations
schema = schema.refine((value) => {
schema = schema.refine((value: any) => {
const bys = typeof value.by === 'string' ? [value.by] : value.by;
if (value.having && typeof value.having === 'object') {
for (const [key, val] of Object.entries(value.having)) {
Expand All @@ -1414,7 +1414,7 @@ export class InputValidator<Schema extends SchemaDef> {
}, 'fields in "having" must be in "by"');

// fields used in `orderBy` must be either in the `by` list, or aggregations
schema = schema.refine((value) => {
schema = schema.refine((value: any) => {
const bys = typeof value.by === 'string' ? [value.by] : value.by;
if (
value.orderBy &&
Expand Down
26 changes: 22 additions & 4 deletions packages/orm/src/client/crud/validator/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,26 @@ export function addDecimalValidation(
return schema.superRefine((v, ctx) => {
const base = z.number();
const { error } = base[op](value).safeParse((v as Decimal).toNumber());
error?.errors.forEach((e) => {
ctx.addIssue(e);
error?.issues.forEach((issue) => {
if (op === 'gt' || op === 'gte') {
ctx.addIssue({
code: 'too_small',
origin: 'number',
minimum: value,
type: 'decimal',
inclusive: op === 'gte',
message: issue.message,
});
} else {
ctx.addIssue({
code: 'too_big',
origin: 'number',
maximum: value,
type: 'decimal',
inclusive: op === 'lte',
message: issue.message,
});
}
});
});
}
Expand Down Expand Up @@ -258,9 +276,9 @@ function applyValidation(
message: string | undefined,
path: string[] | undefined,
) {
const options: z.CustomErrorParams = {};
const options: Parameters<typeof schema.refine>[1] = {};
if (message) {
options.message = message;
options.error = message;
}
if (path) {
options.path = path;
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
"next": "^15.0.0",
"nuxt": "^4.2.0",
"supertest": "^7.1.4",
"zod": "~3.25.0"
"zod": "^4.1.0"
},
"peerDependencies": {
"@sveltejs/kit": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/src/vitest-ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function expectError(err: any, errorType: any) {

function expectErrorMessages(expectedMessages: string[], message: string) {
for (const m of expectedMessages) {
if (!message.includes(m)) {
if (!message.toLowerCase().includes(m.toLowerCase())) {
return {
message: () => `expected message not found in error: ${m}, got message: ${message}`,
pass: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/zod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"devDependencies": {
"@zenstackhq/eslint-config": "workspace:*",
"@zenstackhq/typescript-config": "workspace:*",
"zod": "~3.25.0"
"zod": "^4.1.0"
},
"peerDependencies": {
"zod": "catalog:"
Expand Down
26 changes: 13 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ packages:
- tests/**
catalog:
kysely: ^0.27.6
zod: ^3.25.0 || ^4.0.0
zod: ^4.0.0
prisma: ^6.10.0
langium: 3.5.0
langium-cli: 3.5.0
Expand Down
Loading