From e4ceab93128052d5047c3e664c0c67d95d574bb3 Mon Sep 17 00:00:00 2001 From: Aaron Reisman Date: Fri, 9 Aug 2024 12:58:27 -0700 Subject: [PATCH 1/2] chore: fix number and bigint coercion --- .changeset/hip-actors-wink.md | 5 +++ packages/conform-zod/coercion.ts | 21 +++++++--- tests/conform-zod.spec.ts | 68 ++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 .changeset/hip-actors-wink.md diff --git a/.changeset/hip-actors-wink.md b/.changeset/hip-actors-wink.md new file mode 100644 index 00000000..842de257 --- /dev/null +++ b/.changeset/hip-actors-wink.md @@ -0,0 +1,5 @@ +--- +'@conform-to/zod': minor +--- + +fix number and bigint coercion diff --git a/packages/conform-zod/coercion.ts b/packages/conform-zod/coercion.ts index a6a8cd63..db584981 100644 --- a/packages/conform-zod/coercion.ts +++ b/packages/conform-zod/coercion.ts @@ -119,7 +119,7 @@ export function enableTypeCoercion( schema = any() .transform((value) => coerceString(value, (text) => - text.trim() === '' ? Number.NaN : Number(text), + text.trim() === '' ? text : Number(text), ), ) .pipe(type); @@ -132,14 +132,14 @@ export function enableTypeCoercion( } else if (def.typeName === 'ZodDate') { schema = any() .transform((value) => - coerceString(value, (timestamp) => { - const date = new Date(timestamp); + coerceString(value, (text) => { + const date = new Date(text); // z.date() does not expose a quick way to set invalid_date error // This gets around it by returning the original string if it's invalid // See https://github.com/colinhacks/zod/issues/1526 if (isNaN(date.getTime())) { - return timestamp; + return text; } return date; @@ -148,7 +148,18 @@ export function enableTypeCoercion( .pipe(type); } else if (def.typeName === 'ZodBigInt') { schema = any() - .transform((value) => coerceString(value, BigInt)) + .transform((value) => + coerceString(value, (text) => { + if (text.trim() === '') { + return text; + } + try { + return BigInt(text); + } catch { + return text; + } + }), + ) .pipe(type); } else if (def.typeName === 'ZodArray') { schema = any() diff --git a/tests/conform-zod.spec.ts b/tests/conform-zod.spec.ts index d642f1dc..124be2c0 100644 --- a/tests/conform-zod.spec.ts +++ b/tests/conform-zod.spec.ts @@ -405,6 +405,74 @@ describe('conform-zod', () => { }); }); + test('z.bigint', () => { + const schema = z.object({ + test: z + .bigint({ required_error: 'required', invalid_type_error: 'invalid' }) + .min(1n, 'min') + .max(10n, 'max') + .multipleOf(2n, 'step'), + }); + const file = new File([], ''); + + expect(parseWithZod(createFormData([]), { schema })).toEqual({ + status: 'error', + payload: {}, + error: { test: ['required'] }, + reply: expect.any(Function), + }); + expect( + parseWithZod(createFormData([['test', '']]), { + schema, + }), + ).toEqual({ + status: 'error', + payload: { test: '' }, + error: { test: ['required'] }, + reply: expect.any(Function), + }); + expect( + parseWithZod(createFormData([['test', 'abc']]), { + schema, + }), + ).toEqual({ + status: 'error', + payload: { test: 'abc' }, + error: { test: ['invalid'] }, + reply: expect.any(Function), + }); + expect( + parseWithZod(createFormData([['test', file]]), { + schema, + }), + ).toEqual({ + status: 'error', + payload: { test: file }, + error: { test: ['invalid'] }, + reply: expect.any(Function), + }); + expect( + parseWithZod(createFormData([['test', '5']]), { + schema, + }), + ).toEqual({ + status: 'error', + payload: { test: '5' }, + error: { test: ['step'] }, + reply: expect.any(Function), + }); + expect( + parseWithZod(createFormData([['test', ' ']]), { + schema, + }), + ).toEqual({ + status: 'error', + payload: { test: ' ' }, + error: { test: ['invalid'] }, + reply: expect.any(Function), + }); + }); + test('z.date', () => { const schema = z.object({ test: z From 43ed54962fa14aff9526685fd1a3a19a8c429408 Mon Sep 17 00:00:00 2001 From: Edmund Hung Date: Tue, 10 Sep 2024 23:05:23 +0100 Subject: [PATCH 2/2] update changeset message --- .changeset/hip-actors-wink.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/hip-actors-wink.md b/.changeset/hip-actors-wink.md index 842de257..3c93f050 100644 --- a/.changeset/hip-actors-wink.md +++ b/.changeset/hip-actors-wink.md @@ -2,4 +2,4 @@ '@conform-to/zod': minor --- -fix number and bigint coercion +feat(conform-zod): bigint coercion support