Skip to content

Commit

Permalink
fix(zod): add ability to skip zod's parsing (#401)
Browse files Browse the repository at this point in the history
* skip zod parsing

* align coding style
  • Loading branch information
KATT authored May 15, 2022
1 parent 350d255 commit 259b4dc
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 7 deletions.
9 changes: 8 additions & 1 deletion zod/src/__tests__/__fixtures__/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ export const schema = z
}),
)
.optional(),
dateStr: z
.string()
.transform((value) => new Date(value))
.refine((value) => !isNaN(value.getTime()), {
message: 'Invalid date',
}),
})
.refine((obj) => obj.password === obj.repeatPassword, {
message: 'Passwords do not match',
path: ['confirm'],
});

export const validData: z.infer<typeof schema> = {
export const validData: z.input<typeof schema> = {
username: 'Doe',
password: 'Password123_',
repeatPassword: 'Password123_',
Expand All @@ -51,6 +57,7 @@ export const validData: z.infer<typeof schema> = {
name: 'name',
},
],
dateStr: '2020-01-01',
};

export const invalidData = {
Expand Down
53 changes: 53 additions & 0 deletions zod/src/__tests__/__snapshots__/zod.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ Object {
"ref": undefined,
"type": "invalid_type",
},
"dateStr": Object {
"message": "Required",
"ref": undefined,
"type": "invalid_type",
},
"email": Object {
"message": "Invalid email",
"ref": Object {
Expand Down Expand Up @@ -86,6 +91,11 @@ Object {
"ref": undefined,
"type": "invalid_type",
},
"dateStr": Object {
"message": "Required",
"ref": undefined,
"type": "invalid_type",
},
"email": Object {
"message": "Invalid email",
"ref": Object {
Expand Down Expand Up @@ -169,6 +179,14 @@ Object {
"invalid_type": "Expected number, received string",
},
},
"dateStr": Object {
"message": "Required",
"ref": undefined,
"type": "invalid_type",
"types": Object {
"invalid_type": "Required",
},
},
"email": Object {
"message": "Invalid email",
"ref": Object {
Expand Down Expand Up @@ -284,6 +302,14 @@ Object {
"invalid_type": "Expected number, received string",
},
},
"dateStr": Object {
"message": "Required",
"ref": undefined,
"type": "invalid_type",
"types": Object {
"invalid_type": "Required",
},
},
"email": Object {
"message": "Invalid email",
"ref": Object {
Expand Down Expand Up @@ -375,3 +401,30 @@ Object {
"values": Object {},
}
`;

exports[`zodResolver should return parsed values from zodResolver with \`mode: sync\` when validation pass 1`] = `
Object {
"errors": Object {},
"values": Object {
"accessToken": "accessToken",
"birthYear": 2000,
"dateStr": 2020-01-01T00:00:00.000Z,
"email": "[email protected]",
"enabled": true,
"like": Array [
Object {
"id": 1,
"name": "name",
},
],
"password": "Password123_",
"repeatPassword": "Password123_",
"tags": Array [
"tag1",
"tag2",
],
"url": "https://react-hook-form.com/",
"username": "Doe",
},
}
`;
11 changes: 7 additions & 4 deletions zod/src/__tests__/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { schema, validData, invalidData, fields } from './__fixtures__/data';
const shouldUseNativeValidation = false;

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

const result = await zodResolver(schema)(validData, undefined, {
const result = await zodResolver(schema, undefined, {
rawValues: true,
})(validData, undefined, {
fields,
shouldUseNativeValidation,
});
Expand All @@ -16,7 +18,7 @@ describe('zodResolver', () => {
expect(result).toEqual({ errors: {}, values: validData });
});

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

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

expect(parseSpy).toHaveBeenCalledTimes(1);
expect(parseAsyncSpy).not.toHaveBeenCalled();
expect(result).toEqual({ errors: {}, values: validData });
expect(result.errors).toEqual({});
expect(result).toMatchSnapshot();
});

it('should return a single error from zodResolver when validation fails', async () => {
Expand Down
12 changes: 11 additions & 1 deletion zod/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@ import { z } from 'zod';
export type Resolver = <T extends z.Schema<any, any>>(
schema: T,
schemaOptions?: Partial<z.ParseParams>,
factoryOptions?: { mode?: 'async' | 'sync' },
factoryOptions?: {
/**
* @default async
*/
mode?: 'async' | 'sync';
/**
* Return the raw input values rather than the parsed values.
* @default false
*/
rawValues?: boolean;
},
) => <TFieldValues extends FieldValues, TContext>(
values: UnpackNestedValue<TFieldValues>,
context: TContext | undefined,
Expand Down
2 changes: 1 addition & 1 deletion zod/src/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const zodResolver: Resolver =

return {
errors: {} as FieldErrors,
values: data,
values: resolverOptions.rawValues ? values : data,
};
} catch (error: any) {
return {
Expand Down

0 comments on commit 259b4dc

Please sign in to comment.