@hookform/resolvers 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +420 -0
  3. package/class-validator/dist/class-validator.d.ts +2 -0
  4. package/class-validator/dist/class-validator.js +2 -0
  5. package/class-validator/dist/class-validator.js.map +1 -0
  6. package/class-validator/dist/class-validator.mjs +2 -0
  7. package/class-validator/dist/class-validator.modern.js +2 -0
  8. package/class-validator/dist/class-validator.modern.js.map +1 -0
  9. package/class-validator/dist/class-validator.module.js +2 -0
  10. package/class-validator/dist/class-validator.module.js.map +1 -0
  11. package/class-validator/dist/class-validator.umd.js +2 -0
  12. package/class-validator/dist/class-validator.umd.js.map +1 -0
  13. package/class-validator/dist/index.d.ts +2 -0
  14. package/class-validator/dist/types.d.ts +8 -0
  15. package/class-validator/package.json +19 -0
  16. package/class-validator/src/__tests__/Form-native-validation.tsx +83 -0
  17. package/class-validator/src/__tests__/Form.tsx +55 -0
  18. package/class-validator/src/__tests__/__fixtures__/data.ts +88 -0
  19. package/class-validator/src/__tests__/__snapshots__/class-validator.ts.snap +207 -0
  20. package/class-validator/src/__tests__/class-validator.ts +87 -0
  21. package/class-validator/src/class-validator.ts +62 -0
  22. package/class-validator/src/index.ts +2 -0
  23. package/class-validator/src/types.ts +22 -0
  24. package/computed-types/dist/computed-types.d.ts +2 -0
  25. package/computed-types/dist/computed-types.js +2 -0
  26. package/computed-types/dist/computed-types.js.map +1 -0
  27. package/computed-types/dist/computed-types.mjs +2 -0
  28. package/computed-types/dist/computed-types.modern.js +2 -0
  29. package/computed-types/dist/computed-types.modern.js.map +1 -0
  30. package/computed-types/dist/computed-types.module.js +2 -0
  31. package/computed-types/dist/computed-types.module.js.map +1 -0
  32. package/computed-types/dist/computed-types.umd.js +2 -0
  33. package/computed-types/dist/computed-types.umd.js.map +1 -0
  34. package/computed-types/dist/index.d.ts +2 -0
  35. package/computed-types/dist/types.d.ts +2 -0
  36. package/computed-types/package.json +17 -0
  37. package/computed-types/src/__tests__/Form-native-validation.tsx +85 -0
  38. package/computed-types/src/__tests__/Form.tsx +54 -0
  39. package/computed-types/src/__tests__/__fixtures__/data.ts +72 -0
  40. package/computed-types/src/__tests__/__snapshots__/computed-types.ts.snap +55 -0
  41. package/computed-types/src/__tests__/computed-types.ts +24 -0
  42. package/computed-types/src/computed-types.ts +43 -0
  43. package/computed-types/src/index.ts +2 -0
  44. package/computed-types/src/types.ts +14 -0
  45. package/dist/index.d.ts +2 -0
  46. package/dist/resolvers.js +2 -0
  47. package/dist/resolvers.js.map +1 -0
  48. package/dist/resolvers.mjs +2 -0
  49. package/dist/resolvers.mjs.map +1 -0
  50. package/dist/resolvers.module.js +2 -0
  51. package/dist/resolvers.module.js.map +1 -0
  52. package/dist/resolvers.umd.js +2 -0
  53. package/dist/resolvers.umd.js.map +1 -0
  54. package/dist/toNestError.d.ts +2 -0
  55. package/dist/validateFieldsNatively.d.ts +2 -0
  56. package/io-ts/dist/arrayToPath.d.ts +3 -0
  57. package/io-ts/dist/errorsToRecord.d.ts +5 -0
  58. package/io-ts/dist/index.d.ts +2 -0
  59. package/io-ts/dist/io-ts.d.ts +2 -0
  60. package/io-ts/dist/io-ts.js +2 -0
  61. package/io-ts/dist/io-ts.js.map +1 -0
  62. package/io-ts/dist/io-ts.mjs +2 -0
  63. package/io-ts/dist/io-ts.modern.js +2 -0
  64. package/io-ts/dist/io-ts.modern.js.map +1 -0
  65. package/io-ts/dist/io-ts.module.js +2 -0
  66. package/io-ts/dist/io-ts.module.js.map +1 -0
  67. package/io-ts/dist/io-ts.umd.js +2 -0
  68. package/io-ts/dist/io-ts.umd.js.map +1 -0
  69. package/io-ts/dist/types.d.ts +7 -0
  70. package/io-ts/package.json +19 -0
  71. package/io-ts/src/__tests__/Form-native-validation.tsx +89 -0
  72. package/io-ts/src/__tests__/Form.tsx +65 -0
  73. package/io-ts/src/__tests__/__fixtures__/data.ts +129 -0
  74. package/io-ts/src/__tests__/__snapshots__/io-ts.ts.snap +89 -0
  75. package/io-ts/src/__tests__/io-ts.ts +37 -0
  76. package/io-ts/src/arrayToPath.ts +18 -0
  77. package/io-ts/src/errorsToRecord.ts +131 -0
  78. package/io-ts/src/index.ts +2 -0
  79. package/io-ts/src/io-ts.ts +33 -0
  80. package/io-ts/src/types.ts +23 -0
  81. package/joi/dist/index.d.ts +2 -0
  82. package/joi/dist/joi.d.ts +2 -0
  83. package/joi/dist/joi.js +2 -0
  84. package/joi/dist/joi.js.map +1 -0
  85. package/joi/dist/joi.mjs +2 -0
  86. package/joi/dist/joi.modern.js +2 -0
  87. package/joi/dist/joi.modern.js.map +1 -0
  88. package/joi/dist/joi.module.js +2 -0
  89. package/joi/dist/joi.module.js.map +1 -0
  90. package/joi/dist/joi.umd.js +2 -0
  91. package/joi/dist/joi.umd.js.map +1 -0
  92. package/joi/dist/types.d.ts +5 -0
  93. package/joi/package.json +17 -0
  94. package/joi/src/__tests__/Form-native-validation.tsx +89 -0
  95. package/joi/src/__tests__/Form.tsx +61 -0
  96. package/joi/src/__tests__/__fixtures__/data.ts +85 -0
  97. package/joi/src/__tests__/__snapshots__/joi.ts.snap +293 -0
  98. package/joi/src/__tests__/joi.ts +98 -0
  99. package/joi/src/index.ts +2 -0
  100. package/joi/src/joi.ts +81 -0
  101. package/joi/src/types.ts +16 -0
  102. package/nope/dist/index.d.ts +2 -0
  103. package/nope/dist/nope.d.ts +2 -0
  104. package/nope/dist/nope.js +2 -0
  105. package/nope/dist/nope.js.map +1 -0
  106. package/nope/dist/nope.mjs +2 -0
  107. package/nope/dist/nope.modern.js +2 -0
  108. package/nope/dist/nope.modern.js.map +1 -0
  109. package/nope/dist/nope.module.js +2 -0
  110. package/nope/dist/nope.module.js.map +1 -0
  111. package/nope/dist/nope.umd.js +2 -0
  112. package/nope/dist/nope.umd.js.map +1 -0
  113. package/nope/dist/types.d.ts +6 -0
  114. package/nope/package.json +18 -0
  115. package/nope/src/__tests__/Form-native-validation.tsx +89 -0
  116. package/nope/src/__tests__/Form.tsx +57 -0
  117. package/nope/src/__tests__/__fixtures__/data.ts +70 -0
  118. package/nope/src/__tests__/__snapshots__/nope.ts.snap +43 -0
  119. package/nope/src/__tests__/nope.ts +28 -0
  120. package/nope/src/index.ts +2 -0
  121. package/nope/src/nope.ts +46 -0
  122. package/nope/src/types.ts +22 -0
  123. package/package.json +216 -0
  124. package/superstruct/dist/index.d.ts +2 -0
  125. package/superstruct/dist/superstruct.d.ts +2 -0
  126. package/superstruct/dist/superstruct.js +2 -0
  127. package/superstruct/dist/superstruct.js.map +1 -0
  128. package/superstruct/dist/superstruct.mjs +2 -0
  129. package/superstruct/dist/superstruct.modern.js +2 -0
  130. package/superstruct/dist/superstruct.modern.js.map +1 -0
  131. package/superstruct/dist/superstruct.module.js +2 -0
  132. package/superstruct/dist/superstruct.module.js.map +1 -0
  133. package/superstruct/dist/superstruct.umd.js +2 -0
  134. package/superstruct/dist/superstruct.umd.js.map +1 -0
  135. package/superstruct/dist/types.d.ts +5 -0
  136. package/superstruct/package.json +18 -0
  137. package/superstruct/src/__tests__/Form-native-validation.tsx +86 -0
  138. package/superstruct/src/__tests__/Form.tsx +62 -0
  139. package/superstruct/src/__tests__/__fixtures__/data.ts +75 -0
  140. package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +64 -0
  141. package/superstruct/src/__tests__/superstruct.ts +24 -0
  142. package/superstruct/src/index.ts +2 -0
  143. package/superstruct/src/superstruct.ts +37 -0
  144. package/superstruct/src/types.ts +17 -0
  145. package/typanion/dist/index.d.ts +2 -0
  146. package/typanion/dist/typanion.d.ts +2 -0
  147. package/typanion/dist/typanion.js +2 -0
  148. package/typanion/dist/typanion.js.map +1 -0
  149. package/typanion/dist/typanion.mjs +2 -0
  150. package/typanion/dist/typanion.modern.js +2 -0
  151. package/typanion/dist/typanion.modern.js.map +1 -0
  152. package/typanion/dist/typanion.module.js +2 -0
  153. package/typanion/dist/typanion.module.js.map +1 -0
  154. package/typanion/dist/typanion.umd.js +2 -0
  155. package/typanion/dist/typanion.umd.js.map +1 -0
  156. package/typanion/dist/types.d.ts +6 -0
  157. package/typanion/package.json +18 -0
  158. package/typanion/src/__tests__/Form-native-validation.tsx +89 -0
  159. package/typanion/src/__tests__/Form.tsx +61 -0
  160. package/typanion/src/__tests__/__fixtures__/data.ts +77 -0
  161. package/typanion/src/__tests__/__snapshots__/typanion.ts.snap +67 -0
  162. package/typanion/src/__tests__/typanion.ts +31 -0
  163. package/typanion/src/index.ts +2 -0
  164. package/typanion/src/typanion.ts +44 -0
  165. package/typanion/src/types.ts +28 -0
  166. package/vest/dist/index.d.ts +1 -0
  167. package/vest/dist/vest.d.ts +2 -0
  168. package/vest/dist/vest.js +2 -0
  169. package/vest/dist/vest.js.map +1 -0
  170. package/vest/dist/vest.mjs +2 -0
  171. package/vest/dist/vest.modern.js +2 -0
  172. package/vest/dist/vest.modern.js.map +1 -0
  173. package/vest/dist/vest.module.js +2 -0
  174. package/vest/dist/vest.module.js.map +1 -0
  175. package/vest/dist/vest.umd.js +2 -0
  176. package/vest/dist/vest.umd.js.map +1 -0
  177. package/vest/package.json +18 -0
  178. package/vest/src/__tests__/Form-native-validation.tsx +93 -0
  179. package/vest/src/__tests__/Form.tsx +64 -0
  180. package/vest/src/__tests__/__fixtures__/data.ts +67 -0
  181. package/vest/src/__tests__/__snapshots__/vest.ts.snap +141 -0
  182. package/vest/src/__tests__/vest.ts +71 -0
  183. package/vest/src/index.ts +1 -0
  184. package/vest/src/types.ts +20 -0
  185. package/vest/src/vest.ts +51 -0
  186. package/yup/dist/index.d.ts +2 -0
  187. package/yup/dist/types.d.ts +8 -0
  188. package/yup/dist/yup.d.ts +2 -0
  189. package/yup/dist/yup.js +2 -0
  190. package/yup/dist/yup.js.map +1 -0
  191. package/yup/dist/yup.mjs +2 -0
  192. package/yup/dist/yup.modern.js +2 -0
  193. package/yup/dist/yup.modern.js.map +1 -0
  194. package/yup/dist/yup.module.js +2 -0
  195. package/yup/dist/yup.module.js.map +1 -0
  196. package/yup/dist/yup.umd.js +2 -0
  197. package/yup/dist/yup.umd.js.map +1 -0
  198. package/yup/package.json +17 -0
  199. package/yup/src/__tests__/Form-native-validation.tsx +85 -0
  200. package/yup/src/__tests__/Form.tsx +54 -0
  201. package/yup/src/__tests__/__fixtures__/data.ts +72 -0
  202. package/yup/src/__tests__/__snapshots__/yup.ts.snap +231 -0
  203. package/yup/src/__tests__/yup.ts +174 -0
  204. package/yup/src/index.ts +2 -0
  205. package/yup/src/types.ts +21 -0
  206. package/yup/src/yup.ts +75 -0
  207. package/zod/dist/index.d.ts +2 -0
  208. package/zod/dist/types.d.ts +5 -0
  209. package/zod/dist/zod.d.ts +2 -0
  210. package/zod/dist/zod.js +2 -0
  211. package/zod/dist/zod.js.map +1 -0
  212. package/zod/dist/zod.mjs +2 -0
  213. package/zod/dist/zod.modern.js +2 -0
  214. package/zod/dist/zod.modern.js.map +1 -0
  215. package/zod/dist/zod.module.js +2 -0
  216. package/zod/dist/zod.module.js.map +1 -0
  217. package/zod/dist/zod.umd.js +2 -0
  218. package/zod/dist/zod.umd.js.map +1 -0
  219. package/zod/package.json +17 -0
  220. package/zod/src/__tests__/Form-native-validation.tsx +85 -0
  221. package/zod/src/__tests__/Form.tsx +54 -0
  222. package/zod/src/__tests__/__fixtures__/data.ts +81 -0
  223. package/zod/src/__tests__/__snapshots__/zod.ts.snap +377 -0
  224. package/zod/src/__tests__/zod.ts +77 -0
  225. package/zod/src/index.ts +2 -0
  226. package/zod/src/types.ts +16 -0
  227. package/zod/src/zod.ts +85 -0
@@ -0,0 +1,89 @@
1
+ import React from 'react';
2
+ import { render, screen, act } from '@testing-library/react';
3
+ import user from '@testing-library/user-event';
4
+ import { SubmitHandler, useForm } from 'react-hook-form';
5
+ import * as t from 'io-ts';
6
+ import * as tt from 'io-ts-types';
7
+ import { ioTsResolver } from '..';
8
+
9
+ const USERNAME_REQUIRED_MESSAGE = 'username field is required';
10
+ const PASSWORD_REQUIRED_MESSAGE = 'password field is required';
11
+
12
+ const schema = t.type({
13
+ username: tt.withMessage(tt.NonEmptyString, () => USERNAME_REQUIRED_MESSAGE),
14
+ password: tt.withMessage(tt.NonEmptyString, () => PASSWORD_REQUIRED_MESSAGE),
15
+ });
16
+
17
+ interface FormData {
18
+ username: tt.NonEmptyString;
19
+ password: tt.NonEmptyString;
20
+ }
21
+
22
+ interface Props {
23
+ onSubmit: SubmitHandler<FormData>;
24
+ }
25
+
26
+ function TestComponent({ onSubmit }: Props) {
27
+ const { register, handleSubmit } = useForm({
28
+ resolver: ioTsResolver(schema),
29
+ shouldUseNativeValidation: true,
30
+ });
31
+
32
+ return (
33
+ <form onSubmit={handleSubmit(onSubmit)}>
34
+ <input {...register('username')} placeholder="username" />
35
+
36
+ <input {...register('password')} placeholder="password" />
37
+
38
+ <button type="submit">submit</button>
39
+ </form>
40
+ );
41
+ }
42
+
43
+ test("form's native validation with io-ts", async () => {
44
+ const handleSubmit = jest.fn();
45
+ render(<TestComponent onSubmit={handleSubmit} />);
46
+
47
+ // username
48
+ let usernameField = screen.getByPlaceholderText(
49
+ /username/i,
50
+ ) as HTMLInputElement;
51
+ expect(usernameField.validity.valid).toBe(true);
52
+ expect(usernameField.validationMessage).toBe('');
53
+
54
+ // password
55
+ let passwordField = screen.getByPlaceholderText(
56
+ /password/i,
57
+ ) as HTMLInputElement;
58
+ expect(passwordField.validity.valid).toBe(true);
59
+ expect(passwordField.validationMessage).toBe('');
60
+
61
+ await act(async () => {
62
+ user.click(screen.getByText(/submit/i));
63
+ });
64
+
65
+ // username
66
+ usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
67
+ expect(usernameField.validity.valid).toBe(false);
68
+ expect(usernameField.validationMessage).toBe(USERNAME_REQUIRED_MESSAGE);
69
+
70
+ // password
71
+ passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
72
+ expect(passwordField.validity.valid).toBe(false);
73
+ expect(passwordField.validationMessage).toBe(PASSWORD_REQUIRED_MESSAGE);
74
+
75
+ await act(async () => {
76
+ user.type(screen.getByPlaceholderText(/username/i), 'joe');
77
+ user.type(screen.getByPlaceholderText(/password/i), 'password');
78
+ });
79
+
80
+ // username
81
+ usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
82
+ expect(usernameField.validity.valid).toBe(true);
83
+ expect(usernameField.validationMessage).toBe('');
84
+
85
+ // password
86
+ passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
87
+ expect(passwordField.validity.valid).toBe(true);
88
+ expect(passwordField.validationMessage).toBe('');
89
+ });
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { render, screen, act } from '@testing-library/react';
3
+ import user from '@testing-library/user-event';
4
+ import { NestedValue, SubmitHandler, useForm } from 'react-hook-form';
5
+ import * as t from 'io-ts';
6
+ import * as tt from 'io-ts-types';
7
+ import { ioTsResolver } from '..';
8
+
9
+ const schema = t.type({
10
+ username: tt.withMessage(
11
+ tt.NonEmptyString,
12
+ () => 'username is a required field',
13
+ ),
14
+ password: tt.withMessage(
15
+ tt.NonEmptyString,
16
+ () => 'password is a required field',
17
+ ),
18
+ });
19
+
20
+ interface FormData {
21
+ username: NestedValue<tt.NonEmptyString>;
22
+ password: NestedValue<tt.NonEmptyString>;
23
+ }
24
+
25
+ interface Props {
26
+ onSubmit: SubmitHandler<FormData>;
27
+ }
28
+
29
+ function TestComponent({ onSubmit }: Props) {
30
+ const {
31
+ register,
32
+ formState: { errors },
33
+ handleSubmit,
34
+ } = useForm<FormData>({
35
+ resolver: ioTsResolver<FormData>(schema),
36
+ criteriaMode: 'all',
37
+ });
38
+
39
+ return (
40
+ <form onSubmit={handleSubmit(onSubmit)}>
41
+ <input {...register('username')} />
42
+ {errors.username && <span role="alert">{errors.username.message}</span>}
43
+
44
+ <input {...register('password')} />
45
+ {errors.password && <span role="alert">{errors.password.message}</span>}
46
+
47
+ <button type="submit">submit</button>
48
+ </form>
49
+ );
50
+ }
51
+
52
+ test("form's validation with io-ts and TypeScript's integration", async () => {
53
+ const handleSubmit = jest.fn();
54
+ render(<TestComponent onSubmit={handleSubmit} />);
55
+
56
+ expect(screen.queryAllByRole(/alert/i)).toHaveLength(0);
57
+
58
+ await act(async () => {
59
+ user.click(screen.getByText(/submit/i));
60
+ });
61
+
62
+ expect(screen.getByText(/username is a required field/i)).toBeInTheDocument();
63
+ expect(screen.getByText(/password is a required field/i)).toBeInTheDocument();
64
+ expect(handleSubmit).not.toHaveBeenCalled();
65
+ });
@@ -0,0 +1,129 @@
1
+ import * as t from 'io-ts';
2
+ import * as tt from 'io-ts-types';
3
+
4
+ import { Field, InternalFieldName } from 'react-hook-form';
5
+
6
+ export const schema = t.intersection([
7
+ t.type({
8
+ username: tt.NonEmptyString,
9
+ password: tt.NonEmptyString,
10
+ accessToken: tt.UUID,
11
+ birthYear: t.number,
12
+ email: t.string,
13
+ tags: t.array(
14
+ t.type({
15
+ name: t.string,
16
+ }),
17
+ ),
18
+ luckyNumbers: t.array(t.number),
19
+ enabled: t.boolean,
20
+ animal: t.union([
21
+ t.string,
22
+ t.number,
23
+ t.literal('bird'),
24
+ t.literal('snake'),
25
+ ]),
26
+ vehicles: t.array(
27
+ t.union([
28
+ t.type({
29
+ type: t.literal('car'),
30
+ brand: t.string,
31
+ horsepower: t.number,
32
+ }),
33
+ t.type({
34
+ type: t.literal('bike'),
35
+ speed: t.number,
36
+ }),
37
+ ]),
38
+ ),
39
+ }),
40
+ t.partial({
41
+ like: t.array(
42
+ t.type({
43
+ id: tt.withMessage(
44
+ t.number,
45
+ (i) => `this id is very important but you passed: ${typeof i}(${i})`,
46
+ ),
47
+ name: t.string,
48
+ }),
49
+ ),
50
+ }),
51
+ ]);
52
+
53
+ interface Data {
54
+ username: string;
55
+ password: string;
56
+ accessToken: string;
57
+ birthYear?: number;
58
+ luckyNumbers: number[];
59
+ email?: string;
60
+ animal: string | number;
61
+ tags: { name: string }[];
62
+ enabled: boolean;
63
+ like: { id: number; name: string }[];
64
+ vehicles: Array<
65
+ | { type: 'car'; brand: string; horsepower: number }
66
+ | { type: 'bike'; speed: number }
67
+ >;
68
+ }
69
+
70
+ export const validData: Data = {
71
+ username: 'Doe',
72
+ password: 'Password123',
73
+ accessToken: 'c2883927-5178-4ad1-bbee-07ba33a5de19',
74
+ birthYear: 2000,
75
+ email: 'john@doe.com',
76
+ tags: [{ name: 'test' }],
77
+ enabled: true,
78
+ luckyNumbers: [17, 5],
79
+ animal: 'cat',
80
+ like: [
81
+ {
82
+ id: 1,
83
+ name: 'name',
84
+ },
85
+ ],
86
+ vehicles: [{ type: 'car', brand: 'BMW', horsepower: 150 }],
87
+ };
88
+
89
+ export const invalidData = {
90
+ username: 'test',
91
+ password: 'Password123',
92
+ repeatPassword: 'Password123',
93
+ birthYear: 2000,
94
+ accessToken: '1015d809-e99d-41ec-b161-981a3c243df8',
95
+ email: 'john@doe.com',
96
+ tags: [{ name: 'test' }],
97
+ enabled: true,
98
+ animal: ['dog'],
99
+ luckyNumbers: [1, 2, '3'],
100
+ like: [
101
+ {
102
+ id: '1',
103
+ name: 'name',
104
+ },
105
+ ],
106
+ vehicles: [
107
+ { type: 'car', brand: 'BMW', horsepower: 150 },
108
+ { type: 'car', brand: 'Mercedes' },
109
+ ],
110
+ };
111
+
112
+ export const fields: Record<InternalFieldName, Field['_f']> = {
113
+ username: {
114
+ ref: { name: 'username' },
115
+ name: 'username',
116
+ },
117
+ password: {
118
+ ref: { name: 'password' },
119
+ name: 'password',
120
+ },
121
+ email: {
122
+ ref: { name: 'email' },
123
+ name: 'email',
124
+ },
125
+ birthday: {
126
+ ref: { name: 'birthday' },
127
+ name: 'birthday',
128
+ },
129
+ };
@@ -0,0 +1,89 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ioTsResolver should return a single error from ioTsResolver when validation fails 1`] = `
4
+ Object {
5
+ "errors": Object {
6
+ "animal": Object {
7
+ "message": "expected string but got [\\"dog\\"]",
8
+ "ref": undefined,
9
+ "type": "string",
10
+ },
11
+ "like": Array [
12
+ Object {
13
+ "id": Object {
14
+ "message": "this id is very important but you passed: string(1)",
15
+ "ref": undefined,
16
+ "type": "number",
17
+ },
18
+ },
19
+ ],
20
+ "luckyNumbers": Array [
21
+ ,
22
+ ,
23
+ Object {
24
+ "message": "expected number but got \\"3\\"",
25
+ "ref": undefined,
26
+ "type": "number",
27
+ },
28
+ ],
29
+ "vehicles": Array [
30
+ ,
31
+ Object {
32
+ "horsepower": Object {
33
+ "message": "expected number but got undefined",
34
+ "ref": undefined,
35
+ "type": "number",
36
+ },
37
+ },
38
+ ],
39
+ },
40
+ "values": Object {},
41
+ }
42
+ `;
43
+
44
+ exports[`ioTsResolver should return all the errors from ioTsResolver when validation fails with \`validateAllFieldCriteria\` set to true 1`] = `
45
+ Object {
46
+ "errors": Object {
47
+ "animal": Object {
48
+ "message": "expected \\"snake\\" but got [\\"dog\\"]",
49
+ "ref": undefined,
50
+ "type": "\\"snake\\"",
51
+ "types": Object {
52
+ "\\"bird\\"": "expected \\"bird\\" but got [\\"dog\\"]",
53
+ "\\"snake\\"": "expected \\"snake\\" but got [\\"dog\\"]",
54
+ "number": "expected number but got [\\"dog\\"]",
55
+ "string": "expected string but got [\\"dog\\"]",
56
+ },
57
+ },
58
+ "like": Array [
59
+ Object {
60
+ "id": Object {
61
+ "message": "this id is very important but you passed: string(1)",
62
+ "ref": undefined,
63
+ "type": "number",
64
+ },
65
+ },
66
+ ],
67
+ "luckyNumbers": Array [
68
+ ,
69
+ ,
70
+ Object {
71
+ "message": "expected number but got \\"3\\"",
72
+ "ref": undefined,
73
+ "type": "number",
74
+ },
75
+ ],
76
+ "vehicles": Array [
77
+ ,
78
+ Object {
79
+ "horsepower": Object {
80
+ "message": "expected number but got undefined",
81
+ "ref": undefined,
82
+ "type": "number",
83
+ },
84
+ },
85
+ ],
86
+ },
87
+ "values": Object {},
88
+ }
89
+ `;
@@ -0,0 +1,37 @@
1
+ import { ioTsResolver } from '..';
2
+ import { schema, validData, fields, invalidData } from './__fixtures__/data';
3
+
4
+ const shouldUseNativeValidation = false;
5
+
6
+ describe('ioTsResolver', () => {
7
+ it('should return values from ioTsResolver when validation pass', async () => {
8
+ const validateSpy = jest.spyOn(schema, 'decode');
9
+
10
+ const result = ioTsResolver(schema)(validData, undefined, {
11
+ fields,
12
+ shouldUseNativeValidation,
13
+ });
14
+
15
+ expect(validateSpy).toHaveBeenCalled();
16
+ expect(result).toEqual({ errors: {}, values: validData });
17
+ });
18
+
19
+ it('should return a single error from ioTsResolver when validation fails', () => {
20
+ const result = ioTsResolver(schema)(invalidData, undefined, {
21
+ fields,
22
+ shouldUseNativeValidation,
23
+ });
24
+
25
+ expect(result).toMatchSnapshot();
26
+ });
27
+
28
+ it('should return all the errors from ioTsResolver when validation fails with `validateAllFieldCriteria` set to true', () => {
29
+ const result = ioTsResolver(schema)(invalidData, undefined, {
30
+ fields,
31
+ criteriaMode: 'all',
32
+ shouldUseNativeValidation,
33
+ });
34
+
35
+ expect(result).toMatchSnapshot();
36
+ });
37
+ });
@@ -0,0 +1,18 @@
1
+ import * as Either from 'fp-ts/Either';
2
+ import { pipe } from 'fp-ts/function';
3
+
4
+ const arrayToPath = (paths: Either.Either<string, number>[]): string =>
5
+ paths.reduce(
6
+ (previous, path, index) =>
7
+ pipe(
8
+ path,
9
+ Either.fold(
10
+ (key) => `${index > 0 ? '.' : ''}${key}`,
11
+ (key) => `[${key}]`,
12
+ ),
13
+ (path) => `${previous}${path}`,
14
+ ),
15
+ '',
16
+ );
17
+
18
+ export default arrayToPath;
@@ -0,0 +1,131 @@
1
+ import * as t from 'io-ts';
2
+ import {
3
+ IntersectionType,
4
+ TaggedUnionType,
5
+ UnionType,
6
+ ValidationError,
7
+ } from 'io-ts';
8
+ import { absurd, flow, identity, not, pipe } from 'fp-ts/function';
9
+ import * as ReadonlyArray from 'fp-ts/ReadonlyArray';
10
+ import * as Option from 'fp-ts/Option';
11
+ import * as Either from 'fp-ts/Either';
12
+ import * as SemiGroup from 'fp-ts/Semigroup';
13
+ import arrayToPath from './arrayToPath';
14
+ import * as ReadonlyRecord from 'fp-ts/ReadonlyRecord';
15
+ import { ErrorObject, FieldErrorWithPath } from './types';
16
+
17
+ const formatErrorPath = (context: t.Context): string =>
18
+ pipe(
19
+ context,
20
+ ReadonlyArray.filterMapWithIndex((index, contextEntry) => {
21
+ const previousIndex = index - 1;
22
+
23
+ const shouldBeFiltered =
24
+ context[previousIndex] === undefined ||
25
+ context[previousIndex].type instanceof TaggedUnionType ||
26
+ context[previousIndex].type instanceof UnionType ||
27
+ context[previousIndex].type instanceof IntersectionType;
28
+
29
+ return shouldBeFiltered ? Option.none : Option.some(contextEntry);
30
+ }),
31
+ ReadonlyArray.map(({ key }) => key),
32
+ ReadonlyArray.map((key) =>
33
+ pipe(
34
+ key,
35
+ (k) => parseInt(k, 10),
36
+ Either.fromPredicate(not<number>(Number.isNaN), () => key),
37
+ ),
38
+ ),
39
+ ReadonlyArray.toArray,
40
+ arrayToPath,
41
+ );
42
+
43
+ const formatError = (e: t.ValidationError): FieldErrorWithPath => {
44
+ const path = formatErrorPath(e.context);
45
+
46
+ const message = pipe(
47
+ e.message,
48
+ Either.fromNullable(e.context),
49
+ Either.mapLeft(
50
+ flow(
51
+ ReadonlyArray.last,
52
+ Option.map(
53
+ (contextEntry) =>
54
+ `expected ${contextEntry.type.name} but got ${JSON.stringify(
55
+ contextEntry.actual,
56
+ )}`,
57
+ ),
58
+ Option.getOrElseW(() =>
59
+ absurd<string>('Error context is missing name' as never),
60
+ ),
61
+ ),
62
+ ),
63
+ Either.getOrElseW(identity),
64
+ );
65
+
66
+ const type = pipe(
67
+ e.context,
68
+ ReadonlyArray.last,
69
+ Option.map((contextEntry) => contextEntry.type.name),
70
+ Option.getOrElse(() => 'unknown'),
71
+ );
72
+
73
+ return { message, type, path };
74
+ };
75
+
76
+ // this is almost the same function like Semigroup.getObjectSemigroup but reversed
77
+ // in order to get the first error
78
+ const getObjectSemigroup = <
79
+ A extends Record<string, unknown> = never,
80
+ >(): SemiGroup.Semigroup<A> => ({
81
+ concat: (first, second) => Object.assign({}, second, first),
82
+ });
83
+
84
+ const concatToSingleError = (
85
+ errors: ReadonlyArray<FieldErrorWithPath>,
86
+ ): ErrorObject =>
87
+ pipe(
88
+ errors,
89
+ ReadonlyArray.map((error) => ({
90
+ [error.path]: {
91
+ type: error.type,
92
+ message: error.message,
93
+ },
94
+ })),
95
+ (errors) => SemiGroup.fold(getObjectSemigroup<ErrorObject>())({}, errors),
96
+ );
97
+
98
+ const appendSeveralErrors: SemiGroup.Semigroup<FieldErrorWithPath> = {
99
+ concat: (a, b) => ({
100
+ ...b,
101
+ types: { ...a.types, [a.type]: a.message, [b.type]: b.message },
102
+ }),
103
+ };
104
+
105
+ const concatToMultipleErrors = (
106
+ errors: ReadonlyArray<FieldErrorWithPath>,
107
+ ): ErrorObject =>
108
+ pipe(
109
+ ReadonlyRecord.fromFoldableMap(appendSeveralErrors, ReadonlyArray.Foldable)(
110
+ errors,
111
+ (error) => [error.path, error],
112
+ ),
113
+ ReadonlyRecord.map((errorWithPath) => {
114
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
115
+ const { path, ...error } = errorWithPath;
116
+
117
+ return error;
118
+ }),
119
+ );
120
+
121
+ const errorsToRecord =
122
+ (validateAllFieldCriteria: boolean) =>
123
+ (validationErrors: ReadonlyArray<ValidationError>): ErrorObject => {
124
+ const concat = validateAllFieldCriteria
125
+ ? concatToMultipleErrors
126
+ : concatToSingleError;
127
+
128
+ return pipe(validationErrors, ReadonlyArray.map(formatError), concat);
129
+ };
130
+
131
+ export default errorsToRecord;
@@ -0,0 +1,2 @@
1
+ export * from './io-ts';
2
+ export * from './types';
@@ -0,0 +1,33 @@
1
+ import * as Either from 'fp-ts/lib/Either';
2
+ import { pipe } from 'fp-ts/function';
3
+ import { toNestError, validateFieldsNatively } from '@hookform/resolvers';
4
+ import errorsToRecord from './errorsToRecord';
5
+ import { Resolver } from './types';
6
+ import { FieldErrors } from 'react-hook-form';
7
+
8
+ export const ioTsResolver: Resolver = (codec) => (values, _context, options) =>
9
+ pipe(
10
+ values,
11
+ codec.decode,
12
+ Either.mapLeft(
13
+ errorsToRecord(
14
+ !options.shouldUseNativeValidation && options.criteriaMode === 'all',
15
+ ),
16
+ ),
17
+ Either.mapLeft((errors) => toNestError(errors, options)),
18
+ Either.fold(
19
+ (errors) => ({
20
+ values: {},
21
+ errors,
22
+ }),
23
+ (values) => {
24
+ options.shouldUseNativeValidation &&
25
+ validateFieldsNatively({}, options);
26
+
27
+ return {
28
+ values,
29
+ errors: {} as FieldErrors<any>,
30
+ };
31
+ },
32
+ ),
33
+ );
@@ -0,0 +1,23 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
2
+ import * as t from 'io-ts';
3
+ import {
4
+ FieldError,
5
+ ResolverOptions,
6
+ ResolverResult,
7
+ UnpackNestedValue,
8
+ } from 'react-hook-form';
9
+
10
+ export type Resolver = <
11
+ TFieldValues,
12
+ TInput extends unknown = unknown,
13
+ TContext extends object = object,
14
+ >(
15
+ codec: t.Decoder<TInput, UnpackNestedValue<TFieldValues>>,
16
+ ) => (
17
+ values: TInput,
18
+ _context: TContext | undefined,
19
+ options: ResolverOptions<TFieldValues>,
20
+ ) => ResolverResult<TFieldValues>;
21
+
22
+ export type ErrorObject = Record<string, FieldError>;
23
+ export type FieldErrorWithPath = FieldError & { path: string };
@@ -0,0 +1,2 @@
1
+ export * from './joi';
2
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ import { Resolver } from './types';
2
+ export declare const joiResolver: Resolver;
@@ -0,0 +1,2 @@
1
+ var e=require("react-hook-form"),r=require("@hookform/resolvers");exports.joiResolver=function(t,n,o){return void 0===n&&(n={abortEarly:!1}),void 0===o&&(o={}),function(a,i,s){try{var u=function(){return l.error?{values:{},errors:r.toNestError((t=l.error,n=!s.shouldUseNativeValidation&&"all"===s.criteriaMode,t.details.length?t.details.reduce(function(r,t){var o=t.path.join(".");if(r[o]||(r[o]={message:t.message,type:t.type}),n){var a=r[o].types,i=a&&a[t.type];r[o]=e.appendErrors(o,n,r,t.type,i?[].concat(i,t.message):t.message)}return r},{}):{}),s)}:(s.shouldUseNativeValidation&&r.validateFieldsNatively({},s),{errors:{},values:l.value});var t,n},c=Object.assign({},n,{context:i}),l={},v=function(){if("sync"===o.mode)l=t.validate(a,c);else{var e=function(e,r){try{var t=e()}catch(e){return r(e)}return t&&t.then?t.then(void 0,r):t}(function(){return Promise.resolve(t.validateAsync(a,c)).then(function(e){l.value=e})},function(e){l.error=e});if(e&&e.then)return e.then(function(){})}}();return Promise.resolve(v&&v.then?v.then(u):u())}catch(e){return Promise.reject(e)}}};
2
+ //# sourceMappingURL=joi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joi.js","sources":["../src/joi.ts"],"sourcesContent":["import { appendErrors, FieldError } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { ValidationError } from 'joi';\nimport { Resolver } from './types';\n\nconst parseErrorSchema = (\n error: ValidationError,\n validateAllFieldCriteria: boolean,\n) =>\n error.details.length\n ? error.details.reduce<Record<string, FieldError>>((previous, error) => {\n const _path = error.path.join('.');\n\n if (!previous[_path]) {\n previous[_path] = { message: error.message, type: error.type };\n }\n\n if (validateAllFieldCriteria) {\n const types = previous[_path].types;\n const messages = types && types[error.type!];\n\n previous[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n previous,\n error.type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n return previous;\n }, {})\n : {};\n\nexport const joiResolver: Resolver =\n (\n schema,\n schemaOptions = {\n abortEarly: false,\n },\n resolverOptions = {},\n ) =>\n async (values, context, options) => {\n const _schemaOptions = Object.assign({}, schemaOptions, {\n context,\n });\n\n let result: Record<string, any> = {};\n if (resolverOptions.mode === 'sync') {\n result = schema.validate(values, _schemaOptions);\n } else {\n try {\n result.value = await schema.validateAsync(values, _schemaOptions);\n } catch (e) {\n result.error = e;\n }\n }\n\n if (result.error) {\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(\n result.error,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {},\n values: result.value,\n };\n };\n"],"names":["schema","schemaOptions","resolverOptions","abortEarly","values","context","options","result","error","errors","toNestError","validateAllFieldCriteria","shouldUseNativeValidation","criteriaMode","details","length","reduce","previous","_path","path","join","message","type","types","messages","appendErrors","concat","validateFieldsNatively","value","_schemaOptions","Object","assign","mode","validate","validateAsync","e"],"mappings":"sFAqCE,SACEA,EACAC,EAGAC,mBAHAD,IAAAA,EAAgB,CACdE,YAAY,aAEdD,IAAAA,EAAkB,aAEbE,EAAQC,EAASC,wBAgBtB,OAAIC,EAAOC,MACF,CACLJ,OAAQ,GACRK,OAAQC,eAzDdF,EA2DUD,EAAOC,MA1DjBG,GA2DWL,EAAQM,2BACkB,QAAzBN,EAAQO,aA1DpBL,EAAMM,QAAQC,OACVP,EAAMM,QAAQE,OAAmC,SAACC,EAAUT,GAC1D,IAAMU,EAAQV,EAAMW,KAAKC,KAAK,KAM9B,GAJKH,EAASC,KACZD,EAASC,GAAS,CAAEG,QAASb,EAAMa,QAASC,KAAMd,EAAMc,OAGtDX,EAA0B,CAC5B,IAAMY,EAAQN,EAASC,GAAOK,MACxBC,EAAWD,GAASA,EAAMf,EAAMc,MAEtCL,EAASC,GAASO,eAChBP,EACAP,EACAM,EACAT,EAAMc,KACNE,EACK,GAAgBE,OAAOF,EAAsBhB,EAAMa,SACpDb,EAAMa,SAId,OAAOJ,GACN,IACH,IAmCIX,KAKNA,EAAQM,2BAA6Be,yBAAuB,GAAIrB,GAEzD,CACLG,OAAQ,GACRL,OAAQG,EAAOqB,QAzEI,IACvBpB,EACAG,GAsCQkB,EAAiBC,OAAOC,OAAO,GAAI9B,EAAe,CACtDI,QAAAA,IAGEE,EAA8B,mBACL,SAAzBL,EAAgB8B,KAClBzB,EAASP,EAAOiC,SAAS7B,EAAQyB,sIAGV7B,EAAOkC,cAAc9B,EAAQyB,qBAAlDtB,EAAOqB,oBACAO,GACP5B,EAAOC,MAAQ2B,iGAnBrB"}
@@ -0,0 +1,2 @@
1
+ import{appendErrors as e}from"react-hook-form";import{toNestError as r,validateFieldsNatively as t}from"@hookform/resolvers";var n=function(n,o,a){return void 0===o&&(o={abortEarly:!1}),void 0===a&&(a={}),function(i,s,u){try{var c=function(){return l.error?{values:{},errors:r((n=l.error,o=!u.shouldUseNativeValidation&&"all"===u.criteriaMode,n.details.length?n.details.reduce(function(r,t){var n=t.path.join(".");if(r[n]||(r[n]={message:t.message,type:t.type}),o){var a=r[n].types,i=a&&a[t.type];r[n]=e(n,o,r,t.type,i?[].concat(i,t.message):t.message)}return r},{}):{}),u)}:(u.shouldUseNativeValidation&&t({},u),{errors:{},values:l.value});var n,o},v=Object.assign({},o,{context:s}),l={},f=function(){if("sync"===a.mode)l=n.validate(i,v);else{var e=function(e,r){try{var t=e()}catch(e){return r(e)}return t&&t.then?t.then(void 0,r):t}(function(){return Promise.resolve(n.validateAsync(i,v)).then(function(e){l.value=e})},function(e){l.error=e});if(e&&e.then)return e.then(function(){})}}();return Promise.resolve(f&&f.then?f.then(c):c())}catch(e){return Promise.reject(e)}}};export{n as joiResolver};
2
+ //# sourceMappingURL=joi.module.js.map
@@ -0,0 +1,2 @@
1
+ import{appendErrors as e}from"react-hook-form";import{toNestError as r,validateFieldsNatively as t}from"@hookform/resolvers";const a=(a,o={abortEarly:!1},s={})=>async(i,l,c)=>{const n=Object.assign({},o,{context:l});let d={};if("sync"===s.mode)d=a.validate(i,n);else try{d.value=await a.validateAsync(i,n)}catch(e){d.error=e}return d.error?{values:{},errors:r((m=d.error,v=!c.shouldUseNativeValidation&&"all"===c.criteriaMode,m.details.length?m.details.reduce((r,t)=>{const a=t.path.join(".");if(r[a]||(r[a]={message:t.message,type:t.type}),v){const o=r[a].types,s=o&&o[t.type];r[a]=e(a,v,r,t.type,s?[].concat(s,t.message):t.message)}return r},{}):{}),c)}:(c.shouldUseNativeValidation&&t({},c),{errors:{},values:d.value});var m,v};export{a as joiResolver};
2
+ //# sourceMappingURL=joi.modern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joi.modern.js","sources":["../src/joi.ts"],"sourcesContent":["import { appendErrors, FieldError } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { ValidationError } from 'joi';\nimport { Resolver } from './types';\n\nconst parseErrorSchema = (\n error: ValidationError,\n validateAllFieldCriteria: boolean,\n) =>\n error.details.length\n ? error.details.reduce<Record<string, FieldError>>((previous, error) => {\n const _path = error.path.join('.');\n\n if (!previous[_path]) {\n previous[_path] = { message: error.message, type: error.type };\n }\n\n if (validateAllFieldCriteria) {\n const types = previous[_path].types;\n const messages = types && types[error.type!];\n\n previous[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n previous,\n error.type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n return previous;\n }, {})\n : {};\n\nexport const joiResolver: Resolver =\n (\n schema,\n schemaOptions = {\n abortEarly: false,\n },\n resolverOptions = {},\n ) =>\n async (values, context, options) => {\n const _schemaOptions = Object.assign({}, schemaOptions, {\n context,\n });\n\n let result: Record<string, any> = {};\n if (resolverOptions.mode === 'sync') {\n result = schema.validate(values, _schemaOptions);\n } else {\n try {\n result.value = await schema.validateAsync(values, _schemaOptions);\n } catch (e) {\n result.error = e;\n }\n }\n\n if (result.error) {\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(\n result.error,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {},\n values: result.value,\n };\n };\n"],"names":["joiResolver","schema","schemaOptions","abortEarly","resolverOptions","async","values","context","options","_schemaOptions","Object","assign","result","mode","validate","value","validateAsync","e","error","errors","toNestError","validateAllFieldCriteria","shouldUseNativeValidation","criteriaMode","details","length","reduce","previous","_path","path","join","message","type","types","messages","appendErrors","concat","validateFieldsNatively"],"mappings":"6HAKA,MA+BaA,EACX,CACEC,EACAC,EAAgB,CACdC,YAAY,GAEdC,EAAkB,KAEpBC,MAAOC,EAAQC,EAASC,KACtB,MAAMC,EAAiBC,OAAOC,OAAO,GAAIT,EAAe,CACtDK,QAAAA,IAGF,IAAIK,EAA8B,GAClC,GAA6B,SAAzBR,EAAgBS,KAClBD,EAASX,EAAOa,SAASR,EAAQG,QAEjC,IACEG,EAAOG,YAAcd,EAAOe,cAAcV,EAAQG,GAClD,MAAOQ,GACPL,EAAOM,MAAQD,EAInB,OAAIL,EAAOM,MACF,CACLZ,OAAQ,GACRa,OAAQC,GAzDdF,EA2DUN,EAAOM,MA1DjBG,GA2DWb,EAAQc,2BACkB,QAAzBd,EAAQe,aA1DpBL,EAAMM,QAAQC,OACVP,EAAMM,QAAQE,OAAmC,CAACC,EAAUT,KAC1D,MAAMU,EAAQV,EAAMW,KAAKC,KAAK,KAM9B,GAJKH,EAASC,KACZD,EAASC,GAAS,CAAEG,QAASb,EAAMa,QAASC,KAAMd,EAAMc,OAGtDX,EAA0B,CAC5B,MAAMY,EAAQN,EAASC,GAAOK,MACxBC,EAAWD,GAASA,EAAMf,EAAMc,MAEtCL,EAASC,GAASO,EAChBP,EACAP,EACAM,EACAT,EAAMc,KACNE,EACK,GAAgBE,OAAOF,EAAsBhB,EAAMa,SACpDb,EAAMa,SAId,OAAOJ,GACN,IACH,IAmCInB,KAKNA,EAAQc,2BAA6Be,EAAuB,GAAI7B,GAEzD,CACLW,OAAQ,GACRb,OAAQM,EAAOG,QAzEI,IACvBG,EACAG"}
@@ -0,0 +1,2 @@
1
+ import{appendErrors as e}from"react-hook-form";import{toNestError as r,validateFieldsNatively as t}from"@hookform/resolvers";var n=function(n,o,a){return void 0===o&&(o={abortEarly:!1}),void 0===a&&(a={}),function(i,s,u){try{var c=function(){return l.error?{values:{},errors:r((n=l.error,o=!u.shouldUseNativeValidation&&"all"===u.criteriaMode,n.details.length?n.details.reduce(function(r,t){var n=t.path.join(".");if(r[n]||(r[n]={message:t.message,type:t.type}),o){var a=r[n].types,i=a&&a[t.type];r[n]=e(n,o,r,t.type,i?[].concat(i,t.message):t.message)}return r},{}):{}),u)}:(u.shouldUseNativeValidation&&t({},u),{errors:{},values:l.value});var n,o},v=Object.assign({},o,{context:s}),l={},f=function(){if("sync"===a.mode)l=n.validate(i,v);else{var e=function(e,r){try{var t=e()}catch(e){return r(e)}return t&&t.then?t.then(void 0,r):t}(function(){return Promise.resolve(n.validateAsync(i,v)).then(function(e){l.value=e})},function(e){l.error=e});if(e&&e.then)return e.then(function(){})}}();return Promise.resolve(f&&f.then?f.then(c):c())}catch(e){return Promise.reject(e)}}};export{n as joiResolver};
2
+ //# sourceMappingURL=joi.module.js.map