@hookform/resolvers 2.0.0-rc.1 → 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/LICENSE +21 -0
- package/README.md +115 -18
- package/dist/index.d.ts +1 -0
- package/dist/resolvers.js +2 -0
- package/dist/resolvers.js.map +1 -0
- package/dist/resolvers.mjs +2 -0
- package/dist/resolvers.modern.js +2 -0
- package/dist/resolvers.modern.js.map +1 -0
- package/dist/resolvers.module.js +2 -0
- package/dist/resolvers.module.js.map +1 -0
- package/dist/resolvers.umd.js +2 -0
- package/dist/resolvers.umd.js.map +1 -0
- package/dist/toNestError.d.ts +2 -0
- package/joi/dist/index.d.ts +2 -0
- package/joi/dist/joi.d.ts +2 -0
- package/joi/dist/joi.js +2 -0
- package/joi/dist/joi.js.map +1 -0
- package/joi/dist/joi.mjs +2 -0
- package/joi/dist/joi.modern.js +2 -0
- package/joi/dist/joi.modern.js.map +1 -0
- package/joi/dist/joi.module.js +2 -0
- package/joi/dist/joi.module.js.map +1 -0
- package/joi/dist/joi.umd.js +2 -0
- package/joi/dist/joi.umd.js.map +1 -0
- package/joi/dist/types.d.ts +5 -0
- package/joi/package.json +17 -0
- package/joi/src/__tests__/Form.tsx +61 -0
- package/joi/src/__tests__/__fixtures__/data.ts +76 -0
- package/joi/src/__tests__/__snapshots__/joi.ts.snap +283 -0
- package/joi/src/__tests__/joi.ts +89 -0
- package/joi/src/index.ts +2 -0
- package/joi/src/joi.ts +63 -0
- package/joi/src/types.ts +17 -0
- package/package.json +111 -55
- package/superstruct/dist/index.d.ts +2 -0
- package/superstruct/dist/superstruct.d.ts +2 -0
- package/superstruct/dist/superstruct.js +2 -0
- package/superstruct/dist/superstruct.js.map +1 -0
- package/superstruct/dist/superstruct.mjs +2 -0
- package/superstruct/dist/superstruct.modern.js +2 -0
- package/superstruct/dist/superstruct.modern.js.map +1 -0
- package/superstruct/dist/superstruct.module.js +2 -0
- package/superstruct/dist/superstruct.module.js.map +1 -0
- package/superstruct/dist/superstruct.umd.js +2 -0
- package/superstruct/dist/superstruct.umd.js.map +1 -0
- package/superstruct/dist/types.d.ts +5 -0
- package/superstruct/package.json +18 -0
- package/superstruct/src/__tests__/Form.tsx +62 -0
- package/superstruct/src/__tests__/__fixtures__/data.ts +73 -0
- package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +64 -0
- package/superstruct/src/__tests__/superstruct.ts +20 -0
- package/superstruct/src/index.ts +2 -0
- package/superstruct/src/superstruct.ts +30 -0
- package/superstruct/src/types.ts +18 -0
- package/vest/dist/index.d.ts +1 -0
- package/vest/dist/vest.d.ts +2 -0
- package/vest/dist/vest.js +2 -0
- package/vest/dist/vest.js.map +1 -0
- package/vest/dist/vest.mjs +2 -0
- package/vest/dist/vest.modern.js +2 -0
- package/vest/dist/vest.modern.js.map +1 -0
- package/vest/dist/vest.module.js +2 -0
- package/vest/dist/vest.module.js.map +1 -0
- package/vest/dist/vest.umd.js +2 -0
- package/vest/dist/vest.umd.js.map +1 -0
- package/vest/package.json +18 -0
- package/vest/src/__tests__/Form.tsx +64 -0
- package/vest/src/__tests__/__fixtures__/data.ts +67 -0
- package/vest/src/__tests__/__snapshots__/vest.ts.snap +141 -0
- package/vest/src/__tests__/vest.ts +65 -0
- package/vest/src/index.ts +1 -0
- package/vest/src/types.ts +21 -0
- package/vest/src/vest.ts +45 -0
- package/yup/dist/index.d.ts +2 -0
- package/yup/dist/types.d.ts +8 -0
- package/yup/dist/yup.d.ts +2 -0
- package/yup/dist/yup.js +2 -0
- package/yup/dist/yup.js.map +1 -0
- package/yup/dist/yup.mjs +2 -0
- package/yup/dist/yup.modern.js +2 -0
- package/yup/dist/yup.modern.js.map +1 -0
- package/yup/dist/yup.module.js +2 -0
- package/yup/dist/yup.module.js.map +1 -0
- package/yup/dist/yup.umd.js +2 -0
- package/yup/dist/yup.umd.js.map +1 -0
- package/yup/package.json +17 -0
- package/yup/src/__tests__/Form.tsx +54 -0
- package/yup/src/__tests__/__fixtures__/data.ts +65 -0
- package/yup/src/__tests__/__snapshots__/yup.ts.snap +221 -0
- package/yup/src/__tests__/yup.ts +150 -0
- package/yup/src/index.ts +2 -0
- package/yup/src/types.ts +22 -0
- package/yup/src/yup.ts +65 -0
- package/zod/dist/index.d.ts +2 -0
- package/zod/dist/types.d.ts +6 -0
- package/zod/dist/zod.d.ts +2 -0
- package/zod/dist/zod.js +2 -0
- package/zod/dist/zod.js.map +1 -0
- package/zod/dist/zod.mjs +2 -0
- package/zod/dist/zod.modern.js +2 -0
- package/zod/dist/zod.modern.js.map +1 -0
- package/zod/dist/zod.module.js +2 -0
- package/zod/dist/zod.module.js.map +1 -0
- package/zod/dist/zod.umd.js +2 -0
- package/zod/dist/zod.umd.js.map +1 -0
- package/zod/package.json +17 -0
- package/zod/src/__tests__/Form.tsx +54 -0
- package/zod/src/__tests__/__fixtures__/data.ts +68 -0
- package/zod/src/__tests__/__snapshots__/zod.ts.snap +355 -0
- package/zod/src/__tests__/zod.ts +71 -0
- package/zod/src/index.ts +2 -0
- package/zod/src/types.ts +18 -0
- package/zod/src/zod.ts +65 -0
- package/dist/ie11/joi.d.ts +0 -3
- package/dist/ie11/joi.js +0 -104
- package/dist/ie11/joi.js.map +0 -1
- package/dist/ie11/superstruct.d.ts +0 -3
- package/dist/ie11/superstruct.js +0 -95
- package/dist/ie11/superstruct.js.map +0 -1
- package/dist/ie11/utils/convertArrayToPathName.d.ts +0 -2
- package/dist/ie11/utils/convertArrayToPathName.js +0 -12
- package/dist/ie11/utils/convertArrayToPathName.js.map +0 -1
- package/dist/ie11/yup.d.ts +0 -3
- package/dist/ie11/yup.js +0 -132
- package/dist/ie11/yup.js.map +0 -1
- package/dist/joi.d.ts +0 -3
- package/dist/joi.js +0 -41
- package/dist/joi.js.map +0 -1
- package/dist/superstruct.d.ts +0 -3
- package/dist/superstruct.js +0 -39
- package/dist/superstruct.js.map +0 -1
- package/dist/umd/index.js +0 -2
- package/dist/umd/index.js.map +0 -1
- package/dist/utils/convertArrayToPathName.d.ts +0 -2
- package/dist/utils/convertArrayToPathName.js +0 -8
- package/dist/utils/convertArrayToPathName.js.map +0 -1
- package/dist/yup.d.ts +0 -3
- package/dist/yup.js +0 -49
- package/dist/yup.js.map +0 -1
- package/joi.d.ts +0 -1
- package/joi.js +0 -1
- package/superstruct.js +0 -1
- package/yup.d.ts +0 -1
- package/yup.js +0 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`vestResolver should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true 1`] = `
|
|
4
|
+
Object {
|
|
5
|
+
"errors": Object {
|
|
6
|
+
"deepObject": Object {
|
|
7
|
+
"data": Object {
|
|
8
|
+
"message": "deepObject.data is required",
|
|
9
|
+
"ref": undefined,
|
|
10
|
+
"type": "",
|
|
11
|
+
"types": Object {
|
|
12
|
+
"0": "deepObject.data is required",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
"password": Object {
|
|
17
|
+
"message": "Password must be at least 5 chars",
|
|
18
|
+
"ref": Object {
|
|
19
|
+
"name": "password",
|
|
20
|
+
},
|
|
21
|
+
"type": "",
|
|
22
|
+
"types": Object {
|
|
23
|
+
"0": "Password must be at least 5 chars",
|
|
24
|
+
"1": "Password must contain a digit",
|
|
25
|
+
"2": "Password must contain a symbol",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
"username": Object {
|
|
29
|
+
"message": "Username is required",
|
|
30
|
+
"ref": Object {
|
|
31
|
+
"name": "username",
|
|
32
|
+
},
|
|
33
|
+
"type": "",
|
|
34
|
+
"types": Object {
|
|
35
|
+
"0": "Username is required",
|
|
36
|
+
"1": "Must be longer than 3 chars",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
"values": Object {},
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
exports[`vestResolver should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true and \`mode: sync\` 1`] = `
|
|
45
|
+
Object {
|
|
46
|
+
"errors": Object {
|
|
47
|
+
"deepObject": Object {
|
|
48
|
+
"data": Object {
|
|
49
|
+
"message": "deepObject.data is required",
|
|
50
|
+
"ref": undefined,
|
|
51
|
+
"type": "",
|
|
52
|
+
"types": Object {
|
|
53
|
+
"0": "deepObject.data is required",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
"password": Object {
|
|
58
|
+
"message": "Password must be at least 5 chars",
|
|
59
|
+
"ref": Object {
|
|
60
|
+
"name": "password",
|
|
61
|
+
},
|
|
62
|
+
"type": "",
|
|
63
|
+
"types": Object {
|
|
64
|
+
"0": "Password must be at least 5 chars",
|
|
65
|
+
"1": "Password must contain a digit",
|
|
66
|
+
"2": "Password must contain a symbol",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
"username": Object {
|
|
70
|
+
"message": "Username is required",
|
|
71
|
+
"ref": Object {
|
|
72
|
+
"name": "username",
|
|
73
|
+
},
|
|
74
|
+
"type": "",
|
|
75
|
+
"types": Object {
|
|
76
|
+
"0": "Username is required",
|
|
77
|
+
"1": "Must be longer than 3 chars",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
"values": Object {},
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
exports[`vestResolver should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false 1`] = `
|
|
86
|
+
Object {
|
|
87
|
+
"errors": Object {
|
|
88
|
+
"deepObject": Object {
|
|
89
|
+
"data": Object {
|
|
90
|
+
"message": "deepObject.data is required",
|
|
91
|
+
"ref": undefined,
|
|
92
|
+
"type": "",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
"password": Object {
|
|
96
|
+
"message": "Password must be at least 5 chars",
|
|
97
|
+
"ref": Object {
|
|
98
|
+
"name": "password",
|
|
99
|
+
},
|
|
100
|
+
"type": "",
|
|
101
|
+
},
|
|
102
|
+
"username": Object {
|
|
103
|
+
"message": "Username is required",
|
|
104
|
+
"ref": Object {
|
|
105
|
+
"name": "username",
|
|
106
|
+
},
|
|
107
|
+
"type": "",
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
"values": Object {},
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
|
|
114
|
+
exports[`vestResolver should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false and \`mode: sync\` 1`] = `
|
|
115
|
+
Object {
|
|
116
|
+
"errors": Object {
|
|
117
|
+
"deepObject": Object {
|
|
118
|
+
"data": Object {
|
|
119
|
+
"message": "deepObject.data is required",
|
|
120
|
+
"ref": undefined,
|
|
121
|
+
"type": "",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
"password": Object {
|
|
125
|
+
"message": "Password must be at least 5 chars",
|
|
126
|
+
"ref": Object {
|
|
127
|
+
"name": "password",
|
|
128
|
+
},
|
|
129
|
+
"type": "",
|
|
130
|
+
},
|
|
131
|
+
"username": Object {
|
|
132
|
+
"message": "Username is required",
|
|
133
|
+
"ref": Object {
|
|
134
|
+
"name": "username",
|
|
135
|
+
},
|
|
136
|
+
"type": "",
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
"values": Object {},
|
|
140
|
+
}
|
|
141
|
+
`;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { vestResolver } from '..';
|
|
2
|
+
import {
|
|
3
|
+
invalidData,
|
|
4
|
+
validationSuite,
|
|
5
|
+
validData,
|
|
6
|
+
fields,
|
|
7
|
+
} from './__fixtures__/data';
|
|
8
|
+
|
|
9
|
+
describe('vestResolver', () => {
|
|
10
|
+
it('should return values from vestResolver when validation pass', async () => {
|
|
11
|
+
expect(
|
|
12
|
+
await vestResolver(validationSuite)(validData, undefined, { fields }),
|
|
13
|
+
).toEqual({
|
|
14
|
+
values: validData,
|
|
15
|
+
errors: {},
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return values from vestResolver with `mode: sync` when validation pass', async () => {
|
|
20
|
+
expect(
|
|
21
|
+
await vestResolver(validationSuite, undefined, {
|
|
22
|
+
mode: 'sync',
|
|
23
|
+
})(validData, undefined, { fields }),
|
|
24
|
+
).toEqual({
|
|
25
|
+
values: validData,
|
|
26
|
+
errors: {},
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false', async () => {
|
|
31
|
+
expect(
|
|
32
|
+
await vestResolver(validationSuite)(invalidData, undefined, {
|
|
33
|
+
fields,
|
|
34
|
+
}),
|
|
35
|
+
).toMatchSnapshot();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false and `mode: sync`', async () => {
|
|
39
|
+
expect(
|
|
40
|
+
await vestResolver(validationSuite, undefined, {
|
|
41
|
+
mode: 'sync',
|
|
42
|
+
})(invalidData, undefined, { fields }),
|
|
43
|
+
).toMatchSnapshot();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true', async () => {
|
|
47
|
+
expect(
|
|
48
|
+
await vestResolver(validationSuite)(
|
|
49
|
+
invalidData,
|
|
50
|
+
{},
|
|
51
|
+
{ fields, criteriaMode: 'all' },
|
|
52
|
+
),
|
|
53
|
+
).toMatchSnapshot();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should return all the error messages from vestResolver when validation fails and validateAllFieldCriteria set to true and `mode: sync`', async () => {
|
|
57
|
+
expect(
|
|
58
|
+
await vestResolver(validationSuite, undefined, { mode: 'sync' })(
|
|
59
|
+
invalidData,
|
|
60
|
+
{},
|
|
61
|
+
{ fields, criteriaMode: 'all' },
|
|
62
|
+
),
|
|
63
|
+
).toMatchSnapshot();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './vest';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FieldValues,
|
|
3
|
+
ResolverOptions,
|
|
4
|
+
ResolverResult,
|
|
5
|
+
UnpackNestedValue,
|
|
6
|
+
} from 'react-hook-form';
|
|
7
|
+
import * as Vest from 'vest';
|
|
8
|
+
|
|
9
|
+
export type ICreateResult = ReturnType<typeof Vest.create>;
|
|
10
|
+
|
|
11
|
+
export type Resolver = (
|
|
12
|
+
schema: ICreateResult,
|
|
13
|
+
schemaOptions?: never,
|
|
14
|
+
factoryOptions?: { mode?: 'async' | 'sync' },
|
|
15
|
+
) => <TFieldValues extends FieldValues, TContext>(
|
|
16
|
+
values: UnpackNestedValue<TFieldValues>,
|
|
17
|
+
context: TContext | undefined,
|
|
18
|
+
options: ResolverOptions<TFieldValues>,
|
|
19
|
+
) => Promise<ResolverResult<TFieldValues>>;
|
|
20
|
+
|
|
21
|
+
export type VestErrors = Record<string, string[]>;
|
package/vest/src/vest.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { toNestError } from '@hookform/resolvers';
|
|
2
|
+
import { FieldError } from 'react-hook-form';
|
|
3
|
+
import promisify from 'vest/promisify';
|
|
4
|
+
import type { VestErrors, Resolver } from './types';
|
|
5
|
+
|
|
6
|
+
const parseErrorSchema = (
|
|
7
|
+
vestError: VestErrors,
|
|
8
|
+
validateAllFieldCriteria: boolean,
|
|
9
|
+
) => {
|
|
10
|
+
const errors: Record<string, FieldError> = {};
|
|
11
|
+
for (const path in vestError) {
|
|
12
|
+
if (!errors[path]) {
|
|
13
|
+
errors[path] = { message: vestError[path][0], type: '' };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (validateAllFieldCriteria) {
|
|
17
|
+
errors[path].types = vestError[path].reduce<Record<number, string>>(
|
|
18
|
+
(acc, message, index) => (acc[index] = message) && acc,
|
|
19
|
+
{},
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return errors;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const vestResolver: Resolver = (
|
|
27
|
+
schema,
|
|
28
|
+
_,
|
|
29
|
+
resolverOptions = {},
|
|
30
|
+
) => async (values, _context, options) => {
|
|
31
|
+
const result =
|
|
32
|
+
resolverOptions.mode === 'sync'
|
|
33
|
+
? schema(values)
|
|
34
|
+
: await promisify(schema)(values);
|
|
35
|
+
|
|
36
|
+
return result.hasErrors()
|
|
37
|
+
? {
|
|
38
|
+
values: {},
|
|
39
|
+
errors: toNestError(
|
|
40
|
+
parseErrorSchema(result.getErrors(), options.criteriaMode === 'all'),
|
|
41
|
+
options.fields,
|
|
42
|
+
),
|
|
43
|
+
}
|
|
44
|
+
: { values, errors: {} };
|
|
45
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FieldValues, ResolverOptions, ResolverResult, UnpackNestedValue } from 'react-hook-form';
|
|
2
|
+
import * as Yup from 'yup';
|
|
3
|
+
import type Lazy from 'yup/lib/Lazy';
|
|
4
|
+
declare type Options<T extends Yup.AnyObjectSchema | Lazy<any>> = Parameters<T['validate']>[1];
|
|
5
|
+
export declare type Resolver = <T extends Yup.AnyObjectSchema | Lazy<any>>(schema: T, schemaOptions?: Options<T>, factoryOptions?: {
|
|
6
|
+
mode?: 'async' | 'sync';
|
|
7
|
+
}) => <TFieldValues extends FieldValues, TContext>(values: UnpackNestedValue<TFieldValues>, context: TContext | undefined, options: ResolverOptions<TFieldValues>) => Promise<ResolverResult<TFieldValues>>;
|
|
8
|
+
export {};
|
package/yup/dist/yup.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=require("@hookform/resolvers"),r=require("react-hook-form");exports.yupResolver=function(t,o,n){return void 0===o&&(o={abortEarly:!1}),void 0===n&&(n={}),function(s,a,u){try{return Promise.resolve(function(e,r){try{var u=(o.context&&"development"===process.env.NODE_ENV&&console.warn("You should not used the yup options context. Please, use the 'useForm' context object instead"),Promise.resolve(t["sync"===n.mode?"validateSync":"validate"](s,Object.assign({},o,{context:a}))).then(function(e){return{values:e,errors:{}}}))}catch(e){return r(e)}return u&&u.then?u.then(void 0,r):u}(0,function(t){return{values:{},errors:e.toNestError((o=t,n="all"===u.criteriaMode,o.inner.reduce(function(e,t){return e[t.path]||(e[t.path]={message:t.message,type:t.type}),n&&(e[t.path]=r.appendErrors(t.path,n,e,t.type,t.message)),e},{})),u.fields)};var o,n}))}catch(e){return Promise.reject(e)}}};
|
|
2
|
+
//# sourceMappingURL=yup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yup.js","sources":["../src/yup.ts"],"sourcesContent":["import Yup from 'yup';\nimport { toNestError } from '@hookform/resolvers';\nimport { appendErrors, FieldError } from 'react-hook-form';\nimport { Resolver } from './types';\n\n/**\n * Why `path!` ? because it could be `undefined` in some case\n * https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\n */\nconst parseErrorSchema = (\n error: Yup.ValidationError,\n validateAllFieldCriteria: boolean,\n) => {\n return error.inner.reduce<Record<string, FieldError>>((previous, error) => {\n if (!previous[error.path!]) {\n previous[error.path!] = { message: error.message, type: error.type! };\n }\n\n if (validateAllFieldCriteria) {\n previous[error.path!] = appendErrors(\n error.path!,\n validateAllFieldCriteria,\n previous,\n error.type!,\n error.message,\n ) as FieldError;\n }\n\n return previous;\n }, {});\n};\n\nexport const yupResolver: Resolver = (\n schema,\n schemaOptions = {\n abortEarly: false,\n },\n resolverOptions = {},\n) => async (values, context, options) => {\n try {\n if (schemaOptions.context && process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn(\n \"You should not used the yup options context. Please, use the 'useForm' context object instead\",\n );\n }\n\n const result = await schema[\n resolverOptions.mode === 'sync' ? 'validateSync' : 'validate'\n ](values, Object.assign({}, schemaOptions, { context }));\n\n return {\n values: result,\n errors: {},\n };\n } catch (e) {\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(e, options.criteriaMode === 'all'),\n options.fields,\n ),\n };\n }\n};\n"],"names":["schema","schemaOptions","resolverOptions","abortEarly","values","context","options","process","env","NODE_ENV","console","warn","mode","Object","assign","result","errors","e","toNestError","error","validateAllFieldCriteria","criteriaMode","inner","reduce","previous","path","message","type","appendErrors","fields"],"mappings":"sFAgCqC,SACnCA,EACAC,EAGAC,mBAHAD,IAAAA,EAAgB,CACdE,YAAY,aAEdD,IAAAA,EAAkB,aACRE,EAAQC,EAASC,uDAErBL,EAAcI,SAAoC,gBAAzBE,QAAQC,IAAIC,UAEvCC,QAAQC,KACN,iHAIiBX,EACM,SAAzBE,EAAgBU,KAAkB,eAAiB,YACnDR,EAAQS,OAAOC,OAAO,GAAIb,EAAe,CAAEI,QAAAA,oBAFvCU,GAIN,MAAO,CACLX,OAAQW,EACRC,OAAQ,4EAEHC,GACP,MAAO,CACLb,OAAQ,GACRY,OAAQE,eAhDZC,EAiDuBF,EAhDvBG,EAgDmD,QAAzBd,EAAQe,aA9C3BF,EAAMG,MAAMC,OAAmC,SAACC,EAAUL,GAe/D,OAdKK,EAASL,EAAMM,QAClBD,EAASL,EAAMM,MAAS,CAAEC,QAASP,EAAMO,QAASC,KAAMR,EAAMQ,OAG5DP,IACFI,EAASL,EAAMM,MAASG,eACtBT,EAAMM,KACNL,EACAI,EACAL,EAAMQ,KACNR,EAAMO,UAIHF,GACN,KA+BGlB,EAAQuB,SAnDS,IACvBV,EACAC,KAqBmC"}
|
package/yup/dist/yup.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{toNestError as e}from"@hookform/resolvers";import{appendErrors as t}from"react-hook-form";var r=function(r,o,n){return void 0===o&&(o={abortEarly:!1}),void 0===n&&(n={}),function(s,a,c){try{return Promise.resolve(function(e,t){try{var c=(o.context&&"development"===process.env.NODE_ENV&&console.warn("You should not used the yup options context. Please, use the 'useForm' context object instead"),Promise.resolve(r["sync"===n.mode?"validateSync":"validate"](s,Object.assign({},o,{context:a}))).then(function(e){return{values:e,errors:{}}}))}catch(e){return t(e)}return c&&c.then?c.then(void 0,t):c}(0,function(r){return{values:{},errors:e((o=r,n="all"===c.criteriaMode,o.inner.reduce(function(e,r){return e[r.path]||(e[r.path]={message:r.message,type:r.type}),n&&(e[r.path]=t(r.path,n,e,r.type,r.message)),e},{})),c.fields)};var o,n}))}catch(e){return Promise.reject(e)}}};export{r as yupResolver};
|
|
2
|
+
//# sourceMappingURL=yup.module.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{toNestError as e}from"@hookform/resolvers";import{appendErrors as t}from"react-hook-form";const o=(o,r={abortEarly:!1},s={})=>async(a,n,c)=>{try{return r.context&&"development"===process.env.NODE_ENV&&console.warn("You should not used the yup options context. Please, use the 'useForm' context object instead"),{values:await o["sync"===s.mode?"validateSync":"validate"](a,Object.assign({},r,{context:n})),errors:{}}}catch(o){return{values:{},errors:e((p=o,l="all"===c.criteriaMode,p.inner.reduce((e,o)=>(e[o.path]||(e[o.path]={message:o.message,type:o.type}),l&&(e[o.path]=t(o.path,l,e,o.type,o.message)),e),{})),c.fields)}}var p,l};export{o as yupResolver};
|
|
2
|
+
//# sourceMappingURL=yup.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yup.modern.js","sources":["../src/yup.ts"],"sourcesContent":["import Yup from 'yup';\nimport { toNestError } from '@hookform/resolvers';\nimport { appendErrors, FieldError } from 'react-hook-form';\nimport { Resolver } from './types';\n\n/**\n * Why `path!` ? because it could be `undefined` in some case\n * https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\n */\nconst parseErrorSchema = (\n error: Yup.ValidationError,\n validateAllFieldCriteria: boolean,\n) => {\n return error.inner.reduce<Record<string, FieldError>>((previous, error) => {\n if (!previous[error.path!]) {\n previous[error.path!] = { message: error.message, type: error.type! };\n }\n\n if (validateAllFieldCriteria) {\n previous[error.path!] = appendErrors(\n error.path!,\n validateAllFieldCriteria,\n previous,\n error.type!,\n error.message,\n ) as FieldError;\n }\n\n return previous;\n }, {});\n};\n\nexport const yupResolver: Resolver = (\n schema,\n schemaOptions = {\n abortEarly: false,\n },\n resolverOptions = {},\n) => async (values, context, options) => {\n try {\n if (schemaOptions.context && process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn(\n \"You should not used the yup options context. Please, use the 'useForm' context object instead\",\n );\n }\n\n const result = await schema[\n resolverOptions.mode === 'sync' ? 'validateSync' : 'validate'\n ](values, Object.assign({}, schemaOptions, { context }));\n\n return {\n values: result,\n errors: {},\n };\n } catch (e) {\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(e, options.criteriaMode === 'all'),\n options.fields,\n ),\n };\n }\n};\n"],"names":["yupResolver","schema","schemaOptions","abortEarly","resolverOptions","async","values","context","options","process","env","NODE_ENV","console","warn","mode","Object","assign","errors","e","toNestError","error","validateAllFieldCriteria","criteriaMode","inner","reduce","previous","path","message","type","appendErrors","fields"],"mappings":"iGASA,MAuBaA,EAAwB,CACnCC,EACAC,EAAgB,CACdC,YAAY,GAEdC,EAAkB,KACfC,MAAOC,EAAQC,EAASC,KAC3B,IAYE,OAXIN,EAAcK,SAAoC,gBAAzBE,QAAQC,IAAIC,UAEvCC,QAAQC,KACN,iGAQG,CACLP,aALmBL,EACM,SAAzBG,EAAgBU,KAAkB,eAAiB,YACnDR,EAAQS,OAAOC,OAAO,GAAId,EAAe,CAAEK,QAAAA,KAI3CU,OAAQ,IAEV,MAAOC,GACP,MAAO,CACLZ,OAAQ,GACRW,OAAQE,GAhDZC,EAiDuBF,EAhDvBG,EAgDmD,QAAzBb,EAAQc,aA9C3BF,EAAMG,MAAMC,OAAmC,CAACC,EAAUL,KAC1DK,EAASL,EAAMM,QAClBD,EAASL,EAAMM,MAAS,CAAEC,QAASP,EAAMO,QAASC,KAAMR,EAAMQ,OAG5DP,IACFI,EAASL,EAAMM,MAASG,EACtBT,EAAMM,KACNL,EACAI,EACAL,EAAMQ,KACNR,EAAMO,UAIHF,GACN,KA+BGjB,EAAQsB,SAnDS,IACvBV,EACAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{toNestError as e}from"@hookform/resolvers";import{appendErrors as t}from"react-hook-form";var r=function(r,o,n){return void 0===o&&(o={abortEarly:!1}),void 0===n&&(n={}),function(s,a,c){try{return Promise.resolve(function(e,t){try{var c=(o.context&&"development"===process.env.NODE_ENV&&console.warn("You should not used the yup options context. Please, use the 'useForm' context object instead"),Promise.resolve(r["sync"===n.mode?"validateSync":"validate"](s,Object.assign({},o,{context:a}))).then(function(e){return{values:e,errors:{}}}))}catch(e){return t(e)}return c&&c.then?c.then(void 0,t):c}(0,function(r){return{values:{},errors:e((o=r,n="all"===c.criteriaMode,o.inner.reduce(function(e,r){return e[r.path]||(e[r.path]={message:r.message,type:r.type}),n&&(e[r.path]=t(r.path,n,e,r.type,r.message)),e},{})),c.fields)};var o,n}))}catch(e){return Promise.reject(e)}}};export{r as yupResolver};
|
|
2
|
+
//# sourceMappingURL=yup.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yup.module.js","sources":["../src/yup.ts"],"sourcesContent":["import Yup from 'yup';\nimport { toNestError } from '@hookform/resolvers';\nimport { appendErrors, FieldError } from 'react-hook-form';\nimport { Resolver } from './types';\n\n/**\n * Why `path!` ? because it could be `undefined` in some case\n * https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\n */\nconst parseErrorSchema = (\n error: Yup.ValidationError,\n validateAllFieldCriteria: boolean,\n) => {\n return error.inner.reduce<Record<string, FieldError>>((previous, error) => {\n if (!previous[error.path!]) {\n previous[error.path!] = { message: error.message, type: error.type! };\n }\n\n if (validateAllFieldCriteria) {\n previous[error.path!] = appendErrors(\n error.path!,\n validateAllFieldCriteria,\n previous,\n error.type!,\n error.message,\n ) as FieldError;\n }\n\n return previous;\n }, {});\n};\n\nexport const yupResolver: Resolver = (\n schema,\n schemaOptions = {\n abortEarly: false,\n },\n resolverOptions = {},\n) => async (values, context, options) => {\n try {\n if (schemaOptions.context && process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn(\n \"You should not used the yup options context. Please, use the 'useForm' context object instead\",\n );\n }\n\n const result = await schema[\n resolverOptions.mode === 'sync' ? 'validateSync' : 'validate'\n ](values, Object.assign({}, schemaOptions, { context }));\n\n return {\n values: result,\n errors: {},\n };\n } catch (e) {\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(e, options.criteriaMode === 'all'),\n options.fields,\n ),\n };\n }\n};\n"],"names":["yupResolver","schema","schemaOptions","resolverOptions","abortEarly","values","context","options","process","env","NODE_ENV","console","warn","mode","Object","assign","result","errors","e","toNestError","error","validateAllFieldCriteria","criteriaMode","inner","reduce","previous","path","message","type","appendErrors","fields"],"mappings":"iGASA,IAuBaA,EAAwB,SACnCC,EACAC,EAGAC,mBAHAD,IAAAA,EAAgB,CACdE,YAAY,aAEdD,IAAAA,EAAkB,aACRE,EAAQC,EAASC,uDAErBL,EAAcI,SAAoC,gBAAzBE,QAAQC,IAAIC,UAEvCC,QAAQC,KACN,iHAIiBX,EACM,SAAzBE,EAAgBU,KAAkB,eAAiB,YACnDR,EAAQS,OAAOC,OAAO,GAAIb,EAAe,CAAEI,QAAAA,oBAFvCU,GAIN,MAAO,CACLX,OAAQW,EACRC,OAAQ,4EAEHC,GACP,MAAO,CACLb,OAAQ,GACRY,OAAQE,GAhDZC,EAiDuBF,EAhDvBG,EAgDmD,QAAzBd,EAAQe,aA9C3BF,EAAMG,MAAMC,OAAmC,SAACC,EAAUL,GAe/D,OAdKK,EAASL,EAAMM,QAClBD,EAASL,EAAMM,MAAS,CAAEC,QAASP,EAAMO,QAASC,KAAMR,EAAMQ,OAG5DP,IACFI,EAASL,EAAMM,MAASG,EACtBT,EAAMM,KACNL,EACAI,EACAL,EAAMQ,KACNR,EAAMO,UAIHF,GACN,KA+BGlB,EAAQuB,SAnDS,IACvBV,EACAC,KAqBmC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("@hookform/resolvers"),require("react-hook-form")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers","react-hook-form"],o):o((e||self).hookformResolversYup={},e.hookformResolvers,e.reactHookForm)}(this,function(e,o,r){e.yupResolver=function(e,t,n){return void 0===t&&(t={abortEarly:!1}),void 0===n&&(n={}),function(s,i,u){try{return Promise.resolve(function(o,r){try{var u=(t.context&&"development"===process.env.NODE_ENV&&console.warn("You should not used the yup options context. Please, use the 'useForm' context object instead"),Promise.resolve(e["sync"===n.mode?"validateSync":"validate"](s,Object.assign({},t,{context:i}))).then(function(e){return{values:e,errors:{}}}))}catch(e){return r(e)}return u&&u.then?u.then(void 0,r):u}(0,function(e){return{values:{},errors:o.toNestError((t=e,n="all"===u.criteriaMode,t.inner.reduce(function(e,o){return e[o.path]||(e[o.path]={message:o.message,type:o.type}),n&&(e[o.path]=r.appendErrors(o.path,n,e,o.type,o.message)),e},{})),u.fields)};var t,n}))}catch(e){return Promise.reject(e)}}}});
|
|
2
|
+
//# sourceMappingURL=yup.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yup.umd.js","sources":["../src/yup.ts"],"sourcesContent":["import Yup from 'yup';\nimport { toNestError } from '@hookform/resolvers';\nimport { appendErrors, FieldError } from 'react-hook-form';\nimport { Resolver } from './types';\n\n/**\n * Why `path!` ? because it could be `undefined` in some case\n * https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\n */\nconst parseErrorSchema = (\n error: Yup.ValidationError,\n validateAllFieldCriteria: boolean,\n) => {\n return error.inner.reduce<Record<string, FieldError>>((previous, error) => {\n if (!previous[error.path!]) {\n previous[error.path!] = { message: error.message, type: error.type! };\n }\n\n if (validateAllFieldCriteria) {\n previous[error.path!] = appendErrors(\n error.path!,\n validateAllFieldCriteria,\n previous,\n error.type!,\n error.message,\n ) as FieldError;\n }\n\n return previous;\n }, {});\n};\n\nexport const yupResolver: Resolver = (\n schema,\n schemaOptions = {\n abortEarly: false,\n },\n resolverOptions = {},\n) => async (values, context, options) => {\n try {\n if (schemaOptions.context && process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn(\n \"You should not used the yup options context. Please, use the 'useForm' context object instead\",\n );\n }\n\n const result = await schema[\n resolverOptions.mode === 'sync' ? 'validateSync' : 'validate'\n ](values, Object.assign({}, schemaOptions, { context }));\n\n return {\n values: result,\n errors: {},\n };\n } catch (e) {\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(e, options.criteriaMode === 'all'),\n options.fields,\n ),\n };\n }\n};\n"],"names":["schema","schemaOptions","resolverOptions","abortEarly","values","context","options","process","env","NODE_ENV","console","warn","mode","Object","assign","result","errors","e","toNestError","error","validateAllFieldCriteria","criteriaMode","inner","reduce","previous","path","message","type","appendErrors","fields"],"mappings":"sYAgCqC,SACnCA,EACAC,EAGAC,mBAHAD,IAAAA,EAAgB,CACdE,YAAY,aAEdD,IAAAA,EAAkB,aACRE,EAAQC,EAASC,uDAErBL,EAAcI,SAAoC,gBAAzBE,QAAQC,IAAIC,UAEvCC,QAAQC,KACN,iHAIiBX,EACM,SAAzBE,EAAgBU,KAAkB,eAAiB,YACnDR,EAAQS,OAAOC,OAAO,GAAIb,EAAe,CAAEI,QAAAA,oBAFvCU,GAIN,MAAO,CACLX,OAAQW,EACRC,OAAQ,4EAEHC,GACP,MAAO,CACLb,OAAQ,GACRY,OAAQE,eAhDZC,EAiDuBF,EAhDvBG,EAgDmD,QAAzBd,EAAQe,aA9C3BF,EAAMG,MAAMC,OAAmC,SAACC,EAAUL,GAe/D,OAdKK,EAASL,EAAMM,QAClBD,EAASL,EAAMM,MAAS,CAAEC,QAASP,EAAMO,QAASC,KAAMR,EAAMQ,OAG5DP,IACFI,EAASL,EAAMM,MAASG,eACtBT,EAAMM,KACNL,EACAI,EACAL,EAAMQ,KACNR,EAAMO,UAIHF,GACN,KA+BGlB,EAAQuB,SAnDS,IACvBV,EACAC,KAqBmC"}
|
package/yup/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yup",
|
|
3
|
+
"amdName": "hookformResolversYup",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"description": "React Hook Form validation resolver: yup",
|
|
7
|
+
"main": "dist/yup.js",
|
|
8
|
+
"module": "dist/yup.module.js",
|
|
9
|
+
"umd:main": "dist/yup.umd.js",
|
|
10
|
+
"source": "src/index.ts",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"react-hook-form": ">=6.6.0",
|
|
15
|
+
"@hookform/resolvers": ">=2.0.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen, act } from '@testing-library/react';
|
|
3
|
+
import user from '@testing-library/user-event';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import * as Yup from 'yup';
|
|
6
|
+
import { yupResolver } from '..';
|
|
7
|
+
|
|
8
|
+
const schema = Yup.object({
|
|
9
|
+
username: Yup.string().required(),
|
|
10
|
+
password: Yup.string().required(),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
type FormData = Yup.InferType<typeof schema> & { unusedProperty: string };
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
onSubmit: (data: FormData) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function TestComponent({ onSubmit }: Props) {
|
|
20
|
+
const {
|
|
21
|
+
register,
|
|
22
|
+
formState: { errors },
|
|
23
|
+
handleSubmit,
|
|
24
|
+
} = useForm<FormData>({
|
|
25
|
+
resolver: yupResolver(schema), // Useful to check TypeScript regressions
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
30
|
+
<input {...register('username')} />
|
|
31
|
+
{errors.username && <span role="alert">{errors.username.message}</span>}
|
|
32
|
+
|
|
33
|
+
<input {...register('password')} />
|
|
34
|
+
{errors.password && <span role="alert">{errors.password.message}</span>}
|
|
35
|
+
|
|
36
|
+
<button type="submit">submit</button>
|
|
37
|
+
</form>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
test("form's validation with Yup and TypeScript's integration", async () => {
|
|
42
|
+
const handleSubmit = jest.fn();
|
|
43
|
+
render(<TestComponent onSubmit={handleSubmit} />);
|
|
44
|
+
|
|
45
|
+
expect(screen.queryAllByRole(/alert/i)).toHaveLength(0);
|
|
46
|
+
|
|
47
|
+
await act(async () => {
|
|
48
|
+
user.click(screen.getByText(/submit/i));
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(screen.getByText(/username is a required field/i)).toBeInTheDocument();
|
|
52
|
+
expect(screen.getByText(/password is a required field/i)).toBeInTheDocument();
|
|
53
|
+
expect(handleSubmit).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Field, InternalFieldName } from 'react-hook-form';
|
|
2
|
+
import * as yup from 'yup';
|
|
3
|
+
|
|
4
|
+
export const schema = yup.object({
|
|
5
|
+
username: yup.string().matches(/^\w+$/).min(3).max(30).required(),
|
|
6
|
+
password: yup
|
|
7
|
+
.string()
|
|
8
|
+
.matches(/^[a-zA-Z0-9]{3,30}/)
|
|
9
|
+
.required(),
|
|
10
|
+
repeatPassword: yup.ref('password'),
|
|
11
|
+
accessToken: yup.string(),
|
|
12
|
+
birthYear: yup.number().min(1900).max(2013),
|
|
13
|
+
email: yup.string().email(),
|
|
14
|
+
tags: yup.array(yup.string()),
|
|
15
|
+
enabled: yup.boolean(),
|
|
16
|
+
like: yup.array().of(
|
|
17
|
+
yup.object({
|
|
18
|
+
id: yup.number().required(),
|
|
19
|
+
name: yup.string().length(4).required(),
|
|
20
|
+
}),
|
|
21
|
+
),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const validData: yup.InferType<typeof schema> = {
|
|
25
|
+
username: 'Doe',
|
|
26
|
+
password: 'Password123',
|
|
27
|
+
repeatPassword: 'Password123',
|
|
28
|
+
birthYear: 2000,
|
|
29
|
+
email: 'john@doe.com',
|
|
30
|
+
tags: ['tag1', 'tag2'],
|
|
31
|
+
enabled: true,
|
|
32
|
+
accessToken: 'accessToken',
|
|
33
|
+
like: [
|
|
34
|
+
{
|
|
35
|
+
id: 1,
|
|
36
|
+
name: 'name',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const invalidData = {
|
|
42
|
+
password: '___',
|
|
43
|
+
email: '',
|
|
44
|
+
birthYear: 'birthYear',
|
|
45
|
+
like: [{ id: 'z' }],
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const fields: Record<InternalFieldName, Field['_f']> = {
|
|
49
|
+
username: {
|
|
50
|
+
ref: { name: 'username' },
|
|
51
|
+
name: 'username',
|
|
52
|
+
},
|
|
53
|
+
password: {
|
|
54
|
+
ref: { name: 'password' },
|
|
55
|
+
name: 'password',
|
|
56
|
+
},
|
|
57
|
+
email: {
|
|
58
|
+
ref: { name: 'email' },
|
|
59
|
+
name: 'email',
|
|
60
|
+
},
|
|
61
|
+
birthday: {
|
|
62
|
+
ref: { name: 'birthday' },
|
|
63
|
+
name: 'birthday',
|
|
64
|
+
},
|
|
65
|
+
};
|