Skip to content

Commit 7826da3

Browse files
authored
chore: require zod4 or above (#348)
* chore: require zod4 or above * update * update
1 parent 4e8a1f1 commit 7826da3

File tree

29 files changed

+1642
-2682
lines changed

29 files changed

+1642
-2682
lines changed

BREAKINGCHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
1. `check()` ORM api has been removed
33
1. non-optional to-one relation doesn't automatically filter parent read when evaluating access policies
44
1. `@omit` and `@password` attributes have been removed
5+
1. SWR plugin is removed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "zenstack-v3",
33
"version": "3.0.0-beta.14",
44
"description": "ZenStack",
5-
"packageManager": "pnpm@10.12.1",
5+
"packageManager": "pnpm@10.20.0",
66
"scripts": {
77
"build": "turbo run build",
88
"watch": "turbo run watch build",

packages/orm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,6 @@
9797
"@zenstackhq/typescript-config": "workspace:*",
9898
"@zenstackhq/vitest-config": "workspace:*",
9999
"tsx": "^4.19.2",
100-
"zod": "~3.25.0"
100+
"zod": "^4.1.0"
101101
}
102102
}

packages/orm/src/client/crud/validator/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { enumerate, invariant } from '@zenstackhq/common-helpers';
22
import Decimal from 'decimal.js';
33
import stableStringify from 'json-stable-stringify';
44
import { match, P } from 'ts-pattern';
5-
import { z, ZodSchema, ZodType } from 'zod';
5+
import { z, ZodType } from 'zod';
66
import {
77
type AttributeApplication,
88
type BuiltinType,
@@ -830,7 +830,7 @@ export class InputValidator<Schema extends SchemaDef> {
830830

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

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

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

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

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

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

14161416
// fields used in `orderBy` must be either in the `by` list, or aggregations
1417-
schema = schema.refine((value) => {
1417+
schema = schema.refine((value: any) => {
14181418
const bys = typeof value.by === 'string' ? [value.by] : value.by;
14191419
if (
14201420
value.orderBy &&

packages/orm/src/client/crud/validator/utils.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
import Decimal from 'decimal.js';
1212
import { match, P } from 'ts-pattern';
1313
import { z } from 'zod';
14+
import { ZodIssueCode } from 'zod/v3';
1415
import { ExpressionUtils } from '../../../schema';
1516
import { QueryError } from '../../errors';
1617

@@ -171,8 +172,26 @@ export function addDecimalValidation(
171172
return schema.superRefine((v, ctx) => {
172173
const base = z.number();
173174
const { error } = base[op](value).safeParse((v as Decimal).toNumber());
174-
error?.errors.forEach((e) => {
175-
ctx.addIssue(e);
175+
error?.issues.forEach((issue) => {
176+
if (op === 'gt' || op === 'gte') {
177+
ctx.addIssue({
178+
code: ZodIssueCode.too_small,
179+
origin: 'number',
180+
minimum: value,
181+
type: 'decimal',
182+
inclusive: op === 'gte',
183+
message: issue.message,
184+
});
185+
} else {
186+
ctx.addIssue({
187+
code: ZodIssueCode.too_big,
188+
origin: 'number',
189+
maximum: value,
190+
type: 'decimal',
191+
inclusive: op === 'lte',
192+
message: issue.message,
193+
});
194+
}
176195
});
177196
});
178197
}
@@ -258,9 +277,9 @@ function applyValidation(
258277
message: string | undefined,
259278
path: string[] | undefined,
260279
) {
261-
const options: z.CustomErrorParams = {};
280+
const options: Parameters<typeof schema.refine>[1] = {};
262281
if (message) {
263-
options.message = message;
282+
options.error = message;
264283
}
265284
if (path) {
266285
options.path = path;
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import { ZodError } from 'zod';
2-
import { fromError as fromError3 } from 'zod-validation-error/v3';
3-
import { fromError as fromError4 } from 'zod-validation-error/v4';
2+
import { fromError } from 'zod-validation-error/v4';
43

54
/**
65
* Format ZodError into a readable string
76
*/
87
export function formatError(error: ZodError): string {
9-
if ('_zod' in error) {
10-
return fromError4(error).toString();
11-
} else {
12-
return fromError3(error).toString();
13-
}
8+
return fromError(error).toString();
149
}

packages/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
"next": "^15.0.0",
150150
"nuxt": "^4.2.0",
151151
"supertest": "^7.1.4",
152-
"zod": "~3.25.0"
152+
"zod": "^4.1.0"
153153
},
154154
"peerDependencies": {
155155
"@sveltejs/kit": "^2.0.0",

packages/testtools/src/vitest-ext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function expectError(err: any, errorType: any) {
2121

2222
function expectErrorMessages(expectedMessages: string[], message: string) {
2323
for (const m of expectedMessages) {
24-
if (!message.includes(m)) {
24+
if (!message.toLowerCase().includes(m.toLowerCase())) {
2525
return {
2626
message: () => `expected message not found in error: ${m}, got message: ${message}`,
2727
pass: false,

packages/zod/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"devDependencies": {
3232
"@zenstackhq/eslint-config": "workspace:*",
3333
"@zenstackhq/typescript-config": "workspace:*",
34-
"zod": "~3.25.0"
34+
"zod": "^4.1.0"
3535
},
3636
"peerDependencies": {
3737
"zod": "catalog:"

pnpm-lock.yaml

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)