Skip to content

Commit

Permalink
feat(conform-zod): enable zod object coercion
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Aug 17, 2024
1 parent 55a8a4e commit b691537
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 11 deletions.
33 changes: 22 additions & 11 deletions packages/conform-zod/coercion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,28 @@ export function enableTypeCoercion<Schema extends ZodTypeAny>(
}),
);
} else if (def.typeName === 'ZodObject') {
const shape = Object.fromEntries(
Object.entries(def.shape()).map(([key, def]) => [
key,
// @ts-expect-error see message above
enableTypeCoercion(def, cache),
]),
);
schema = new ZodObject({
...def,
shape: () => shape,
});
schema = any()
.transform((value) => {
if (typeof value === 'undefined') {
// Defaults it to an empty object
return {};
}

return value;
})
.pipe(
new ZodObject({
...def,
shape: () =>
Object.fromEntries(
Object.entries(def.shape()).map(([key, def]) => [
key,
// @ts-expect-error see message above
enableTypeCoercion(def, cache),
]),
),
}),
);
} else if (def.typeName === 'ZodEffects') {
if (isFileSchema(type as unknown as ZodEffects<any, any, any>)) {
schema = any()
Expand Down
50 changes: 50 additions & 0 deletions tests/conform-zod.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,56 @@ describe('conform-zod', () => {
});
});

test('z.object', () => {
const schema = z.object({
a: z.object({
text: z.string({
required_error: 'required',
}),
flag: z.boolean({
required_error: 'required',
}),
}),
b: z
.object({
text: z.string({
required_error: 'required',
}),
flag: z.boolean({
required_error: 'required',
}),
})
.optional(),
});

expect(parseWithZod(createFormData([]), { schema })).toEqual({
status: 'error',
payload: {},
error: {
'a.text': ['required'],
'a.flag': ['required'],
},
reply: expect.any(Function),
});
expect(
parseWithZod(createFormData([['b.text', '']]), { schema }),
).toEqual({
status: 'error',
payload: {
b: {
text: '',
},
},
error: {
'a.text': ['required'],
'a.flag': ['required'],
'b.text': ['required'],
'b.flag': ['required'],
},
reply: expect.any(Function),
});
});

test('z.array', () => {
const createSchema = (
element: z.ZodTypeAny = z.string({
Expand Down

0 comments on commit b691537

Please sign in to comment.