Skip to content

Commit

Permalink
feat: add zodResolverSync
Browse files Browse the repository at this point in the history
  • Loading branch information
kotarella1110 committed Nov 9, 2023
1 parent 3805d3e commit 2d6d392
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 15 deletions.
12 changes: 4 additions & 8 deletions zod/src/__tests__/zod.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { zodResolver } from '..';
import { zodResolver, zodResolverSync } from '..';
import { schema, validData, invalidData, fields } from './__fixtures__/data';

const shouldUseNativeValidation = false;
Expand All @@ -22,9 +22,7 @@ describe('zodResolver', () => {
const parseSpy = vi.spyOn(schema, 'parse');
const parseAsyncSpy = vi.spyOn(schema, 'parseAsync');

const result = await zodResolver(schema, undefined, {
mode: 'sync',
})(validData, undefined, { fields, shouldUseNativeValidation });
const result = await zodResolverSync(schema, undefined)(validData, undefined, { fields, shouldUseNativeValidation });

expect(parseSpy).toHaveBeenCalledTimes(1);
expect(parseAsyncSpy).not.toHaveBeenCalled();
Expand All @@ -45,9 +43,7 @@ describe('zodResolver', () => {
const parseSpy = vi.spyOn(schema, 'parse');
const parseAsyncSpy = vi.spyOn(schema, 'parseAsync');

const result = await zodResolver(schema, undefined, {
mode: 'sync',
})(invalidData, undefined, { fields, shouldUseNativeValidation });
const result = await zodResolverSync(schema, undefined)(invalidData, undefined, { fields, shouldUseNativeValidation });

expect(parseSpy).toHaveBeenCalledTimes(1);
expect(parseAsyncSpy).not.toHaveBeenCalled();
Expand All @@ -65,7 +61,7 @@ describe('zodResolver', () => {
});

it('should return all the errors from zodResolver when validation fails with `validateAllFieldCriteria` set to true and `mode: sync`', async () => {
const result = await zodResolver(schema, undefined, { mode: 'sync' })(
const result = await zodResolverSync(schema, undefined)(
invalidData,
undefined,
{
Expand Down
18 changes: 15 additions & 3 deletions zod/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,21 @@ export type Resolver = <T extends z.Schema<any, any>>(
schemaOptions?: Partial<z.ParseParams>,
factoryOptions?: {
/**
* @default async
* Return the raw input values rather than the parsed values.
* @default false
*/
mode?: 'async' | 'sync';
raw?: boolean;
},
) => <TFieldValues extends FieldValues, TContext>(
values: TFieldValues,
context: TContext | undefined,
options: ResolverOptions<TFieldValues>,
) => Promise<ResolverResult<TFieldValues>>;

export type ResolverSync = <T extends z.Schema<any, any>>(
schema: T,
schemaOptions?: Partial<z.ParseParams>,
factoryOptions?: {
/**
* Return the raw input values rather than the parsed values.
* @default false
Expand All @@ -19,4 +31,4 @@ export type Resolver = <T extends z.Schema<any, any>>(
values: TFieldValues,
context: TContext | undefined,
options: ResolverOptions<TFieldValues>,
) => Promise<ResolverResult<TFieldValues>>;
) => ResolverResult<TFieldValues>;
37 changes: 33 additions & 4 deletions zod/src/zod.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';
import { z, ZodError } from 'zod';
import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';
import type { Resolver } from './types';
import type { Resolver, ResolverSync } from './types';

const isZodError = (error: any): error is ZodError => error.errors != null;

Expand Down Expand Up @@ -59,9 +59,7 @@ export const zodResolver: Resolver =
(schema, schemaOptions, resolverOptions = {}) =>
async (values, _, options) => {
try {
const data = await schema[
resolverOptions.mode === 'sync' ? 'parse' : 'parseAsync'
](values, schemaOptions);
const data = await schema.parseAsync(values, schemaOptions);

options.shouldUseNativeValidation && validateFieldsNatively({}, options);

Expand All @@ -87,3 +85,34 @@ export const zodResolver: Resolver =
throw error;
}
};

export const zodResolverSync: ResolverSync =
(schema, schemaOptions, resolverOptions = {}) =>
(values, _, options) => {
try {
const data = schema.parse(values, schemaOptions);

options.shouldUseNativeValidation && validateFieldsNatively({}, options);

return {
errors: {} as FieldErrors,
values: resolverOptions.raw ? values : data,
};
} catch (error: any) {
if (isZodError(error)) {
return {
values: {},
errors: toNestErrors(
parseErrorSchema(
error.errors,
!options.shouldUseNativeValidation &&
options.criteriaMode === 'all',
),
options,
),
};
}

throw error;
}
};

0 comments on commit 2d6d392

Please sign in to comment.