@hookform/resolvers 2.0.0-beta.7 → 2.0.0
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.
- package/README.md +19 -10
- package/dist/index.d.ts +1 -1
- package/dist/resolvers.js +1 -1
- package/dist/resolvers.js.map +1 -1
- package/dist/resolvers.mjs +1 -1
- package/dist/resolvers.modern.js +1 -1
- package/dist/resolvers.modern.js.map +1 -1
- package/dist/resolvers.module.js +1 -1
- package/dist/resolvers.module.js.map +1 -1
- package/dist/resolvers.umd.js +1 -1
- package/dist/resolvers.umd.js.map +1 -1
- package/dist/toNestError.d.ts +2 -0
- package/joi/dist/joi.js +1 -1
- package/joi/dist/joi.js.map +1 -1
- package/joi/dist/joi.mjs +1 -1
- package/joi/dist/joi.modern.js +1 -1
- package/joi/dist/joi.modern.js.map +1 -1
- package/joi/dist/joi.module.js +1 -1
- package/joi/dist/joi.module.js.map +1 -1
- package/joi/dist/joi.umd.js +1 -1
- package/joi/dist/joi.umd.js.map +1 -1
- package/joi/dist/types.d.ts +1 -1
- package/joi/src/__tests__/__fixtures__/data.ts +76 -0
- package/joi/src/__tests__/__snapshots__/joi.ts.snap +118 -0
- package/joi/src/__tests__/joi.ts +35 -88
- package/joi/src/joi.ts +47 -64
- package/joi/src/types.ts +1 -1
- package/package.json +14 -15
- package/superstruct/dist/superstruct.js +1 -1
- package/superstruct/dist/superstruct.js.map +1 -1
- package/superstruct/dist/superstruct.mjs +1 -1
- package/superstruct/dist/superstruct.modern.js +1 -1
- package/superstruct/dist/superstruct.modern.js.map +1 -1
- package/superstruct/dist/superstruct.module.js +1 -1
- package/superstruct/dist/superstruct.module.js.map +1 -1
- package/superstruct/dist/superstruct.umd.js +1 -1
- package/superstruct/dist/superstruct.umd.js.map +1 -1
- package/superstruct/dist/types.d.ts +1 -1
- package/superstruct/package.json +2 -1
- package/superstruct/src/__tests__/__fixtures__/data.ts +73 -0
- package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +26 -56
- package/superstruct/src/__tests__/superstruct.ts +6 -65
- package/superstruct/src/superstruct.ts +20 -53
- package/superstruct/src/types.ts +1 -1
- package/vest/dist/vest.js +1 -1
- package/vest/dist/vest.js.map +1 -1
- package/vest/dist/vest.mjs +1 -1
- package/vest/dist/vest.modern.js +1 -1
- package/vest/dist/vest.modern.js.map +1 -1
- package/vest/dist/vest.module.js +1 -1
- package/vest/dist/vest.module.js.map +1 -1
- package/vest/dist/vest.umd.js +1 -1
- package/vest/dist/vest.umd.js.map +1 -1
- package/vest/package.json +3 -1
- package/vest/src/__tests__/__fixtures__/data.ts +67 -0
- package/vest/src/__tests__/__snapshots__/vest.ts.snap +28 -0
- package/vest/src/__tests__/vest.ts +22 -95
- package/vest/src/types.ts +1 -1
- package/vest/src/vest.ts +31 -42
- package/yup/dist/types.d.ts +4 -3
- package/yup/dist/yup.js +1 -1
- package/yup/dist/yup.js.map +1 -1
- package/yup/dist/yup.mjs +1 -1
- package/yup/dist/yup.modern.js +1 -1
- package/yup/dist/yup.modern.js.map +1 -1
- package/yup/dist/yup.module.js +1 -1
- package/yup/dist/yup.module.js.map +1 -1
- package/yup/dist/yup.umd.js +1 -1
- package/yup/dist/yup.umd.js.map +1 -1
- package/yup/package.json +2 -1
- package/yup/src/__tests__/__fixtures__/data.ts +65 -0
- package/yup/src/__tests__/__snapshots__/yup.ts.snap +99 -13
- package/yup/src/__tests__/yup.ts +23 -97
- package/yup/src/types.ts +6 -3
- package/yup/src/yup.ts +30 -60
- package/zod/dist/types.d.ts +1 -1
- package/zod/dist/zod.js +1 -1
- package/zod/dist/zod.js.map +1 -1
- package/zod/dist/zod.mjs +1 -1
- package/zod/dist/zod.modern.js +1 -1
- package/zod/dist/zod.modern.js.map +1 -1
- package/zod/dist/zod.module.js +1 -1
- package/zod/dist/zod.module.js.map +1 -1
- package/zod/dist/zod.umd.js +1 -1
- package/zod/dist/zod.umd.js.map +1 -1
- package/zod/src/__tests__/__fixtures__/data.ts +68 -0
- package/zod/src/__tests__/__snapshots__/zod.ts.snap +146 -0
- package/zod/src/__tests__/zod.ts +19 -79
- package/zod/src/types.ts +1 -1
- package/zod/src/zod.ts +45 -50
- package/dist/convertArrayToPathName.d.ts +0 -1
|
@@ -5,26 +5,52 @@ Object {
|
|
|
5
5
|
"errors": Object {
|
|
6
6
|
"birthYear": Object {
|
|
7
7
|
"message": "\\"birthYear\\" must be a number",
|
|
8
|
+
"ref": undefined,
|
|
8
9
|
"type": "number.base",
|
|
9
10
|
},
|
|
10
11
|
"email": Object {
|
|
11
12
|
"message": "\\"email\\" is not allowed to be empty",
|
|
13
|
+
"ref": Object {
|
|
14
|
+
"name": "email",
|
|
15
|
+
},
|
|
12
16
|
"type": "string.empty",
|
|
13
17
|
},
|
|
14
18
|
"enabled": Object {
|
|
15
19
|
"message": "\\"enabled\\" is required",
|
|
20
|
+
"ref": undefined,
|
|
16
21
|
"type": "any.required",
|
|
17
22
|
},
|
|
23
|
+
"like": Array [
|
|
24
|
+
Object {
|
|
25
|
+
"id": Object {
|
|
26
|
+
"message": "\\"like[0].id\\" must be a number",
|
|
27
|
+
"ref": undefined,
|
|
28
|
+
"type": "number.base",
|
|
29
|
+
},
|
|
30
|
+
"name": Object {
|
|
31
|
+
"message": "\\"like[0].name\\" length must be 4 characters long",
|
|
32
|
+
"ref": undefined,
|
|
33
|
+
"type": "string.length",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
18
37
|
"password": Object {
|
|
19
38
|
"message": "\\"password\\" with value \\"___\\" fails to match the required pattern: /^[a-zA-Z0-9]{3,30}$/",
|
|
39
|
+
"ref": Object {
|
|
40
|
+
"name": "password",
|
|
41
|
+
},
|
|
20
42
|
"type": "string.pattern.base",
|
|
21
43
|
},
|
|
22
44
|
"tags": Object {
|
|
23
45
|
"message": "\\"tags\\" is required",
|
|
46
|
+
"ref": undefined,
|
|
24
47
|
"type": "any.required",
|
|
25
48
|
},
|
|
26
49
|
"username": Object {
|
|
27
50
|
"message": "\\"username\\" is required",
|
|
51
|
+
"ref": Object {
|
|
52
|
+
"name": "username",
|
|
53
|
+
},
|
|
28
54
|
"type": "any.required",
|
|
29
55
|
},
|
|
30
56
|
},
|
|
@@ -37,26 +63,52 @@ Object {
|
|
|
37
63
|
"errors": Object {
|
|
38
64
|
"birthYear": Object {
|
|
39
65
|
"message": "\\"birthYear\\" must be a number",
|
|
66
|
+
"ref": undefined,
|
|
40
67
|
"type": "number.base",
|
|
41
68
|
},
|
|
42
69
|
"email": Object {
|
|
43
70
|
"message": "\\"email\\" is not allowed to be empty",
|
|
71
|
+
"ref": Object {
|
|
72
|
+
"name": "email",
|
|
73
|
+
},
|
|
44
74
|
"type": "string.empty",
|
|
45
75
|
},
|
|
46
76
|
"enabled": Object {
|
|
47
77
|
"message": "\\"enabled\\" is required",
|
|
78
|
+
"ref": undefined,
|
|
48
79
|
"type": "any.required",
|
|
49
80
|
},
|
|
81
|
+
"like": Array [
|
|
82
|
+
Object {
|
|
83
|
+
"id": Object {
|
|
84
|
+
"message": "\\"like[0].id\\" must be a number",
|
|
85
|
+
"ref": undefined,
|
|
86
|
+
"type": "number.base",
|
|
87
|
+
},
|
|
88
|
+
"name": Object {
|
|
89
|
+
"message": "\\"like[0].name\\" length must be 4 characters long",
|
|
90
|
+
"ref": undefined,
|
|
91
|
+
"type": "string.length",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
50
95
|
"password": Object {
|
|
51
96
|
"message": "\\"password\\" with value \\"___\\" fails to match the required pattern: /^[a-zA-Z0-9]{3,30}$/",
|
|
97
|
+
"ref": Object {
|
|
98
|
+
"name": "password",
|
|
99
|
+
},
|
|
52
100
|
"type": "string.pattern.base",
|
|
53
101
|
},
|
|
54
102
|
"tags": Object {
|
|
55
103
|
"message": "\\"tags\\" is required",
|
|
104
|
+
"ref": undefined,
|
|
56
105
|
"type": "any.required",
|
|
57
106
|
},
|
|
58
107
|
"username": Object {
|
|
59
108
|
"message": "\\"username\\" is required",
|
|
109
|
+
"ref": Object {
|
|
110
|
+
"name": "username",
|
|
111
|
+
},
|
|
60
112
|
"type": "any.required",
|
|
61
113
|
},
|
|
62
114
|
},
|
|
@@ -69,6 +121,7 @@ Object {
|
|
|
69
121
|
"errors": Object {
|
|
70
122
|
"birthYear": Object {
|
|
71
123
|
"message": "\\"birthYear\\" must be a number",
|
|
124
|
+
"ref": undefined,
|
|
72
125
|
"type": "number.base",
|
|
73
126
|
"types": Object {
|
|
74
127
|
"number.base": "\\"birthYear\\" must be a number",
|
|
@@ -76,6 +129,9 @@ Object {
|
|
|
76
129
|
},
|
|
77
130
|
"email": Object {
|
|
78
131
|
"message": "\\"email\\" is not allowed to be empty",
|
|
132
|
+
"ref": Object {
|
|
133
|
+
"name": "email",
|
|
134
|
+
},
|
|
79
135
|
"type": "string.empty",
|
|
80
136
|
"types": Object {
|
|
81
137
|
"string.empty": "\\"email\\" is not allowed to be empty",
|
|
@@ -83,13 +139,38 @@ Object {
|
|
|
83
139
|
},
|
|
84
140
|
"enabled": Object {
|
|
85
141
|
"message": "\\"enabled\\" is required",
|
|
142
|
+
"ref": undefined,
|
|
86
143
|
"type": "any.required",
|
|
87
144
|
"types": Object {
|
|
88
145
|
"any.required": "\\"enabled\\" is required",
|
|
89
146
|
},
|
|
90
147
|
},
|
|
148
|
+
"like": Array [
|
|
149
|
+
Object {
|
|
150
|
+
"id": Object {
|
|
151
|
+
"message": "\\"like[0].id\\" must be a number",
|
|
152
|
+
"ref": undefined,
|
|
153
|
+
"type": "number.base",
|
|
154
|
+
"types": Object {
|
|
155
|
+
"number.base": "\\"like[0].id\\" must be a number",
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
"name": Object {
|
|
159
|
+
"message": "\\"like[0].name\\" length must be 4 characters long",
|
|
160
|
+
"ref": undefined,
|
|
161
|
+
"type": "string.length",
|
|
162
|
+
"types": Object {
|
|
163
|
+
"string.length": "\\"like[0].name\\" length must be 4 characters long",
|
|
164
|
+
"string.pattern.base": "\\"like[0].name\\" with value \\"r\\" fails to match the required pattern: /a/",
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
],
|
|
91
169
|
"password": Object {
|
|
92
170
|
"message": "\\"password\\" with value \\"___\\" fails to match the required pattern: /^[a-zA-Z0-9]{3,30}$/",
|
|
171
|
+
"ref": Object {
|
|
172
|
+
"name": "password",
|
|
173
|
+
},
|
|
93
174
|
"type": "string.pattern.base",
|
|
94
175
|
"types": Object {
|
|
95
176
|
"string.pattern.base": "\\"password\\" with value \\"___\\" fails to match the required pattern: /^[a-zA-Z0-9]{3,30}$/",
|
|
@@ -97,6 +178,7 @@ Object {
|
|
|
97
178
|
},
|
|
98
179
|
"tags": Object {
|
|
99
180
|
"message": "\\"tags\\" is required",
|
|
181
|
+
"ref": undefined,
|
|
100
182
|
"type": "any.required",
|
|
101
183
|
"types": Object {
|
|
102
184
|
"any.required": "\\"tags\\" is required",
|
|
@@ -104,6 +186,9 @@ Object {
|
|
|
104
186
|
},
|
|
105
187
|
"username": Object {
|
|
106
188
|
"message": "\\"username\\" is required",
|
|
189
|
+
"ref": Object {
|
|
190
|
+
"name": "username",
|
|
191
|
+
},
|
|
107
192
|
"type": "any.required",
|
|
108
193
|
"types": Object {
|
|
109
194
|
"any.required": "\\"username\\" is required",
|
|
@@ -119,6 +204,7 @@ Object {
|
|
|
119
204
|
"errors": Object {
|
|
120
205
|
"birthYear": Object {
|
|
121
206
|
"message": "\\"birthYear\\" must be a number",
|
|
207
|
+
"ref": undefined,
|
|
122
208
|
"type": "number.base",
|
|
123
209
|
"types": Object {
|
|
124
210
|
"number.base": "\\"birthYear\\" must be a number",
|
|
@@ -126,6 +212,9 @@ Object {
|
|
|
126
212
|
},
|
|
127
213
|
"email": Object {
|
|
128
214
|
"message": "\\"email\\" is not allowed to be empty",
|
|
215
|
+
"ref": Object {
|
|
216
|
+
"name": "email",
|
|
217
|
+
},
|
|
129
218
|
"type": "string.empty",
|
|
130
219
|
"types": Object {
|
|
131
220
|
"string.empty": "\\"email\\" is not allowed to be empty",
|
|
@@ -133,13 +222,38 @@ Object {
|
|
|
133
222
|
},
|
|
134
223
|
"enabled": Object {
|
|
135
224
|
"message": "\\"enabled\\" is required",
|
|
225
|
+
"ref": undefined,
|
|
136
226
|
"type": "any.required",
|
|
137
227
|
"types": Object {
|
|
138
228
|
"any.required": "\\"enabled\\" is required",
|
|
139
229
|
},
|
|
140
230
|
},
|
|
231
|
+
"like": Array [
|
|
232
|
+
Object {
|
|
233
|
+
"id": Object {
|
|
234
|
+
"message": "\\"like[0].id\\" must be a number",
|
|
235
|
+
"ref": undefined,
|
|
236
|
+
"type": "number.base",
|
|
237
|
+
"types": Object {
|
|
238
|
+
"number.base": "\\"like[0].id\\" must be a number",
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
"name": Object {
|
|
242
|
+
"message": "\\"like[0].name\\" length must be 4 characters long",
|
|
243
|
+
"ref": undefined,
|
|
244
|
+
"type": "string.length",
|
|
245
|
+
"types": Object {
|
|
246
|
+
"string.length": "\\"like[0].name\\" length must be 4 characters long",
|
|
247
|
+
"string.pattern.base": "\\"like[0].name\\" with value \\"r\\" fails to match the required pattern: /a/",
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
],
|
|
141
252
|
"password": Object {
|
|
142
253
|
"message": "\\"password\\" with value \\"___\\" fails to match the required pattern: /^[a-zA-Z0-9]{3,30}$/",
|
|
254
|
+
"ref": Object {
|
|
255
|
+
"name": "password",
|
|
256
|
+
},
|
|
143
257
|
"type": "string.pattern.base",
|
|
144
258
|
"types": Object {
|
|
145
259
|
"string.pattern.base": "\\"password\\" with value \\"___\\" fails to match the required pattern: /^[a-zA-Z0-9]{3,30}$/",
|
|
@@ -147,6 +261,7 @@ Object {
|
|
|
147
261
|
},
|
|
148
262
|
"tags": Object {
|
|
149
263
|
"message": "\\"tags\\" is required",
|
|
264
|
+
"ref": undefined,
|
|
150
265
|
"type": "any.required",
|
|
151
266
|
"types": Object {
|
|
152
267
|
"any.required": "\\"tags\\" is required",
|
|
@@ -154,6 +269,9 @@ Object {
|
|
|
154
269
|
},
|
|
155
270
|
"username": Object {
|
|
156
271
|
"message": "\\"username\\" is required",
|
|
272
|
+
"ref": Object {
|
|
273
|
+
"name": "username",
|
|
274
|
+
},
|
|
157
275
|
"type": "any.required",
|
|
158
276
|
"types": Object {
|
|
159
277
|
"any.required": "\\"username\\" is required",
|
package/joi/src/__tests__/joi.ts
CHANGED
|
@@ -1,105 +1,48 @@
|
|
|
1
|
-
import * as Joi from 'joi';
|
|
2
1
|
import { joiResolver } from '..';
|
|
3
|
-
|
|
4
|
-
const schema = Joi.object({
|
|
5
|
-
username: Joi.string().alphanum().min(3).max(30).required(),
|
|
6
|
-
password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).required(),
|
|
7
|
-
repeatPassword: Joi.ref('password'),
|
|
8
|
-
accessToken: [Joi.string(), Joi.number()],
|
|
9
|
-
birthYear: Joi.number().integer().min(1900).max(2013),
|
|
10
|
-
email: Joi.string().email({
|
|
11
|
-
minDomainSegments: 2,
|
|
12
|
-
tlds: { allow: ['com', 'net'] },
|
|
13
|
-
}),
|
|
14
|
-
tags: Joi.array().items(Joi.string()).required(),
|
|
15
|
-
enabled: Joi.boolean().required(),
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
interface Data {
|
|
19
|
-
username: string;
|
|
20
|
-
password: string;
|
|
21
|
-
repeatPassword: string;
|
|
22
|
-
accessToken?: number | string;
|
|
23
|
-
birthYear?: number;
|
|
24
|
-
email?: string;
|
|
25
|
-
tags: string[];
|
|
26
|
-
enabled: boolean;
|
|
27
|
-
}
|
|
2
|
+
import { schema, validData, fields, invalidData } from './__fixtures__/data';
|
|
28
3
|
|
|
29
4
|
describe('joiResolver', () => {
|
|
30
5
|
it('should return values from joiResolver when validation pass', async () => {
|
|
31
|
-
const data: Data = {
|
|
32
|
-
username: 'Doe',
|
|
33
|
-
password: 'Password123',
|
|
34
|
-
repeatPassword: 'Password123',
|
|
35
|
-
birthYear: 2000,
|
|
36
|
-
email: 'john@doe.com',
|
|
37
|
-
tags: ['tag1', 'tag2'],
|
|
38
|
-
enabled: true,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
6
|
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
|
|
42
7
|
const validateSpy = jest.spyOn(schema, 'validate');
|
|
43
8
|
|
|
44
|
-
const result = await joiResolver(schema)(
|
|
9
|
+
const result = await joiResolver(schema)(validData, undefined, {
|
|
10
|
+
fields,
|
|
11
|
+
});
|
|
45
12
|
|
|
46
13
|
expect(validateSpy).not.toHaveBeenCalled();
|
|
47
14
|
expect(validateAsyncSpy).toHaveBeenCalledTimes(1);
|
|
48
|
-
expect(result).toEqual({ errors: {}, values:
|
|
15
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
49
16
|
});
|
|
50
17
|
|
|
51
18
|
it('should return values from joiResolver with `mode: sync` when validation pass', async () => {
|
|
52
|
-
const data: Data = {
|
|
53
|
-
username: 'Doe',
|
|
54
|
-
password: 'Password123',
|
|
55
|
-
repeatPassword: 'Password123',
|
|
56
|
-
birthYear: 2000,
|
|
57
|
-
email: 'john@doe.com',
|
|
58
|
-
tags: ['tag1', 'tag2'],
|
|
59
|
-
enabled: true,
|
|
60
|
-
};
|
|
61
|
-
|
|
62
19
|
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
|
|
63
20
|
const validateSpy = jest.spyOn(schema, 'validate');
|
|
64
21
|
|
|
65
|
-
const result = await joiResolver(schema, undefined, {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
{ fields: {} },
|
|
69
|
-
);
|
|
22
|
+
const result = await joiResolver(schema, undefined, {
|
|
23
|
+
mode: 'sync',
|
|
24
|
+
})(validData, undefined, { fields });
|
|
70
25
|
|
|
71
26
|
expect(validateAsyncSpy).not.toHaveBeenCalled();
|
|
72
27
|
expect(validateSpy).toHaveBeenCalledTimes(1);
|
|
73
|
-
expect(result).toEqual({ errors: {}, values:
|
|
28
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
74
29
|
});
|
|
75
30
|
|
|
76
31
|
it('should return a single error from joiResolver when validation fails', async () => {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
birthYear: 'birthYear',
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const result = await joiResolver(schema)(data, undefined, { fields: {} });
|
|
32
|
+
const result = await joiResolver(schema)(invalidData, undefined, {
|
|
33
|
+
fields,
|
|
34
|
+
});
|
|
84
35
|
|
|
85
36
|
expect(result).toMatchSnapshot();
|
|
86
37
|
});
|
|
87
38
|
|
|
88
39
|
it('should return a single error from joiResolver with `mode: sync` when validation fails', async () => {
|
|
89
|
-
const data = {
|
|
90
|
-
password: '___',
|
|
91
|
-
email: '',
|
|
92
|
-
birthYear: 'birthYear',
|
|
93
|
-
};
|
|
94
|
-
|
|
95
40
|
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
|
|
96
41
|
const validateSpy = jest.spyOn(schema, 'validate');
|
|
97
42
|
|
|
98
|
-
const result = await joiResolver(schema, undefined, {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
{ fields: {} },
|
|
102
|
-
);
|
|
43
|
+
const result = await joiResolver(schema, undefined, {
|
|
44
|
+
mode: 'sync',
|
|
45
|
+
})(invalidData, undefined, { fields });
|
|
103
46
|
|
|
104
47
|
expect(validateAsyncSpy).not.toHaveBeenCalled();
|
|
105
48
|
expect(validateSpy).toHaveBeenCalledTimes(1);
|
|
@@ -107,14 +50,8 @@ describe('joiResolver', () => {
|
|
|
107
50
|
});
|
|
108
51
|
|
|
109
52
|
it('should return all the errors from joiResolver when validation fails with `validateAllFieldCriteria` set to true', async () => {
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
email: '',
|
|
113
|
-
birthYear: 'birthYear',
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const result = await joiResolver(schema)(data, undefined, {
|
|
117
|
-
fields: {},
|
|
53
|
+
const result = await joiResolver(schema)(invalidData, undefined, {
|
|
54
|
+
fields,
|
|
118
55
|
criteriaMode: 'all',
|
|
119
56
|
});
|
|
120
57
|
|
|
@@ -122,21 +59,31 @@ describe('joiResolver', () => {
|
|
|
122
59
|
});
|
|
123
60
|
|
|
124
61
|
it('should return all the errors from joiResolver when validation fails with `validateAllFieldCriteria` set to true and `mode: sync`', async () => {
|
|
125
|
-
const data = {
|
|
126
|
-
password: '___',
|
|
127
|
-
email: '',
|
|
128
|
-
birthYear: 'birthYear',
|
|
129
|
-
};
|
|
130
|
-
|
|
131
62
|
const result = await joiResolver(schema, undefined, { mode: 'sync' })(
|
|
132
|
-
|
|
63
|
+
invalidData,
|
|
133
64
|
undefined,
|
|
134
65
|
{
|
|
135
|
-
fields
|
|
66
|
+
fields,
|
|
136
67
|
criteriaMode: 'all',
|
|
137
68
|
},
|
|
138
69
|
);
|
|
139
70
|
|
|
140
71
|
expect(result).toMatchSnapshot();
|
|
141
72
|
});
|
|
73
|
+
|
|
74
|
+
it('should return values from joiResolver when validation pass and pass down the Joi context', async () => {
|
|
75
|
+
const context = { value: 'context' };
|
|
76
|
+
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
|
|
77
|
+
const validateSpy = jest.spyOn(schema, 'validate');
|
|
78
|
+
|
|
79
|
+
const result = await joiResolver(schema)(validData, context, { fields });
|
|
80
|
+
|
|
81
|
+
expect(validateSpy).not.toHaveBeenCalled();
|
|
82
|
+
expect(validateAsyncSpy).toHaveBeenCalledTimes(1);
|
|
83
|
+
expect(validateAsyncSpy).toHaveBeenCalledWith(validData, {
|
|
84
|
+
abortEarly: false,
|
|
85
|
+
context,
|
|
86
|
+
});
|
|
87
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
88
|
+
});
|
|
142
89
|
});
|
package/joi/src/joi.ts
CHANGED
|
@@ -1,80 +1,63 @@
|
|
|
1
|
-
import { appendErrors,
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import { convertArrayToPathName } from '@hookform/resolvers';
|
|
1
|
+
import { appendErrors, FieldError } from 'react-hook-form';
|
|
2
|
+
import { toNestError } from '@hookform/resolvers';
|
|
3
|
+
import type { ValidationError } from 'joi';
|
|
5
4
|
import { Resolver } from './types';
|
|
6
5
|
|
|
7
6
|
const parseErrorSchema = (
|
|
8
|
-
error:
|
|
7
|
+
error: ValidationError,
|
|
9
8
|
validateAllFieldCriteria: boolean,
|
|
10
9
|
) =>
|
|
11
|
-
|
|
12
|
-
? error.details.reduce(
|
|
13
|
-
|
|
14
|
-
const currentPath = convertArrayToPathName(path);
|
|
10
|
+
error.details.length
|
|
11
|
+
? error.details.reduce<Record<string, FieldError>>((previous, error) => {
|
|
12
|
+
const _path = error.path.join('.');
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
...(validateAllFieldCriteria
|
|
34
|
-
? {
|
|
35
|
-
types: { [type]: message || true },
|
|
36
|
-
}
|
|
37
|
-
: {}),
|
|
38
|
-
},
|
|
39
|
-
}
|
|
40
|
-
: {}),
|
|
41
|
-
};
|
|
42
|
-
},
|
|
43
|
-
{},
|
|
44
|
-
)
|
|
45
|
-
: [];
|
|
14
|
+
if (!previous[_path]) {
|
|
15
|
+
previous[_path] = { message: error.message, type: error.type };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (validateAllFieldCriteria) {
|
|
19
|
+
previous[_path] = appendErrors(
|
|
20
|
+
_path,
|
|
21
|
+
validateAllFieldCriteria,
|
|
22
|
+
previous,
|
|
23
|
+
error.type,
|
|
24
|
+
error.message,
|
|
25
|
+
) as FieldError;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return previous;
|
|
29
|
+
}, {})
|
|
30
|
+
: {};
|
|
46
31
|
|
|
47
32
|
export const joiResolver: Resolver = (
|
|
48
33
|
schema,
|
|
49
34
|
schemaOptions = {
|
|
50
35
|
abortEarly: false,
|
|
51
36
|
},
|
|
52
|
-
|
|
53
|
-
) => async (values,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
result = await schema.validateAsync(values, schemaOptions);
|
|
58
|
-
} else {
|
|
59
|
-
const { value, error } = schema.validate(values, schemaOptions);
|
|
60
|
-
|
|
61
|
-
if (error) {
|
|
62
|
-
throw error;
|
|
63
|
-
}
|
|
37
|
+
resolverOptions = {},
|
|
38
|
+
) => async (values, context, options) => {
|
|
39
|
+
const _schemaOptions = Object.assign({}, schemaOptions, {
|
|
40
|
+
context,
|
|
41
|
+
});
|
|
64
42
|
|
|
65
|
-
|
|
43
|
+
let result: Record<string, any> = {};
|
|
44
|
+
if (resolverOptions.mode === 'sync') {
|
|
45
|
+
result = schema.validate(values, _schemaOptions);
|
|
46
|
+
} else {
|
|
47
|
+
try {
|
|
48
|
+
result.value = await schema.validateAsync(values, _schemaOptions);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
result.error = e;
|
|
66
51
|
}
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
values: result,
|
|
70
|
-
errors: {},
|
|
71
|
-
};
|
|
72
|
-
} catch (e) {
|
|
73
|
-
return {
|
|
74
|
-
values: {},
|
|
75
|
-
errors: transformToNestObject(
|
|
76
|
-
parseErrorSchema(e, criteriaMode === 'all'),
|
|
77
|
-
),
|
|
78
|
-
};
|
|
79
52
|
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
values: result.error ? {} : result.value,
|
|
56
|
+
errors: result.error
|
|
57
|
+
? toNestError(
|
|
58
|
+
parseErrorSchema(result.error, options.criteriaMode === 'all'),
|
|
59
|
+
options.fields,
|
|
60
|
+
)
|
|
61
|
+
: {},
|
|
62
|
+
};
|
|
80
63
|
};
|
package/joi/src/types.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { AsyncValidationOptions, Schema } from 'joi';
|
|
|
9
9
|
export type Resolver = <T extends Schema>(
|
|
10
10
|
schema: T,
|
|
11
11
|
schemaOptions?: AsyncValidationOptions,
|
|
12
|
-
factoryOptions?: { mode
|
|
12
|
+
factoryOptions?: { mode?: 'async' | 'sync' },
|
|
13
13
|
) => <TFieldValues extends FieldValues, TContext>(
|
|
14
14
|
values: UnpackNestedValue<TFieldValues>,
|
|
15
15
|
context: TContext | undefined,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hookform/resolvers",
|
|
3
3
|
"amdName": "hookformResolvers",
|
|
4
|
-
"version": "2.0.0
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"description": "React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest and etc.",
|
|
6
6
|
"main": "dist/resolvers.js",
|
|
7
7
|
"module": "dist/resolvers.module.js",
|
|
@@ -70,14 +70,14 @@
|
|
|
70
70
|
"access": "public"
|
|
71
71
|
},
|
|
72
72
|
"scripts": {
|
|
73
|
-
"prepare": "run-s build && check-export-map",
|
|
73
|
+
"prepare": "run-s build:src build && check-export-map",
|
|
74
74
|
"build": "npm-run-all --parallel build:*",
|
|
75
75
|
"build:src": "microbundle build",
|
|
76
76
|
"build:zod": "microbundle --cwd zod --globals '@hookform/resolvers=hookformResolvers'",
|
|
77
|
-
"build:yup": "microbundle --cwd yup",
|
|
77
|
+
"build:yup": "microbundle --cwd yup --globals '@hookform/resolvers=hookformResolvers'",
|
|
78
78
|
"build:joi": "microbundle --cwd joi --globals '@hookform/resolvers=hookformResolvers'",
|
|
79
79
|
"build:superstruct": "microbundle --cwd superstruct --globals '@hookform/resolvers=hookformResolvers'",
|
|
80
|
-
"build:vest": "microbundle --cwd vest",
|
|
80
|
+
"build:vest": "microbundle --cwd vest --globals '@hookform/resolvers=hookformResolvers'",
|
|
81
81
|
"postbuild": "node ./config/node-13-exports.js",
|
|
82
82
|
"lint": "eslint . --ext .ts,.js --ignore-path .gitignore",
|
|
83
83
|
"lint:types": "tsc",
|
|
@@ -111,13 +111,13 @@
|
|
|
111
111
|
"devDependencies": {
|
|
112
112
|
"@testing-library/jest-dom": "^5.11.9",
|
|
113
113
|
"@testing-library/react": "^11.2.3",
|
|
114
|
-
"@testing-library/user-event": "^12.6.
|
|
114
|
+
"@testing-library/user-event": "^12.6.3",
|
|
115
115
|
"@types/jest": "^26.0.20",
|
|
116
116
|
"@types/react": "^17.0.0",
|
|
117
|
-
"@typescript-eslint/eslint-plugin": "^4.14.
|
|
118
|
-
"@typescript-eslint/parser": "^4.14.
|
|
117
|
+
"@typescript-eslint/eslint-plugin": "^4.14.2",
|
|
118
|
+
"@typescript-eslint/parser": "^4.14.2",
|
|
119
119
|
"check-export-map": "^1.0.1",
|
|
120
|
-
"eslint": "^7.
|
|
120
|
+
"eslint": "^7.19.0",
|
|
121
121
|
"eslint-config-prettier": "^7.2.0",
|
|
122
122
|
"eslint-plugin-prettier": "^3.3.1",
|
|
123
123
|
"husky": "^4.3.8",
|
|
@@ -129,12 +129,12 @@
|
|
|
129
129
|
"prettier": "^2.2.1",
|
|
130
130
|
"react": "^17.0.1",
|
|
131
131
|
"react-dom": "^17.0.1",
|
|
132
|
-
"react-hook-form": "^7.0.0-alpha.
|
|
133
|
-
"semantic-release": "^17.3.
|
|
134
|
-
"superstruct": "^0.
|
|
135
|
-
"ts-jest": "^26.
|
|
132
|
+
"react-hook-form": "^7.0.0-alpha.2",
|
|
133
|
+
"semantic-release": "^17.3.7",
|
|
134
|
+
"superstruct": "^0.14.0",
|
|
135
|
+
"ts-jest": "^26.5.0",
|
|
136
136
|
"typescript": "^4.1.3",
|
|
137
|
-
"vest": "^3.1.
|
|
137
|
+
"vest": "^3.1.2",
|
|
138
138
|
"yup": "^0.32.8",
|
|
139
139
|
"zod": "^1.11.11"
|
|
140
140
|
},
|
|
@@ -153,6 +153,5 @@
|
|
|
153
153
|
"*.{md,json,yml}": [
|
|
154
154
|
"prettier --write"
|
|
155
155
|
]
|
|
156
|
-
}
|
|
157
|
-
"dependencies": {}
|
|
156
|
+
}
|
|
158
157
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var r=require("
|
|
1
|
+
var r=require("@hookform/resolvers"),e=require("superstruct");exports.superstructResolver=function(s,t){return function(u,o,n){var a,i=e.validate(u,s,t);return{values:i[1]||{},errors:i[0]?r.toNestError((a=i[0],a.failures().reduce(function(r,e){return(r[e.path.join(".")]={message:e.message,type:e.type})&&r},{})),n.fields):{}}}};
|
|
2
2
|
//# sourceMappingURL=superstruct.js.map
|