Skip to content

Commit 259b4dc

Browse files
authored
fix(zod): add ability to skip zod's parsing (#401)
* skip zod parsing * align coding style
1 parent 350d255 commit 259b4dc

File tree

5 files changed

+80
-7
lines changed

5 files changed

+80
-7
lines changed

zod/src/__tests__/__fixtures__/data.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,19 @@ export const schema = z
2929
}),
3030
)
3131
.optional(),
32+
dateStr: z
33+
.string()
34+
.transform((value) => new Date(value))
35+
.refine((value) => !isNaN(value.getTime()), {
36+
message: 'Invalid date',
37+
}),
3238
})
3339
.refine((obj) => obj.password === obj.repeatPassword, {
3440
message: 'Passwords do not match',
3541
path: ['confirm'],
3642
});
3743

38-
export const validData: z.infer<typeof schema> = {
44+
export const validData: z.input<typeof schema> = {
3945
username: 'Doe',
4046
password: 'Password123_',
4147
repeatPassword: 'Password123_',
@@ -51,6 +57,7 @@ export const validData: z.infer<typeof schema> = {
5157
name: 'name',
5258
},
5359
],
60+
dateStr: '2020-01-01',
5461
};
5562

5663
export const invalidData = {

zod/src/__tests__/__snapshots__/zod.ts.snap

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ Object {
1313
"ref": undefined,
1414
"type": "invalid_type",
1515
},
16+
"dateStr": Object {
17+
"message": "Required",
18+
"ref": undefined,
19+
"type": "invalid_type",
20+
},
1621
"email": Object {
1722
"message": "Invalid email",
1823
"ref": Object {
@@ -86,6 +91,11 @@ Object {
8691
"ref": undefined,
8792
"type": "invalid_type",
8893
},
94+
"dateStr": Object {
95+
"message": "Required",
96+
"ref": undefined,
97+
"type": "invalid_type",
98+
},
8999
"email": Object {
90100
"message": "Invalid email",
91101
"ref": Object {
@@ -169,6 +179,14 @@ Object {
169179
"invalid_type": "Expected number, received string",
170180
},
171181
},
182+
"dateStr": Object {
183+
"message": "Required",
184+
"ref": undefined,
185+
"type": "invalid_type",
186+
"types": Object {
187+
"invalid_type": "Required",
188+
},
189+
},
172190
"email": Object {
173191
"message": "Invalid email",
174192
"ref": Object {
@@ -284,6 +302,14 @@ Object {
284302
"invalid_type": "Expected number, received string",
285303
},
286304
},
305+
"dateStr": Object {
306+
"message": "Required",
307+
"ref": undefined,
308+
"type": "invalid_type",
309+
"types": Object {
310+
"invalid_type": "Required",
311+
},
312+
},
287313
"email": Object {
288314
"message": "Invalid email",
289315
"ref": Object {
@@ -375,3 +401,30 @@ Object {
375401
"values": Object {},
376402
}
377403
`;
404+
405+
exports[`zodResolver should return parsed values from zodResolver with \`mode: sync\` when validation pass 1`] = `
406+
Object {
407+
"errors": Object {},
408+
"values": Object {
409+
"accessToken": "accessToken",
410+
"birthYear": 2000,
411+
"dateStr": 2020-01-01T00:00:00.000Z,
412+
"email": "john@doe.com",
413+
"enabled": true,
414+
"like": Array [
415+
Object {
416+
"id": 1,
417+
"name": "name",
418+
},
419+
],
420+
"password": "Password123_",
421+
"repeatPassword": "Password123_",
422+
"tags": Array [
423+
"tag1",
424+
"tag2",
425+
],
426+
"url": "https://react-hook-form.com/",
427+
"username": "Doe",
428+
},
429+
}
430+
`;

zod/src/__tests__/zod.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import { schema, validData, invalidData, fields } from './__fixtures__/data';
44
const shouldUseNativeValidation = false;
55

66
describe('zodResolver', () => {
7-
it('should return values from zodResolver when validation pass', async () => {
7+
it('should return values from zodResolver when validation pass & rawValues=true', async () => {
88
const parseAsyncSpy = jest.spyOn(schema, 'parseAsync');
99

10-
const result = await zodResolver(schema)(validData, undefined, {
10+
const result = await zodResolver(schema, undefined, {
11+
rawValues: true,
12+
})(validData, undefined, {
1113
fields,
1214
shouldUseNativeValidation,
1315
});
@@ -16,7 +18,7 @@ describe('zodResolver', () => {
1618
expect(result).toEqual({ errors: {}, values: validData });
1719
});
1820

19-
it('should return values from zodResolver with `mode: sync` when validation pass', async () => {
21+
it('should return parsed values from zodResolver with `mode: sync` when validation pass', async () => {
2022
const parseSpy = jest.spyOn(schema, 'parse');
2123
const parseAsyncSpy = jest.spyOn(schema, 'parseAsync');
2224

@@ -26,7 +28,8 @@ describe('zodResolver', () => {
2628

2729
expect(parseSpy).toHaveBeenCalledTimes(1);
2830
expect(parseAsyncSpy).not.toHaveBeenCalled();
29-
expect(result).toEqual({ errors: {}, values: validData });
31+
expect(result.errors).toEqual({});
32+
expect(result).toMatchSnapshot();
3033
});
3134

3235
it('should return a single error from zodResolver when validation fails', async () => {

zod/src/types.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,17 @@ import { z } from 'zod';
99
export type Resolver = <T extends z.Schema<any, any>>(
1010
schema: T,
1111
schemaOptions?: Partial<z.ParseParams>,
12-
factoryOptions?: { mode?: 'async' | 'sync' },
12+
factoryOptions?: {
13+
/**
14+
* @default async
15+
*/
16+
mode?: 'async' | 'sync';
17+
/**
18+
* Return the raw input values rather than the parsed values.
19+
* @default false
20+
*/
21+
rawValues?: boolean;
22+
},
1323
) => <TFieldValues extends FieldValues, TContext>(
1424
values: UnpackNestedValue<TFieldValues>,
1525
context: TContext | undefined,

zod/src/zod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const zodResolver: Resolver =
6969

7070
return {
7171
errors: {} as FieldErrors,
72-
values: data,
72+
values: resolverOptions.rawValues ? values : data,
7373
};
7474
} catch (error: any) {
7575
return {

0 commit comments

Comments
 (0)