Skip to content

Commit

Permalink
chore: fix number and bigint coercion
Browse files Browse the repository at this point in the history
  • Loading branch information
lifeiscontent authored and edmundhung committed Aug 17, 2024
1 parent 55a8a4e commit e4ceab9
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-actors-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@conform-to/zod': minor
---

fix number and bigint coercion
21 changes: 16 additions & 5 deletions packages/conform-zod/coercion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export function enableTypeCoercion<Schema extends ZodTypeAny>(
schema = any()
.transform((value) =>
coerceString(value, (text) =>
text.trim() === '' ? Number.NaN : Number(text),
text.trim() === '' ? text : Number(text),
),
)
.pipe(type);
Expand All @@ -132,14 +132,14 @@ export function enableTypeCoercion<Schema extends ZodTypeAny>(
} 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;
Expand All @@ -148,7 +148,18 @@ export function enableTypeCoercion<Schema extends ZodTypeAny>(
.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()
Expand Down
68 changes: 68 additions & 0 deletions tests/conform-zod.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e4ceab9

Please sign in to comment.