From f04003972a3cc7875beb073ff88c942deb6a2086 Mon Sep 17 00:00:00 2001 From: Igor Brasileiro Date: Fri, 25 Jul 2025 09:48:53 -0300 Subject: [PATCH 1/5] feat(ajv): add ajv-formats for ajvResolver (#797) * add ajv-formats for ajvResolver * change lint command and add @biomejs/biome as dev dep --- ajv/package.json | 3 ++- ajv/src/ajv.ts | 2 ++ bun.lock | 22 ++++++++++++++++++++++ package.json | 4 +++- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ajv/package.json b/ajv/package.json index c8d0b756..6200a811 100644 --- a/ajv/package.json +++ b/ajv/package.json @@ -14,6 +14,7 @@ "react-hook-form": "^7.55.0", "@hookform/resolvers": "^2.0.0", "ajv": "^8.12.0", - "ajv-errors": "^3.0.0" + "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1" } } diff --git a/ajv/src/ajv.ts b/ajv/src/ajv.ts index 958947f0..12f34a5a 100644 --- a/ajv/src/ajv.ts +++ b/ajv/src/ajv.ts @@ -1,6 +1,7 @@ import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers'; import Ajv, { DefinedError } from 'ajv'; import ajvErrors from 'ajv-errors'; +import addFormats from 'ajv-formats'; import { FieldError, appendErrors } from 'react-hook-form'; import { AjvError, Resolver } from './types'; @@ -93,6 +94,7 @@ export const ajvResolver: Resolver = ); ajvErrors(ajv); + addFormats(ajv); const validate = ajv.compile( Object.assign( diff --git a/bun.lock b/bun.lock index 6fbd1cf3..3c54f718 100644 --- a/bun.lock +++ b/bun.lock @@ -7,6 +7,7 @@ "@standard-schema/utils": "^0.3.0", }, "devDependencies": { + "@biomejs/biome": "^1.8.3", "@sinclair/typebox": "^0.34.30", "@standard-schema/spec": "^1.0.0", "@testing-library/dom": "^10.4.0", @@ -22,6 +23,7 @@ "@vitejs/plugin-react": "^4.3.4", "ajv": "^8.17.1", "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1", "arktype": "2.0.4", "check-export-map": "^1.3.1", "class-transformer": "^0.5.1", @@ -274,6 +276,24 @@ "@babel/types": ["@babel/types@7.27.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="], + "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="], + "@csstools/color-helpers": ["@csstools/color-helpers@5.0.2", "", {}, "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA=="], "@csstools/css-calc": ["@csstools/css-calc@2.1.2", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3" } }, "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw=="], @@ -484,6 +504,8 @@ "ajv-errors": ["ajv-errors@3.0.0", "", { "peerDependencies": { "ajv": "^8.0.1" } }, "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ=="], + "ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], diff --git a/package.json b/package.json index 7319445c..9b66a9ff 100644 --- a/package.json +++ b/package.json @@ -222,7 +222,7 @@ "build:fluentvalidation-ts": "microbundle --cwd fluentvalidation-ts --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm", "build:standard-schema": "microbundle --cwd standard-schema --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm,@standard-schema/spec=standardSchema", "postbuild": "node ./config/node-13-exports.js && check-export-map", - "lint": "bunx @biomejs/biome check --write --vcs-use-ignore-file=true .", + "lint": "biome check --write --vcs-use-ignore-file=true .", "lint:types": "tsc", "test": "vitest run", "test:watch": "vitest watch", @@ -267,6 +267,7 @@ }, "homepage": "https://react-hook-form.com/", "devDependencies": { + "@biomejs/biome": "^1.8.3", "@sinclair/typebox": "^0.34.30", "@standard-schema/spec": "^1.0.0", "@testing-library/dom": "^10.4.0", @@ -282,6 +283,7 @@ "@vitejs/plugin-react": "^4.3.4", "ajv": "^8.17.1", "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1", "arktype": "2.0.4", "check-export-map": "^1.3.1", "class-transformer": "^0.5.1", From 2d28e6aca611b042e07da0ae4cf448adbe78e1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20LUDWIG?= Date: Tue, 29 Jul 2025 15:29:51 +0200 Subject: [PATCH 2/5] fix: zod v4 peer deps (#798) --- zod/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zod/package.json b/zod/package.json index 77f1eaaf..f415f3c2 100644 --- a/zod/package.json +++ b/zod/package.json @@ -13,6 +13,6 @@ "peerDependencies": { "react-hook-form": "^7.55.0", "@hookform/resolvers": "^2.0.0", - "zod": "^3.25.0" + "zod": "^3.25.0 || ^4.0.0" } } From bc09647a5eec21d07097a8ccf89fb52ebf50a1ec Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 29 Jul 2025 15:30:48 +0200 Subject: [PATCH 3/5] fix(zod): fix output type for Zod 4 resolver (#801) Signed-off-by: Sefa Eyeoglu --- zod/src/zod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zod/src/zod.ts b/zod/src/zod.ts index 0e227eb6..2f25f9cf 100644 --- a/zod/src/zod.ts +++ b/zod/src/zod.ts @@ -215,7 +215,7 @@ export function zodResolver< schema: z4.$ZodType, schemaOptions: Zod4ParseParams | undefined, // already partial resolverOptions: RawResolverOptions, -): Resolver, Context, z4.input>; +): Resolver, Context, z4.output>; /** * Creates a resolver function for react-hook-form that validates form data using a Zod schema * @param {z3.ZodSchema} schema - The Zod schema used to validate the form data From 49a0d7ba939f58e04ca2d01a98949fc70f50b53e Mon Sep 17 00:00:00 2001 From: Elio Capella Date: Tue, 29 Jul 2025 15:32:52 +0200 Subject: [PATCH 4/5] fix: discriminated union for zod v4 mini (#784) --- zod/src/__tests__/__fixtures__/data-v4-mini.ts | 14 ++++++++++++++ zod/src/zod.ts | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/zod/src/__tests__/__fixtures__/data-v4-mini.ts b/zod/src/__tests__/__fixtures__/data-v4-mini.ts index 11bab770..d6ebb23e 100644 --- a/zod/src/__tests__/__fixtures__/data-v4-mini.ts +++ b/zod/src/__tests__/__fixtures__/data-v4-mini.ts @@ -43,6 +43,15 @@ export const schema = z message: 'Invalid date', }), ), + auth: z.discriminatedUnion('type', [ + z.object({ + type: z.literal('registered'), + passwordHash: z.string(), + }), + z.object({ + type: z.literal('guest'), + }), + ]), }) .check( z.refine((obj) => obj.password === obj.repeatPassword, { @@ -68,6 +77,10 @@ export const validData = { }, ], dateStr: '2020-01-01', + auth: { + type: 'registered', + passwordHash: 'hash', + }, } satisfies z.input; export const invalidData = { @@ -76,6 +89,7 @@ export const invalidData = { birthYear: 'birthYear', like: [{ id: 'z' }], url: 'abc', + auth: { type: 'invalid' }, } as unknown as z.input; export const fields: Record = { diff --git a/zod/src/zod.ts b/zod/src/zod.ts index 2f25f9cf..ff55dfce 100644 --- a/zod/src/zod.ts +++ b/zod/src/zod.ts @@ -91,7 +91,7 @@ function parseZod4Issues( const _path = path.join('.'); if (!errors[_path]) { - if (error.code === 'invalid_union') { + if (error.code === 'invalid_union' && error.errors.length > 0) { const unionError = error.errors[0][0]; errors[_path] = { From e95721d3c8c6d6e555508b0e7b21c6ac801360cf Mon Sep 17 00:00:00 2001 From: Jinwoo Date: Sun, 14 Sep 2025 17:26:02 +0900 Subject: [PATCH 5/5] fix(zod): fix output type for Zod 4 resolver (#803) This reverts commit bc09647a5eec21d07097a8ccf89fb52ebf50a1ec. --- zod/src/zod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zod/src/zod.ts b/zod/src/zod.ts index ff55dfce..461d6a8a 100644 --- a/zod/src/zod.ts +++ b/zod/src/zod.ts @@ -215,7 +215,7 @@ export function zodResolver< schema: z4.$ZodType, schemaOptions: Zod4ParseParams | undefined, // already partial resolverOptions: RawResolverOptions, -): Resolver, Context, z4.output>; +): Resolver, Context, z4.input>; /** * Creates a resolver function for react-hook-form that validates form data using a Zod schema * @param {z3.ZodSchema} schema - The Zod schema used to validate the form data