-
-
Notifications
You must be signed in to change notification settings - Fork 167
/
Copy pathzod.ts
89 lines (76 loc) · 2.29 KB
/
zod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';
import { z, ZodError } from 'zod';
import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';
import type { Resolver } from './types';
const isZodError = (error: any): error is ZodError => error.errors != null;
const parseErrorSchema = (
zodErrors: z.ZodIssue[],
validateAllFieldCriteria: boolean,
) => {
const errors: Record<string, FieldError> = {};
for (; zodErrors.length; ) {
const error = zodErrors[0];
const { code, message, path } = error;
const _path = path.join('.');
if (!errors[_path]) {
if ('unionErrors' in error) {
const unionError = error.unionErrors[0].errors[0];
errors[_path] = {
message: unionError.message,
type: unionError.code,
};
} else {
errors[_path] = { message, type: code };
}
}
if ('unionErrors' in error) {
error.unionErrors.forEach((unionError) =>
unionError.errors.forEach((e) => zodErrors.push(e)),
);
}
if (validateAllFieldCriteria) {
const types = errors[_path].types;
const messages = types && types[error.code];
errors[_path] = appendErrors(
_path,
validateAllFieldCriteria,
errors,
code,
messages
? ([] as string[]).concat(messages as string[], error.message)
: error.message,
) as FieldError;
}
zodErrors.shift();
}
return errors;
};
export const zodResolver: Resolver =
(schema, schemaOptions, resolverOptions = {}) =>
async (values, _, options) => {
try {
const data = await schema[
resolverOptions.mode === 'sync' ? 'parse' : 'parseAsync'
](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;
}
};