@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.
- package/LICENSE +21 -0
- package/README.md +420 -0
- package/class-validator/dist/class-validator.d.ts +2 -0
- package/class-validator/dist/class-validator.js +2 -0
- package/class-validator/dist/class-validator.js.map +1 -0
- package/class-validator/dist/class-validator.mjs +2 -0
- package/class-validator/dist/class-validator.modern.js +2 -0
- package/class-validator/dist/class-validator.modern.js.map +1 -0
- package/class-validator/dist/class-validator.module.js +2 -0
- package/class-validator/dist/class-validator.module.js.map +1 -0
- package/class-validator/dist/class-validator.umd.js +2 -0
- package/class-validator/dist/class-validator.umd.js.map +1 -0
- package/class-validator/dist/index.d.ts +2 -0
- package/class-validator/dist/types.d.ts +8 -0
- package/class-validator/package.json +19 -0
- package/class-validator/src/__tests__/Form-native-validation.tsx +83 -0
- package/class-validator/src/__tests__/Form.tsx +55 -0
- package/class-validator/src/__tests__/__fixtures__/data.ts +88 -0
- package/class-validator/src/__tests__/__snapshots__/class-validator.ts.snap +207 -0
- package/class-validator/src/__tests__/class-validator.ts +87 -0
- package/class-validator/src/class-validator.ts +62 -0
- package/class-validator/src/index.ts +2 -0
- package/class-validator/src/types.ts +22 -0
- package/computed-types/dist/computed-types.d.ts +2 -0
- package/computed-types/dist/computed-types.js +2 -0
- package/computed-types/dist/computed-types.js.map +1 -0
- package/computed-types/dist/computed-types.mjs +2 -0
- package/computed-types/dist/computed-types.modern.js +2 -0
- package/computed-types/dist/computed-types.modern.js.map +1 -0
- package/computed-types/dist/computed-types.module.js +2 -0
- package/computed-types/dist/computed-types.module.js.map +1 -0
- package/computed-types/dist/computed-types.umd.js +2 -0
- package/computed-types/dist/computed-types.umd.js.map +1 -0
- package/computed-types/dist/index.d.ts +2 -0
- package/computed-types/dist/types.d.ts +2 -0
- package/computed-types/package.json +17 -0
- package/computed-types/src/__tests__/Form-native-validation.tsx +85 -0
- package/computed-types/src/__tests__/Form.tsx +54 -0
- package/computed-types/src/__tests__/__fixtures__/data.ts +72 -0
- package/computed-types/src/__tests__/__snapshots__/computed-types.ts.snap +55 -0
- package/computed-types/src/__tests__/computed-types.ts +24 -0
- package/computed-types/src/computed-types.ts +43 -0
- package/computed-types/src/index.ts +2 -0
- package/computed-types/src/types.ts +14 -0
- package/dist/index.d.ts +2 -0
- package/dist/resolvers.js +2 -0
- package/dist/resolvers.js.map +1 -0
- package/dist/resolvers.mjs +2 -0
- package/dist/resolvers.mjs.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/dist/validateFieldsNatively.d.ts +2 -0
- package/io-ts/dist/arrayToPath.d.ts +3 -0
- package/io-ts/dist/errorsToRecord.d.ts +5 -0
- package/io-ts/dist/index.d.ts +2 -0
- package/io-ts/dist/io-ts.d.ts +2 -0
- package/io-ts/dist/io-ts.js +2 -0
- package/io-ts/dist/io-ts.js.map +1 -0
- package/io-ts/dist/io-ts.mjs +2 -0
- package/io-ts/dist/io-ts.modern.js +2 -0
- package/io-ts/dist/io-ts.modern.js.map +1 -0
- package/io-ts/dist/io-ts.module.js +2 -0
- package/io-ts/dist/io-ts.module.js.map +1 -0
- package/io-ts/dist/io-ts.umd.js +2 -0
- package/io-ts/dist/io-ts.umd.js.map +1 -0
- package/io-ts/dist/types.d.ts +7 -0
- package/io-ts/package.json +19 -0
- package/io-ts/src/__tests__/Form-native-validation.tsx +89 -0
- package/io-ts/src/__tests__/Form.tsx +65 -0
- package/io-ts/src/__tests__/__fixtures__/data.ts +129 -0
- package/io-ts/src/__tests__/__snapshots__/io-ts.ts.snap +89 -0
- package/io-ts/src/__tests__/io-ts.ts +37 -0
- package/io-ts/src/arrayToPath.ts +18 -0
- package/io-ts/src/errorsToRecord.ts +131 -0
- package/io-ts/src/index.ts +2 -0
- package/io-ts/src/io-ts.ts +33 -0
- package/io-ts/src/types.ts +23 -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-native-validation.tsx +89 -0
- package/joi/src/__tests__/Form.tsx +61 -0
- package/joi/src/__tests__/__fixtures__/data.ts +85 -0
- package/joi/src/__tests__/__snapshots__/joi.ts.snap +293 -0
- package/joi/src/__tests__/joi.ts +98 -0
- package/joi/src/index.ts +2 -0
- package/joi/src/joi.ts +81 -0
- package/joi/src/types.ts +16 -0
- package/nope/dist/index.d.ts +2 -0
- package/nope/dist/nope.d.ts +2 -0
- package/nope/dist/nope.js +2 -0
- package/nope/dist/nope.js.map +1 -0
- package/nope/dist/nope.mjs +2 -0
- package/nope/dist/nope.modern.js +2 -0
- package/nope/dist/nope.modern.js.map +1 -0
- package/nope/dist/nope.module.js +2 -0
- package/nope/dist/nope.module.js.map +1 -0
- package/nope/dist/nope.umd.js +2 -0
- package/nope/dist/nope.umd.js.map +1 -0
- package/nope/dist/types.d.ts +6 -0
- package/nope/package.json +18 -0
- package/nope/src/__tests__/Form-native-validation.tsx +89 -0
- package/nope/src/__tests__/Form.tsx +57 -0
- package/nope/src/__tests__/__fixtures__/data.ts +70 -0
- package/nope/src/__tests__/__snapshots__/nope.ts.snap +43 -0
- package/nope/src/__tests__/nope.ts +28 -0
- package/nope/src/index.ts +2 -0
- package/nope/src/nope.ts +46 -0
- package/nope/src/types.ts +22 -0
- package/package.json +216 -0
- 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-native-validation.tsx +86 -0
- package/superstruct/src/__tests__/Form.tsx +62 -0
- package/superstruct/src/__tests__/__fixtures__/data.ts +75 -0
- package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +64 -0
- package/superstruct/src/__tests__/superstruct.ts +24 -0
- package/superstruct/src/index.ts +2 -0
- package/superstruct/src/superstruct.ts +37 -0
- package/superstruct/src/types.ts +17 -0
- package/typanion/dist/index.d.ts +2 -0
- package/typanion/dist/typanion.d.ts +2 -0
- package/typanion/dist/typanion.js +2 -0
- package/typanion/dist/typanion.js.map +1 -0
- package/typanion/dist/typanion.mjs +2 -0
- package/typanion/dist/typanion.modern.js +2 -0
- package/typanion/dist/typanion.modern.js.map +1 -0
- package/typanion/dist/typanion.module.js +2 -0
- package/typanion/dist/typanion.module.js.map +1 -0
- package/typanion/dist/typanion.umd.js +2 -0
- package/typanion/dist/typanion.umd.js.map +1 -0
- package/typanion/dist/types.d.ts +6 -0
- package/typanion/package.json +18 -0
- package/typanion/src/__tests__/Form-native-validation.tsx +89 -0
- package/typanion/src/__tests__/Form.tsx +61 -0
- package/typanion/src/__tests__/__fixtures__/data.ts +77 -0
- package/typanion/src/__tests__/__snapshots__/typanion.ts.snap +67 -0
- package/typanion/src/__tests__/typanion.ts +31 -0
- package/typanion/src/index.ts +2 -0
- package/typanion/src/typanion.ts +44 -0
- package/typanion/src/types.ts +28 -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-native-validation.tsx +93 -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 +71 -0
- package/vest/src/index.ts +1 -0
- package/vest/src/types.ts +20 -0
- package/vest/src/vest.ts +51 -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-native-validation.tsx +85 -0
- package/yup/src/__tests__/Form.tsx +54 -0
- package/yup/src/__tests__/__fixtures__/data.ts +72 -0
- package/yup/src/__tests__/__snapshots__/yup.ts.snap +231 -0
- package/yup/src/__tests__/yup.ts +174 -0
- package/yup/src/index.ts +2 -0
- package/yup/src/types.ts +21 -0
- package/yup/src/yup.ts +75 -0
- package/zod/dist/index.d.ts +2 -0
- package/zod/dist/types.d.ts +5 -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-native-validation.tsx +85 -0
- package/zod/src/__tests__/Form.tsx +54 -0
- package/zod/src/__tests__/__fixtures__/data.ts +81 -0
- package/zod/src/__tests__/__snapshots__/zod.ts.snap +377 -0
- package/zod/src/__tests__/zod.ts +77 -0
- package/zod/src/index.ts +2 -0
- package/zod/src/types.ts +16 -0
- package/zod/src/zod.ts +85 -0
|
@@ -0,0 +1,85 @@
|
|
|
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 Schema, { Type, string } from 'computed-types';
|
|
6
|
+
import { computedTypesResolver } from '..';
|
|
7
|
+
|
|
8
|
+
const USERNAME_REQUIRED_MESSAGE = 'username field is required';
|
|
9
|
+
const PASSWORD_REQUIRED_MESSAGE = 'password field is required';
|
|
10
|
+
|
|
11
|
+
const schema = Schema({
|
|
12
|
+
username: string.min(2).error(USERNAME_REQUIRED_MESSAGE),
|
|
13
|
+
password: string.min(2).error(PASSWORD_REQUIRED_MESSAGE),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
type FormData = Type<typeof schema> & { unusedProperty: string };
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
onSubmit: (data: FormData) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function TestComponent({ onSubmit }: Props) {
|
|
23
|
+
const { register, handleSubmit } = useForm<FormData>({
|
|
24
|
+
resolver: computedTypesResolver(schema),
|
|
25
|
+
shouldUseNativeValidation: true,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
30
|
+
<input {...register('username')} placeholder="username" />
|
|
31
|
+
|
|
32
|
+
<input {...register('password')} placeholder="password" />
|
|
33
|
+
|
|
34
|
+
<button type="submit">submit</button>
|
|
35
|
+
</form>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
test("form's native validation with computed-types", async () => {
|
|
40
|
+
const handleSubmit = jest.fn();
|
|
41
|
+
render(<TestComponent onSubmit={handleSubmit} />);
|
|
42
|
+
|
|
43
|
+
// username
|
|
44
|
+
let usernameField = screen.getByPlaceholderText(
|
|
45
|
+
/username/i,
|
|
46
|
+
) as HTMLInputElement;
|
|
47
|
+
expect(usernameField.validity.valid).toBe(true);
|
|
48
|
+
expect(usernameField.validationMessage).toBe('');
|
|
49
|
+
|
|
50
|
+
// password
|
|
51
|
+
let passwordField = screen.getByPlaceholderText(
|
|
52
|
+
/password/i,
|
|
53
|
+
) as HTMLInputElement;
|
|
54
|
+
expect(passwordField.validity.valid).toBe(true);
|
|
55
|
+
expect(passwordField.validationMessage).toBe('');
|
|
56
|
+
|
|
57
|
+
await act(async () => {
|
|
58
|
+
user.click(screen.getByText(/submit/i));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// username
|
|
62
|
+
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
63
|
+
expect(usernameField.validity.valid).toBe(false);
|
|
64
|
+
expect(usernameField.validationMessage).toBe(USERNAME_REQUIRED_MESSAGE);
|
|
65
|
+
|
|
66
|
+
// password
|
|
67
|
+
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
68
|
+
expect(passwordField.validity.valid).toBe(false);
|
|
69
|
+
expect(passwordField.validationMessage).toBe(PASSWORD_REQUIRED_MESSAGE);
|
|
70
|
+
|
|
71
|
+
await act(async () => {
|
|
72
|
+
user.type(screen.getByPlaceholderText(/username/i), 'joe');
|
|
73
|
+
user.type(screen.getByPlaceholderText(/password/i), 'password');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// username
|
|
77
|
+
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
78
|
+
expect(usernameField.validity.valid).toBe(true);
|
|
79
|
+
expect(usernameField.validationMessage).toBe('');
|
|
80
|
+
|
|
81
|
+
// password
|
|
82
|
+
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
83
|
+
expect(passwordField.validity.valid).toBe(true);
|
|
84
|
+
expect(passwordField.validationMessage).toBe('');
|
|
85
|
+
});
|
|
@@ -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 Schema, { Type, string } from 'computed-types';
|
|
6
|
+
import { computedTypesResolver } from '..';
|
|
7
|
+
|
|
8
|
+
const schema = Schema({
|
|
9
|
+
username: string.min(2).error('username field is required'),
|
|
10
|
+
password: string.min(2).error('password field is required'),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
type FormData = Type<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
|
+
handleSubmit,
|
|
23
|
+
formState: { errors },
|
|
24
|
+
} = useForm<FormData>({
|
|
25
|
+
resolver: computedTypesResolver(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 computed-types 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 field is required/i)).toBeInTheDocument();
|
|
52
|
+
expect(screen.getByText(/password field is required/i)).toBeInTheDocument();
|
|
53
|
+
expect(handleSubmit).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Field, InternalFieldName } from 'react-hook-form';
|
|
2
|
+
import Schema, { Type, string, number, array, boolean } from 'computed-types';
|
|
3
|
+
|
|
4
|
+
export const schema = Schema({
|
|
5
|
+
username: string.regexp(/^\w+$/).min(3).max(30),
|
|
6
|
+
password: string
|
|
7
|
+
.regexp(new RegExp('.*[A-Z].*'), 'One uppercase character')
|
|
8
|
+
.regexp(new RegExp('.*[a-z].*'), 'One lowercase character')
|
|
9
|
+
.regexp(new RegExp('.*\\d.*'), 'One number')
|
|
10
|
+
.regexp(
|
|
11
|
+
new RegExp('.*[`~<>?,./!@#$%^&*()\\-_+="\'|{}\\[\\];:\\\\].*'),
|
|
12
|
+
'One special character',
|
|
13
|
+
)
|
|
14
|
+
.min(8, 'Must be at least 8 characters in length'),
|
|
15
|
+
repeatPassword: string,
|
|
16
|
+
accessToken: Schema.either(string, number).optional(),
|
|
17
|
+
birthYear: number.min(1900).max(2013).optional(),
|
|
18
|
+
email: string
|
|
19
|
+
.regexp(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/)
|
|
20
|
+
.error('Incorrect email'),
|
|
21
|
+
tags: array.of(string),
|
|
22
|
+
enabled: boolean,
|
|
23
|
+
like: array
|
|
24
|
+
.of({
|
|
25
|
+
id: number,
|
|
26
|
+
name: string.min(4).max(4),
|
|
27
|
+
})
|
|
28
|
+
.optional(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const validData: Type<typeof schema> = {
|
|
32
|
+
username: 'Doe',
|
|
33
|
+
password: 'Password123_',
|
|
34
|
+
repeatPassword: 'Password123_',
|
|
35
|
+
accessToken: 'accessToken',
|
|
36
|
+
birthYear: 2000,
|
|
37
|
+
email: 'john@doe.com',
|
|
38
|
+
tags: ['tag1', 'tag2'],
|
|
39
|
+
enabled: true,
|
|
40
|
+
like: [
|
|
41
|
+
{
|
|
42
|
+
id: 1,
|
|
43
|
+
name: 'name',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const invalidData = {
|
|
49
|
+
password: '___',
|
|
50
|
+
email: '',
|
|
51
|
+
birthYear: 'birthYear',
|
|
52
|
+
like: [{ id: 'z' }],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const fields: Record<InternalFieldName, Field['_f']> = {
|
|
56
|
+
username: {
|
|
57
|
+
ref: { name: 'username' },
|
|
58
|
+
name: 'username',
|
|
59
|
+
},
|
|
60
|
+
password: {
|
|
61
|
+
ref: { name: 'password' },
|
|
62
|
+
name: 'password',
|
|
63
|
+
},
|
|
64
|
+
email: {
|
|
65
|
+
ref: { name: 'email' },
|
|
66
|
+
name: 'email',
|
|
67
|
+
},
|
|
68
|
+
birthday: {
|
|
69
|
+
ref: { name: 'birthday' },
|
|
70
|
+
name: 'birthday',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`computedTypesResolver should return a single error from computedTypesResolver when validation fails 1`] = `
|
|
4
|
+
Object {
|
|
5
|
+
"errors": Object {
|
|
6
|
+
"birthYear": Object {
|
|
7
|
+
"message": "Expect value to be \\"number\\"",
|
|
8
|
+
"ref": undefined,
|
|
9
|
+
"type": "ValidationError",
|
|
10
|
+
},
|
|
11
|
+
"email": Object {
|
|
12
|
+
"message": "Incorrect email",
|
|
13
|
+
"ref": Object {
|
|
14
|
+
"name": "email",
|
|
15
|
+
},
|
|
16
|
+
"type": "ValidationError",
|
|
17
|
+
},
|
|
18
|
+
"enabled": Object {
|
|
19
|
+
"message": "Expect value to be \\"boolean\\"",
|
|
20
|
+
"ref": undefined,
|
|
21
|
+
"type": "ValidationError",
|
|
22
|
+
},
|
|
23
|
+
"like": Object {
|
|
24
|
+
"message": "Expect value to be \\"string\\"",
|
|
25
|
+
"ref": undefined,
|
|
26
|
+
"type": "ValidationError",
|
|
27
|
+
},
|
|
28
|
+
"password": Object {
|
|
29
|
+
"message": "One uppercase character",
|
|
30
|
+
"ref": Object {
|
|
31
|
+
"name": "password",
|
|
32
|
+
},
|
|
33
|
+
"type": "ValidationError",
|
|
34
|
+
},
|
|
35
|
+
"repeatPassword": Object {
|
|
36
|
+
"message": "Expect value to be \\"string\\"",
|
|
37
|
+
"ref": undefined,
|
|
38
|
+
"type": "ValidationError",
|
|
39
|
+
},
|
|
40
|
+
"tags": Object {
|
|
41
|
+
"message": "Expecting value to be an array",
|
|
42
|
+
"ref": undefined,
|
|
43
|
+
"type": "ValidationError",
|
|
44
|
+
},
|
|
45
|
+
"username": Object {
|
|
46
|
+
"message": "Expect value to be \\"string\\"",
|
|
47
|
+
"ref": Object {
|
|
48
|
+
"name": "username",
|
|
49
|
+
},
|
|
50
|
+
"type": "ValidationError",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
"values": Object {},
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { computedTypesResolver } from '..';
|
|
2
|
+
import { schema, validData, invalidData, fields } from './__fixtures__/data';
|
|
3
|
+
|
|
4
|
+
const shouldUseNativeValidation = false;
|
|
5
|
+
|
|
6
|
+
describe('computedTypesResolver', () => {
|
|
7
|
+
it('should return values from computedTypesResolver when validation pass', async () => {
|
|
8
|
+
const result = await computedTypesResolver(schema)(validData, undefined, {
|
|
9
|
+
fields,
|
|
10
|
+
shouldUseNativeValidation,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return a single error from computedTypesResolver when validation fails', async () => {
|
|
17
|
+
const result = await computedTypesResolver(schema)(invalidData, undefined, {
|
|
18
|
+
fields,
|
|
19
|
+
shouldUseNativeValidation,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
expect(result).toMatchSnapshot();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FieldErrors } from 'react-hook-form';
|
|
2
|
+
import { toNestError, validateFieldsNatively } from '@hookform/resolvers';
|
|
3
|
+
import type { ValidationError } from 'computed-types';
|
|
4
|
+
import type { Resolver } from './types';
|
|
5
|
+
|
|
6
|
+
const parseErrorSchema = (
|
|
7
|
+
computedTypesError: ValidationError,
|
|
8
|
+
parsedErrors: FieldErrors = {},
|
|
9
|
+
path = '',
|
|
10
|
+
) => {
|
|
11
|
+
return (computedTypesError.errors || []).reduce((acc, error) => {
|
|
12
|
+
const _currentPath = String(error.path[0]);
|
|
13
|
+
const _path = path ? `${path}.${_currentPath}` : _currentPath;
|
|
14
|
+
|
|
15
|
+
acc[_path] = {
|
|
16
|
+
type: error.error.name,
|
|
17
|
+
message: error.error.message,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
parseErrorSchema(error.error, acc, _path);
|
|
21
|
+
|
|
22
|
+
return acc;
|
|
23
|
+
}, parsedErrors);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const computedTypesResolver: Resolver =
|
|
27
|
+
(schema) => async (values, _, options) => {
|
|
28
|
+
try {
|
|
29
|
+
const data = await schema(values);
|
|
30
|
+
|
|
31
|
+
options.shouldUseNativeValidation && validateFieldsNatively({}, options);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
errors: {},
|
|
35
|
+
values: data,
|
|
36
|
+
};
|
|
37
|
+
} catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
values: {},
|
|
40
|
+
errors: toNestError(parseErrorSchema(error), options),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FieldValues,
|
|
3
|
+
ResolverResult,
|
|
4
|
+
UnpackNestedValue,
|
|
5
|
+
ResolverOptions,
|
|
6
|
+
} from 'react-hook-form';
|
|
7
|
+
|
|
8
|
+
export type Resolver = (
|
|
9
|
+
schema: any,
|
|
10
|
+
) => <TFieldValues extends FieldValues, TContext>(
|
|
11
|
+
values: UnpackNestedValue<TFieldValues>,
|
|
12
|
+
context: TContext | undefined,
|
|
13
|
+
options: ResolverOptions<TFieldValues>,
|
|
14
|
+
) => Promise<ResolverResult<TFieldValues>>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=require("react-hook-form"),r=function(r,i){for(var t in i.fields){var a=i.fields[t];if(a&&a.ref&&"reportValidity"in a.ref){var o=e.get(r,t);a.ref.setCustomValidity(o&&o.message||""),a.ref.reportValidity()}}};exports.toNestError=function(i,t){t.shouldUseNativeValidation&&r(i,t);var a={};for(var o in i){var s=e.get(t.fields,o);e.set(a,o,Object.assign(i[o],{ref:s&&s.ref}))}return a},exports.validateFieldsNatively=r;
|
|
2
|
+
//# sourceMappingURL=resolvers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.js","sources":["../src/validateFieldsNatively.ts","../src/toNestError.ts"],"sourcesContent":["import { get, FieldError, ResolverOptions } from 'react-hook-form';\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n\n if (field && field.ref && 'reportValidity' in field.ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n\n field.ref.setCustomValidity((error && error.message) || '');\n\n field.ref.reportValidity();\n }\n }\n};\n","import {\n set,\n get,\n FieldError,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestError = <TFieldValues extends FieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n\n set(\n fieldErrors,\n path,\n Object.assign(errors[path], { ref: field && field.ref }),\n );\n }\n\n return fieldErrors;\n};\n"],"names":["validateFieldsNatively","errors","options","fieldPath","fields","field","ref","error","get","setCustomValidity","message","reportValidity","shouldUseNativeValidation","fieldErrors","path","set","Object","assign"],"mappings":"iCAGaA,EAAyB,SACpCC,EACAC,GAEA,IAAK,IAAMC,KAAaD,EAAQE,OAAQ,CACtC,IAAMC,EAAQH,EAAQE,OAAOD,GAE7B,GAAIE,GAASA,EAAMC,KAAO,mBAAoBD,EAAMC,IAAK,CACvD,IAAMC,EAAQC,MAAIP,EAAQE,GAE1BE,EAAMC,IAAIG,kBAAmBF,GAASA,EAAMG,SAAY,IAExDL,EAAMC,IAAIK,wCCJW,SACzBV,EACAC,GAEAA,EAAQU,2BAA6BZ,EAAuBC,EAAQC,GAEpE,IAAMW,EAAc,GACpB,IAAK,IAAMC,KAAQb,EAAQ,CACzB,IAAMI,EAAQG,MAAIN,EAAQE,OAAQU,GAElCC,MACEF,EACAC,EACAE,OAAOC,OAAOhB,EAAOa,GAAO,CAAER,IAAKD,GAASA,EAAMC,OAItD,OAAOO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{get as r,set as e}from"react-hook-form";var i=function(e,i){for(var a in i.fields){var f=i.fields[a];if(f&&f.ref&&"reportValidity"in f.ref){var t=r(e,a);f.ref.setCustomValidity(t&&t.message||""),f.ref.reportValidity()}}},a=function(a,f){f.shouldUseNativeValidation&&i(a,f);var t={};for(var o in a){var s=r(f.fields,o);e(t,o,Object.assign(a[o],{ref:s&&s.ref}))}return t};export{a as toNestError,i as validateFieldsNatively};
|
|
2
|
+
//# sourceMappingURL=resolvers.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.mjs","sources":["../src/validateFieldsNatively.ts","../src/toNestError.ts"],"sourcesContent":["import { get, FieldError, ResolverOptions } from 'react-hook-form';\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n\n if (field && field.ref && 'reportValidity' in field.ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n\n field.ref.setCustomValidity((error && error.message) || '');\n\n field.ref.reportValidity();\n }\n }\n};\n","import {\n set,\n get,\n FieldError,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestError = <TFieldValues extends FieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n\n set(\n fieldErrors,\n path,\n Object.assign(errors[path], { ref: field && field.ref }),\n );\n }\n\n return fieldErrors;\n};\n"],"names":["validateFieldsNatively","errors","options","fieldPath","fields","field","ref","error","get","setCustomValidity","message","reportValidity","toNestError","shouldUseNativeValidation","fieldErrors","path","set","Object","assign"],"mappings":"+CAGaA,MAAAA,EAAyB,CACpCC,EACAC,KAEA,IAAK,MAAMC,KAAaD,EAAQE,OAAQ,CACtC,MAAMC,EAAQH,EAAQE,OAAOD,GAE7B,GAAIE,GAASA,EAAMC,KAAO,mBAAoBD,EAAMC,IAAK,CACvD,MAAMC,EAAQC,EAAIP,EAAQE,GAE1BE,EAAMC,IAAIG,kBAAmBF,GAASA,EAAMG,SAAY,IAExDL,EAAMC,IAAIK,oBCJHC,EAAc,CACzBX,EACAC,KAEAA,EAAQW,2BAA6Bb,EAAuBC,EAAQC,GAEpE,MAAMY,EAAc,GACpB,IAAK,MAAMC,KAAQd,EAAQ,CACzB,MAAMI,EAAQG,EAAIN,EAAQE,OAAQW,GAElCC,EACEF,EACAC,EACAE,OAAOC,OAAOjB,EAAOc,GAAO,CAAET,IAAKD,GAASA,EAAMC,OAItD,OAAOQ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{get as r,set as e}from"react-hook-form";var i=function(e,i){for(var a in i.fields){var f=i.fields[a];if(f&&f.ref&&"reportValidity"in f.ref){var t=r(e,a);f.ref.setCustomValidity(t&&t.message||""),f.ref.reportValidity()}}},a=function(a,f){f.shouldUseNativeValidation&&i(a,f);var t={};for(var o in a){var s=r(f.fields,o);e(t,o,Object.assign(a[o],{ref:s&&s.ref}))}return t};export{a as toNestError,i as validateFieldsNatively};
|
|
2
|
+
//# sourceMappingURL=resolvers.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.module.js","sources":["../src/validateFieldsNatively.ts","../src/toNestError.ts"],"sourcesContent":["import { get, FieldError, ResolverOptions } from 'react-hook-form';\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n\n if (field && field.ref && 'reportValidity' in field.ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n\n field.ref.setCustomValidity((error && error.message) || '');\n\n field.ref.reportValidity();\n }\n }\n};\n","import {\n set,\n get,\n FieldError,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestError = <TFieldValues extends FieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n\n set(\n fieldErrors,\n path,\n Object.assign(errors[path], { ref: field && field.ref }),\n );\n }\n\n return fieldErrors;\n};\n"],"names":["validateFieldsNatively","errors","options","fieldPath","fields","field","ref","error","get","setCustomValidity","message","reportValidity","toNestError","shouldUseNativeValidation","fieldErrors","path","set","Object","assign"],"mappings":"+CAGaA,IAAAA,EAAyB,SACpCC,EACAC,GAEA,IAAK,IAAMC,KAAaD,EAAQE,OAAQ,CACtC,IAAMC,EAAQH,EAAQE,OAAOD,GAE7B,GAAIE,GAASA,EAAMC,KAAO,mBAAoBD,EAAMC,IAAK,CACvD,IAAMC,EAAQC,EAAIP,EAAQE,GAE1BE,EAAMC,IAAIG,kBAAmBF,GAASA,EAAMG,SAAY,IAExDL,EAAMC,IAAIK,oBCJHC,EAAc,SACzBX,EACAC,GAEAA,EAAQW,2BAA6Bb,EAAuBC,EAAQC,GAEpE,IAAMY,EAAc,GACpB,IAAK,IAAMC,KAAQd,EAAQ,CACzB,IAAMI,EAAQG,EAAIN,EAAQE,OAAQW,GAElCC,EACEF,EACAC,EACAE,OAAOC,OAAOjB,EAAOc,GAAO,CAAET,IAAKD,GAASA,EAAMC,OAItD,OAAOQ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("react-hook-form")):"function"==typeof define&&define.amd?define(["exports","react-hook-form"],o):o((e||self).hookformResolvers={},e.reactHookForm)}(this,function(e,o){var r=function(e,r){for(var t in r.fields){var i=r.fields[t];if(i&&i.ref&&"reportValidity"in i.ref){var f=o.get(e,t);i.ref.setCustomValidity(f&&f.message||""),i.ref.reportValidity()}}};e.toNestError=function(e,t){t.shouldUseNativeValidation&&r(e,t);var i={};for(var f in e){var a=o.get(t.fields,f);o.set(i,f,Object.assign(e[f],{ref:a&&a.ref}))}return i},e.validateFieldsNatively=r});
|
|
2
|
+
//# sourceMappingURL=resolvers.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.umd.js","sources":["../src/validateFieldsNatively.ts","../src/toNestError.ts"],"sourcesContent":["import { get, FieldError, ResolverOptions } from 'react-hook-form';\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n\n if (field && field.ref && 'reportValidity' in field.ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n\n field.ref.setCustomValidity((error && error.message) || '');\n\n field.ref.reportValidity();\n }\n }\n};\n","import {\n set,\n get,\n FieldError,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestError = <TFieldValues extends FieldValues>(\n errors: Record<string, FieldError>,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n\n set(\n fieldErrors,\n path,\n Object.assign(errors[path], { ref: field && field.ref }),\n );\n }\n\n return fieldErrors;\n};\n"],"names":["validateFieldsNatively","errors","options","fieldPath","fields","field","ref","error","get","setCustomValidity","message","reportValidity","shouldUseNativeValidation","fieldErrors","path","set","Object","assign"],"mappings":"8SAGaA,EAAyB,SACpCC,EACAC,GAEA,IAAK,IAAMC,KAAaD,EAAQE,OAAQ,CACtC,IAAMC,EAAQH,EAAQE,OAAOD,GAE7B,GAAIE,GAASA,EAAMC,KAAO,mBAAoBD,EAAMC,IAAK,CACvD,IAAMC,EAAQC,MAAIP,EAAQE,GAE1BE,EAAMC,IAAIG,kBAAmBF,GAASA,EAAMG,SAAY,IAExDL,EAAMC,IAAIK,kCCJW,SACzBV,EACAC,GAEAA,EAAQU,2BAA6BZ,EAAuBC,EAAQC,GAEpE,IAAMW,EAAc,GACpB,IAAK,IAAMC,KAAQb,EAAQ,CACzB,IAAMI,EAAQG,MAAIN,EAAQE,OAAQU,GAElCC,MACEF,EACAC,EACAE,OAAOC,OAAOhB,EAAOa,GAAO,CAAER,IAAKD,GAASA,EAAMC,OAItD,OAAOO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { FieldError, FieldErrors, ResolverOptions, FieldValues } from 'react-hook-form';
|
|
2
|
+
export declare const toNestError: <TFieldValues extends FieldValues>(errors: Record<string, FieldError>, options: ResolverOptions<TFieldValues>) => import("react-hook-form").DeepMap<import("react-hook-form").DeepPartial<TFieldValues>, FieldError>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ValidationError } from 'io-ts';
|
|
2
|
+
import * as ReadonlyArray from 'fp-ts/ReadonlyArray';
|
|
3
|
+
import { ErrorObject } from './types';
|
|
4
|
+
declare const errorsToRecord: (validateAllFieldCriteria: boolean) => (validationErrors: ReadonlyArray<ValidationError>) => ErrorObject;
|
|
5
|
+
export default errorsToRecord;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=require("fp-ts/lib/Either"),t=require("fp-ts/function"),r=require("@hookform/resolvers"),n=require("io-ts"),i=require("fp-ts/ReadonlyArray"),o=require("fp-ts/Option"),u=require("fp-ts/Either"),a=require("fp-ts/Semigroup"),f=require("fp-ts/ReadonlyRecord");function p(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,t}var c=p(e),s=p(i),l=p(o),d=p(u),y=p(a),m=p(f);function v(){return(v=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var g=function(e){return e.reduce(function(e,r,n){return t.pipe(r,d.fold(function(e){return(n>0?".":"")+e},function(e){return"["+e+"]"}),function(t){return""+e+t})},"")},b=["path"],O=function(e){var r,i=t.pipe(r=e.context,s.filterMapWithIndex(function(e,t){var i=e-1;return void 0===r[i]||r[i].type instanceof n.TaggedUnionType||r[i].type instanceof n.UnionType||r[i].type instanceof n.IntersectionType?l.none:l.some(t)}),s.map(function(e){return e.key}),s.map(function(e){return t.pipe(e,function(e){return parseInt(e,10)},d.fromPredicate(t.not(Number.isNaN),function(){return e}))}),s.toArray,g);return{message:t.pipe(e.message,d.fromNullable(e.context),d.mapLeft(t.flow(s.last,l.map(function(e){return"expected "+e.type.name+" but got "+JSON.stringify(e.actual)}),l.getOrElseW(function(){return t.absurd("Error context is missing name")}))),d.getOrElseW(t.identity)),type:t.pipe(e.context,s.last,l.map(function(e){return e.type.name}),l.getOrElse(function(){return"unknown"})),path:i}},h=function(e){return t.pipe(e,s.map(function(e){var t;return(t={})[e.path]={type:e.type,message:e.message},t}),function(e){return y.fold({concat:function(e,t){return Object.assign({},t,e)}})({},e)})},q={concat:function(e,t){var r;return v({},t,{types:v({},e.types,(r={},r[e.type]=e.message,r[t.type]=t.message,r))})}},N=function(e){return t.pipe(m.fromFoldableMap(q,s.Foldable)(e,function(e){return[e.path,e]}),m.map(function(e){return function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t.indexOf(r=o[n])>=0||(i[r]=e[r]);return i}(e,b)}))};exports.ioTsResolver=function(e){return function(n,i,o){return t.pipe(n,e.decode,c.mapLeft((u=!o.shouldUseNativeValidation&&"all"===o.criteriaMode,function(e){var r=u?N:h;return t.pipe(e,s.map(O),r)})),c.mapLeft(function(e){return r.toNestError(e,o)}),c.fold(function(e){return{values:{},errors:e}},function(e){return o.shouldUseNativeValidation&&r.validateFieldsNatively({},o),{values:e,errors:{}}}));var u}};
|
|
2
|
+
//# sourceMappingURL=io-ts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io-ts.js","sources":["../src/arrayToPath.ts","../src/errorsToRecord.ts","../src/io-ts.ts"],"sourcesContent":["import * as Either from 'fp-ts/Either';\nimport { pipe } from 'fp-ts/function';\n\nconst arrayToPath = (paths: Either.Either<string, number>[]): string =>\n paths.reduce(\n (previous, path, index) =>\n pipe(\n path,\n Either.fold(\n (key) => `${index > 0 ? '.' : ''}${key}`,\n (key) => `[${key}]`,\n ),\n (path) => `${previous}${path}`,\n ),\n '',\n );\n\nexport default arrayToPath;\n","import * as t from 'io-ts';\nimport {\n IntersectionType,\n TaggedUnionType,\n UnionType,\n ValidationError,\n} from 'io-ts';\nimport { absurd, flow, identity, not, pipe } from 'fp-ts/function';\nimport * as ReadonlyArray from 'fp-ts/ReadonlyArray';\nimport * as Option from 'fp-ts/Option';\nimport * as Either from 'fp-ts/Either';\nimport * as SemiGroup from 'fp-ts/Semigroup';\nimport arrayToPath from './arrayToPath';\nimport * as ReadonlyRecord from 'fp-ts/ReadonlyRecord';\nimport { ErrorObject, FieldErrorWithPath } from './types';\n\nconst formatErrorPath = (context: t.Context): string =>\n pipe(\n context,\n ReadonlyArray.filterMapWithIndex((index, contextEntry) => {\n const previousIndex = index - 1;\n\n const shouldBeFiltered =\n context[previousIndex] === undefined ||\n context[previousIndex].type instanceof TaggedUnionType ||\n context[previousIndex].type instanceof UnionType ||\n context[previousIndex].type instanceof IntersectionType;\n\n return shouldBeFiltered ? Option.none : Option.some(contextEntry);\n }),\n ReadonlyArray.map(({ key }) => key),\n ReadonlyArray.map((key) =>\n pipe(\n key,\n (k) => parseInt(k, 10),\n Either.fromPredicate(not<number>(Number.isNaN), () => key),\n ),\n ),\n ReadonlyArray.toArray,\n arrayToPath,\n );\n\nconst formatError = (e: t.ValidationError): FieldErrorWithPath => {\n const path = formatErrorPath(e.context);\n\n const message = pipe(\n e.message,\n Either.fromNullable(e.context),\n Either.mapLeft(\n flow(\n ReadonlyArray.last,\n Option.map(\n (contextEntry) =>\n `expected ${contextEntry.type.name} but got ${JSON.stringify(\n contextEntry.actual,\n )}`,\n ),\n Option.getOrElseW(() =>\n absurd<string>('Error context is missing name' as never),\n ),\n ),\n ),\n Either.getOrElseW(identity),\n );\n\n const type = pipe(\n e.context,\n ReadonlyArray.last,\n Option.map((contextEntry) => contextEntry.type.name),\n Option.getOrElse(() => 'unknown'),\n );\n\n return { message, type, path };\n};\n\n// this is almost the same function like Semigroup.getObjectSemigroup but reversed\n// in order to get the first error\nconst getObjectSemigroup = <\n A extends Record<string, unknown> = never,\n>(): SemiGroup.Semigroup<A> => ({\n concat: (first, second) => Object.assign({}, second, first),\n});\n\nconst concatToSingleError = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n errors,\n ReadonlyArray.map((error) => ({\n [error.path]: {\n type: error.type,\n message: error.message,\n },\n })),\n (errors) => SemiGroup.fold(getObjectSemigroup<ErrorObject>())({}, errors),\n );\n\nconst appendSeveralErrors: SemiGroup.Semigroup<FieldErrorWithPath> = {\n concat: (a, b) => ({\n ...b,\n types: { ...a.types, [a.type]: a.message, [b.type]: b.message },\n }),\n};\n\nconst concatToMultipleErrors = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n ReadonlyRecord.fromFoldableMap(appendSeveralErrors, ReadonlyArray.Foldable)(\n errors,\n (error) => [error.path, error],\n ),\n ReadonlyRecord.map((errorWithPath) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { path, ...error } = errorWithPath;\n\n return error;\n }),\n );\n\nconst errorsToRecord =\n (validateAllFieldCriteria: boolean) =>\n (validationErrors: ReadonlyArray<ValidationError>): ErrorObject => {\n const concat = validateAllFieldCriteria\n ? concatToMultipleErrors\n : concatToSingleError;\n\n return pipe(validationErrors, ReadonlyArray.map(formatError), concat);\n };\n\nexport default errorsToRecord;\n","import * as Either from 'fp-ts/lib/Either';\nimport { pipe } from 'fp-ts/function';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport errorsToRecord from './errorsToRecord';\nimport { Resolver } from './types';\nimport { FieldErrors } from 'react-hook-form';\n\nexport const ioTsResolver: Resolver = (codec) => (values, _context, options) =>\n pipe(\n values,\n codec.decode,\n Either.mapLeft(\n errorsToRecord(\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n ),\n Either.mapLeft((errors) => toNestError(errors, options)),\n Either.fold(\n (errors) => ({\n values: {},\n errors,\n }),\n (values) => {\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options);\n\n return {\n values,\n errors: {} as FieldErrors<any>,\n };\n },\n ),\n );\n"],"names":["arrayToPath","paths","reduce","previous","path","index","pipe","Either","fold","key","formatError","e","context","ReadonlyArray","filterMapWithIndex","contextEntry","previousIndex","undefined","type","TaggedUnionType","UnionType","IntersectionType","Option","none","some","map","k","parseInt","fromPredicate","not","Number","isNaN","toArray","message","fromNullable","mapLeft","flow","last","name","JSON","stringify","actual","getOrElseW","absurd","identity","getOrElse","concatToSingleError","errors","error","SemiGroup","concat","first","second","Object","assign","appendSeveralErrors","a","b","types","concatToMultipleErrors","ReadonlyRecord","fromFoldableMap","Foldable","errorWithPath","codec","values","_context","options","decode","validateAllFieldCriteria","shouldUseNativeValidation","criteriaMode","validationErrors","toNestError","validateFieldsNatively"],"mappings":"ixBAGA,IAAMA,EAAc,SAACC,UACnBA,EAAMC,OACJ,SAACC,EAAUC,EAAMC,UACfC,OACEF,EACAG,EAAOC,KACL,SAACC,UAAWJ,EAAQ,EAAI,IAAM,IAAKI,GACnC,SAACA,aAAYA,QAEf,SAACL,YAAYD,EAAWC,KAE5B,gBC4BEM,EAAc,SAACC,GACnB,IA3BuBC,EA2BjBR,EA1BNE,OADuBM,EA2BMD,EAAEC,QAxB7BC,EAAcC,mBAAmB,SAACT,EAAOU,GACvC,IAAMC,EAAgBX,EAAQ,EAQ9B,YAL6BY,IAA3BL,EAAQI,IACRJ,EAAQI,GAAeE,gBAAgBC,mBACvCP,EAAQI,GAAeE,gBAAgBE,aACvCR,EAAQI,GAAeE,gBAAgBG,mBAEfC,EAAOC,KAAOD,EAAOE,KAAKT,KAEtDF,EAAcY,IAAI,qBAAGhB,MACrBI,EAAcY,IAAI,SAAChB,UACjBH,OACEG,EACA,SAACiB,UAAMC,SAASD,EAAG,KACnBnB,EAAOqB,cAAcC,MAAYC,OAAOC,OAAQ,kBAAMtB,OAG1DI,EAAcmB,QACdhC,GAiCF,MAAO,CAAEiC,QA3BO3B,OACdK,EAAEsB,QACF1B,EAAO2B,aAAavB,EAAEC,SACtBL,EAAO4B,QACLC,OACEvB,EAAcwB,KACdf,EAAOG,IACL,SAACV,qBACaA,EAAaG,KAAKoB,iBAAgBC,KAAKC,UACjDzB,EAAa0B,UAGnBnB,EAAOoB,WAAW,kBAChBC,SAAe,qCAIrBpC,EAAOmC,WAAWE,aAUF1B,KAPLZ,OACXK,EAAEC,QACFC,EAAcwB,KACdf,EAAOG,IAAI,SAACV,UAAiBA,EAAaG,KAAKoB,OAC/ChB,EAAOuB,UAAU,iBAAM,aAGDzC,KAAAA,IAWpB0C,EAAsB,SAC1BC,UAEAzC,OACEyC,EACAlC,EAAcY,IAAI,SAACuB,sBAChBA,EAAM5C,MAAO,CACZc,KAAM8B,EAAM9B,KACZe,QAASe,EAAMf,aAGnB,SAACc,UAAWE,EAAUzC,KAfM,CAC9B0C,OAAQ,SAACC,EAAOC,UAAWC,OAAOC,OAAO,GAAIF,EAAQD,KAcvCF,CAAkD,GAAIF,MAGhEQ,EAA+D,CACnEL,OAAQ,SAACM,EAAGC,qBACPA,GACHC,WAAYF,EAAEE,cAAQF,EAAEtC,MAAOsC,EAAEvB,UAAUwB,EAAEvC,MAAOuC,EAAExB,gBAIpD0B,EAAyB,SAC7BZ,UAEAzC,OACEsD,EAAeC,gBAAgBN,EAAqB1C,EAAciD,SAAlEF,CACEb,EACA,SAACC,SAAU,CAACA,EAAM5C,KAAM4C,KAE1BY,EAAenC,IAAI,SAACsC,GAIlB,0IAF2BA,8BC3GK,SAACC,mBAAWC,EAAQC,EAAUC,UAClE7D,OACE2D,EACAD,EAAMI,OACN7D,EAAO4B,SD8GRkC,GC5GMF,EAAQG,2BAAsD,QAAzBH,EAAQI,sBD6GnDC,GACC,IAAMtB,EAASmB,EACXV,EACAb,EAEJ,OAAOxC,OAAKkE,EAAkB3D,EAAcY,IAAIf,GAAcwC,MC/G9D3C,EAAO4B,QAAQ,SAACY,UAAW0B,cAAY1B,EAAQoB,KAC/C5D,EAAOC,KACL,SAACuC,SAAY,CACXkB,OAAQ,GACRlB,OAAAA,IAEF,SAACkB,GAIC,OAHAE,EAAQG,2BACNI,yBAAuB,GAAIP,GAEtB,CACLF,OAAAA,EACAlB,OAAQ,OD6FhB,IAACsB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as t from"fp-ts/lib/Either";import{pipe as n,not as r,flow as e,absurd as o,identity as u}from"fp-ts/function";import{toNestError as a,validateFieldsNatively as i}from"@hookform/resolvers";import{TaggedUnionType as f,UnionType as s,IntersectionType as c}from"io-ts";import*as p from"fp-ts/ReadonlyArray";import*as m from"fp-ts/Option";import*as l from"fp-ts/Either";import*as y from"fp-ts/Semigroup";import*as d from"fp-ts/ReadonlyRecord";function g(){return(g=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t}).apply(this,arguments)}var v=function(t){return t.reduce(function(t,r,e){return n(r,l.fold(function(t){return(e>0?".":"")+t},function(t){return"["+t+"]"}),function(n){return""+t+n})},"")},h=["path"],O=function(t){var a,i=n(a=t.context,p.filterMapWithIndex(function(t,n){var r=t-1;return void 0===a[r]||a[r].type instanceof f||a[r].type instanceof s||a[r].type instanceof c?m.none:m.some(n)}),p.map(function(t){return t.key}),p.map(function(t){return n(t,function(t){return parseInt(t,10)},l.fromPredicate(r(Number.isNaN),function(){return t}))}),p.toArray,v);return{message:n(t.message,l.fromNullable(t.context),l.mapLeft(e(p.last,m.map(function(t){return"expected "+t.type.name+" but got "+JSON.stringify(t.actual)}),m.getOrElseW(function(){return o("Error context is missing name")}))),l.getOrElseW(u)),type:n(t.context,p.last,m.map(function(t){return t.type.name}),m.getOrElse(function(){return"unknown"})),path:i}},b=function(t){return n(t,p.map(function(t){var n;return(n={})[t.path]={type:t.type,message:t.message},n}),function(t){return y.fold({concat:function(t,n){return Object.assign({},n,t)}})({},t)})},x={concat:function(t,n){var r;return g({},n,{types:g({},t.types,(r={},r[t.type]=t.message,r[n.type]=n.message,r))})}},N=function(t){return n(d.fromFoldableMap(x,p.Foldable)(t,function(t){return[t.path,t]}),d.map(function(t){return function(t,n){if(null==t)return{};var r,e,o={},u=Object.keys(t);for(e=0;e<u.length;e++)n.indexOf(r=u[e])>=0||(o[r]=t[r]);return o}(t,h)}))},E=function(r){return function(e,o,u){return n(e,r.decode,t.mapLeft((f=!u.shouldUseNativeValidation&&"all"===u.criteriaMode,function(t){var r=f?N:b;return n(t,p.map(O),r)})),t.mapLeft(function(t){return a(t,u)}),t.fold(function(t){return{values:{},errors:t}},function(t){return u.shouldUseNativeValidation&&i({},u),{values:t,errors:{}}}));var f}};export{E as ioTsResolver};
|
|
2
|
+
//# sourceMappingURL=io-ts.module.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as e from"fp-ts/lib/Either";import{pipe as t,not as r,flow as o,absurd as a,identity as s}from"fp-ts/function";import{toNestError as n,validateFieldsNatively as p}from"@hookform/resolvers";import{TaggedUnionType as i,UnionType as m,IntersectionType as f}from"io-ts";import*as l from"fp-ts/ReadonlyArray";import*as c from"fp-ts/Option";import*as u from"fp-ts/Either";import*as y from"fp-ts/Semigroup";import*as d from"fp-ts/ReadonlyRecord";function g(){return(g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e}).apply(this,arguments)}const h=e=>e.reduce((e,r,o)=>t(r,u.fold(e=>`${o>0?".":""}${e}`,e=>`[${e}]`),t=>`${e}${t}`),""),v=["path"],O=e=>{const n=t(p=e.context,l.filterMapWithIndex((e,t)=>{const r=e-1;return void 0===p[r]||p[r].type instanceof i||p[r].type instanceof m||p[r].type instanceof f?c.none:c.some(t)}),l.map(({key:e})=>e),l.map(e=>t(e,e=>parseInt(e,10),u.fromPredicate(r(Number.isNaN),()=>e))),l.toArray,h);var p;return{message:t(e.message,u.fromNullable(e.context),u.mapLeft(o(l.last,c.map(e=>`expected ${e.type.name} but got ${JSON.stringify(e.actual)}`),c.getOrElseW(()=>a("Error context is missing name")))),u.getOrElseW(s)),type:t(e.context,l.last,c.map(e=>e.type.name),c.getOrElse(()=>"unknown")),path:n}},b=e=>t(e,l.map(e=>({[e.path]:{type:e.type,message:e.message}})),e=>y.fold({concat:(e,t)=>Object.assign({},t,e)})({},e)),x={concat:(e,t)=>g({},t,{types:g({},e.types,{[e.type]:e.message,[t.type]:t.message})})},N=e=>t(d.fromFoldableMap(x,l.Foldable)(e,e=>[e.path,e]),d.map(e=>function(e,t){if(null==e)return{};var r,o,a={},s=Object.keys(e);for(o=0;o<s.length;o++)t.indexOf(r=s[o])>=0||(a[r]=e[r]);return a}(e,v))),$=r=>(o,a,s)=>{return t(o,r.decode,e.mapLeft((i=!s.shouldUseNativeValidation&&"all"===s.criteriaMode,e=>{const r=i?N:b;return t(e,l.map(O),r)})),e.mapLeft(e=>n(e,s)),e.fold(e=>({values:{},errors:e}),e=>(s.shouldUseNativeValidation&&p({},s),{values:e,errors:{}})));var i};export{$ as ioTsResolver};
|
|
2
|
+
//# sourceMappingURL=io-ts.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io-ts.modern.js","sources":["../src/arrayToPath.ts","../src/errorsToRecord.ts","../src/io-ts.ts"],"sourcesContent":["import * as Either from 'fp-ts/Either';\nimport { pipe } from 'fp-ts/function';\n\nconst arrayToPath = (paths: Either.Either<string, number>[]): string =>\n paths.reduce(\n (previous, path, index) =>\n pipe(\n path,\n Either.fold(\n (key) => `${index > 0 ? '.' : ''}${key}`,\n (key) => `[${key}]`,\n ),\n (path) => `${previous}${path}`,\n ),\n '',\n );\n\nexport default arrayToPath;\n","import * as t from 'io-ts';\nimport {\n IntersectionType,\n TaggedUnionType,\n UnionType,\n ValidationError,\n} from 'io-ts';\nimport { absurd, flow, identity, not, pipe } from 'fp-ts/function';\nimport * as ReadonlyArray from 'fp-ts/ReadonlyArray';\nimport * as Option from 'fp-ts/Option';\nimport * as Either from 'fp-ts/Either';\nimport * as SemiGroup from 'fp-ts/Semigroup';\nimport arrayToPath from './arrayToPath';\nimport * as ReadonlyRecord from 'fp-ts/ReadonlyRecord';\nimport { ErrorObject, FieldErrorWithPath } from './types';\n\nconst formatErrorPath = (context: t.Context): string =>\n pipe(\n context,\n ReadonlyArray.filterMapWithIndex((index, contextEntry) => {\n const previousIndex = index - 1;\n\n const shouldBeFiltered =\n context[previousIndex] === undefined ||\n context[previousIndex].type instanceof TaggedUnionType ||\n context[previousIndex].type instanceof UnionType ||\n context[previousIndex].type instanceof IntersectionType;\n\n return shouldBeFiltered ? Option.none : Option.some(contextEntry);\n }),\n ReadonlyArray.map(({ key }) => key),\n ReadonlyArray.map((key) =>\n pipe(\n key,\n (k) => parseInt(k, 10),\n Either.fromPredicate(not<number>(Number.isNaN), () => key),\n ),\n ),\n ReadonlyArray.toArray,\n arrayToPath,\n );\n\nconst formatError = (e: t.ValidationError): FieldErrorWithPath => {\n const path = formatErrorPath(e.context);\n\n const message = pipe(\n e.message,\n Either.fromNullable(e.context),\n Either.mapLeft(\n flow(\n ReadonlyArray.last,\n Option.map(\n (contextEntry) =>\n `expected ${contextEntry.type.name} but got ${JSON.stringify(\n contextEntry.actual,\n )}`,\n ),\n Option.getOrElseW(() =>\n absurd<string>('Error context is missing name' as never),\n ),\n ),\n ),\n Either.getOrElseW(identity),\n );\n\n const type = pipe(\n e.context,\n ReadonlyArray.last,\n Option.map((contextEntry) => contextEntry.type.name),\n Option.getOrElse(() => 'unknown'),\n );\n\n return { message, type, path };\n};\n\n// this is almost the same function like Semigroup.getObjectSemigroup but reversed\n// in order to get the first error\nconst getObjectSemigroup = <\n A extends Record<string, unknown> = never,\n>(): SemiGroup.Semigroup<A> => ({\n concat: (first, second) => Object.assign({}, second, first),\n});\n\nconst concatToSingleError = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n errors,\n ReadonlyArray.map((error) => ({\n [error.path]: {\n type: error.type,\n message: error.message,\n },\n })),\n (errors) => SemiGroup.fold(getObjectSemigroup<ErrorObject>())({}, errors),\n );\n\nconst appendSeveralErrors: SemiGroup.Semigroup<FieldErrorWithPath> = {\n concat: (a, b) => ({\n ...b,\n types: { ...a.types, [a.type]: a.message, [b.type]: b.message },\n }),\n};\n\nconst concatToMultipleErrors = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n ReadonlyRecord.fromFoldableMap(appendSeveralErrors, ReadonlyArray.Foldable)(\n errors,\n (error) => [error.path, error],\n ),\n ReadonlyRecord.map((errorWithPath) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { path, ...error } = errorWithPath;\n\n return error;\n }),\n );\n\nconst errorsToRecord =\n (validateAllFieldCriteria: boolean) =>\n (validationErrors: ReadonlyArray<ValidationError>): ErrorObject => {\n const concat = validateAllFieldCriteria\n ? concatToMultipleErrors\n : concatToSingleError;\n\n return pipe(validationErrors, ReadonlyArray.map(formatError), concat);\n };\n\nexport default errorsToRecord;\n","import * as Either from 'fp-ts/lib/Either';\nimport { pipe } from 'fp-ts/function';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport errorsToRecord from './errorsToRecord';\nimport { Resolver } from './types';\nimport { FieldErrors } from 'react-hook-form';\n\nexport const ioTsResolver: Resolver = (codec) => (values, _context, options) =>\n pipe(\n values,\n codec.decode,\n Either.mapLeft(\n errorsToRecord(\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n ),\n Either.mapLeft((errors) => toNestError(errors, options)),\n Either.fold(\n (errors) => ({\n values: {},\n errors,\n }),\n (values) => {\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options);\n\n return {\n values,\n errors: {} as FieldErrors<any>,\n };\n },\n ),\n );\n"],"names":["arrayToPath","paths","reduce","previous","path","index","pipe","Either","fold","key","formatError","e","context","ReadonlyArray","filterMapWithIndex","contextEntry","previousIndex","undefined","type","TaggedUnionType","UnionType","IntersectionType","Option","none","some","map","k","parseInt","fromPredicate","not","Number","isNaN","toArray","message","fromNullable","mapLeft","flow","last","name","JSON","stringify","actual","getOrElseW","absurd","identity","getOrElse","concatToSingleError","errors","error","SemiGroup","concat","first","second","Object","assign","appendSeveralErrors","a","b","types","concatToMultipleErrors","ReadonlyRecord","fromFoldableMap","Foldable","errorWithPath","ioTsResolver","codec","values","_context","options","decode","validateAllFieldCriteria","shouldUseNativeValidation","criteriaMode","validationErrors","toNestError","validateFieldsNatively"],"mappings":"6oBAGA,MAAMA,EAAeC,GACnBA,EAAMC,OACJ,CAACC,EAAUC,EAAMC,IACfC,EACEF,EACAG,EAAOC,KACJC,MAAWJ,EAAQ,EAAI,IAAM,KAAKI,IAClCA,OAAYA,MAEdL,MAAYD,IAAWC,KAE5B,eC4BEM,EAAeC,IACnB,MAAMP,EA1BNE,EADuBM,EA2BMD,EAAEC,QAxB7BC,EAAcC,mBAAmB,CAACT,EAAOU,KACvC,MAAMC,EAAgBX,EAAQ,EAQ9B,YAL6BY,IAA3BL,EAAQI,IACRJ,EAAQI,GAAeE,gBAAgBC,GACvCP,EAAQI,GAAeE,gBAAgBE,GACvCR,EAAQI,GAAeE,gBAAgBG,EAEfC,EAAOC,KAAOD,EAAOE,KAAKT,KAEtDF,EAAcY,IAAI,EAAGhB,IAAAA,KAAUA,GAC/BI,EAAcY,IAAKhB,GACjBH,EACEG,EACCiB,GAAMC,SAASD,EAAG,IACnBnB,EAAOqB,cAAcC,EAAYC,OAAOC,OAAQ,IAAMtB,KAG1DI,EAAcmB,QACdhC,GAvBqBY,IAAAA,EAwDvB,MAAO,CAAEqB,QA3BO3B,EACdK,EAAEsB,QACF1B,EAAO2B,aAAavB,EAAEC,SACtBL,EAAO4B,QACLC,EACEvB,EAAcwB,KACdf,EAAOG,IACJV,eACaA,EAAaG,KAAKoB,gBAAgBC,KAAKC,UACjDzB,EAAa0B,WAGnBnB,EAAOoB,WAAW,IAChBC,EAAe,oCAIrBpC,EAAOmC,WAAWE,IAUF1B,KAPLZ,EACXK,EAAEC,QACFC,EAAcwB,KACdf,EAAOG,IAAKV,GAAiBA,EAAaG,KAAKoB,MAC/ChB,EAAOuB,UAAU,IAAM,YAGDzC,KAAAA,IAWpB0C,EACJC,GAEAzC,EACEyC,EACAlC,EAAcY,IAAKuB,KACjB,CAACA,EAAM5C,MAAO,CACZc,KAAM8B,EAAM9B,KACZe,QAASe,EAAMf,YAGlBc,GAAWE,EAAUzC,MAdxB0C,OAAQ,CAACC,EAAOC,IAAWC,OAAOC,OAAO,GAAIF,EAAQD,IAcvCF,CAAkD,GAAIF,IAGhEQ,EAA+D,CACnEL,OAAQ,CAACM,EAAGC,SACPA,GACHC,WAAYF,EAAEE,OAAO,CAACF,EAAEtC,MAAOsC,EAAEvB,QAAS,CAACwB,EAAEvC,MAAOuC,EAAExB,aAIpD0B,EACJZ,GAEAzC,EACEsD,EAAeC,gBAAgBN,EAAqB1C,EAAciD,SAAlEF,CACEb,EACCC,GAAU,CAACA,EAAM5C,KAAM4C,IAE1BY,EAAenC,IAAKsC,sIAESA,OC3GpBC,EAA0BC,GAAU,CAACC,EAAQC,EAAUC,KAClE9D,OAAAA,EACE4D,EACAD,EAAMI,OACN9D,EAAO4B,SD8GRmC,GC5GMF,EAAQG,2BAAsD,QAAzBH,EAAQI,aD6GnDC,IACC,MAAMvB,EAASoB,EACXX,EACAb,EAEJ,OAAOxC,EAAKmE,EAAkB5D,EAAcY,IAAIf,GAAcwC,MC/G9D3C,EAAO4B,QAASY,GAAW2B,EAAY3B,EAAQqB,IAC/C7D,EAAOC,KACJuC,KACCmB,OAAQ,GACRnB,OAAAA,IAEDmB,IACCE,EAAQG,2BACNI,EAAuB,GAAIP,GAEtB,CACLF,OAAAA,EACAnB,OAAQ,OD6FfuB,IAAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as t from"fp-ts/lib/Either";import{pipe as n,not as r,flow as e,absurd as o,identity as u}from"fp-ts/function";import{toNestError as a,validateFieldsNatively as i}from"@hookform/resolvers";import{TaggedUnionType as f,UnionType as s,IntersectionType as c}from"io-ts";import*as p from"fp-ts/ReadonlyArray";import*as m from"fp-ts/Option";import*as l from"fp-ts/Either";import*as y from"fp-ts/Semigroup";import*as d from"fp-ts/ReadonlyRecord";function g(){return(g=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t}).apply(this,arguments)}var v=function(t){return t.reduce(function(t,r,e){return n(r,l.fold(function(t){return(e>0?".":"")+t},function(t){return"["+t+"]"}),function(n){return""+t+n})},"")},h=["path"],O=function(t){var a,i=n(a=t.context,p.filterMapWithIndex(function(t,n){var r=t-1;return void 0===a[r]||a[r].type instanceof f||a[r].type instanceof s||a[r].type instanceof c?m.none:m.some(n)}),p.map(function(t){return t.key}),p.map(function(t){return n(t,function(t){return parseInt(t,10)},l.fromPredicate(r(Number.isNaN),function(){return t}))}),p.toArray,v);return{message:n(t.message,l.fromNullable(t.context),l.mapLeft(e(p.last,m.map(function(t){return"expected "+t.type.name+" but got "+JSON.stringify(t.actual)}),m.getOrElseW(function(){return o("Error context is missing name")}))),l.getOrElseW(u)),type:n(t.context,p.last,m.map(function(t){return t.type.name}),m.getOrElse(function(){return"unknown"})),path:i}},b=function(t){return n(t,p.map(function(t){var n;return(n={})[t.path]={type:t.type,message:t.message},n}),function(t){return y.fold({concat:function(t,n){return Object.assign({},n,t)}})({},t)})},x={concat:function(t,n){var r;return g({},n,{types:g({},t.types,(r={},r[t.type]=t.message,r[n.type]=n.message,r))})}},N=function(t){return n(d.fromFoldableMap(x,p.Foldable)(t,function(t){return[t.path,t]}),d.map(function(t){return function(t,n){if(null==t)return{};var r,e,o={},u=Object.keys(t);for(e=0;e<u.length;e++)n.indexOf(r=u[e])>=0||(o[r]=t[r]);return o}(t,h)}))},E=function(r){return function(e,o,u){return n(e,r.decode,t.mapLeft((f=!u.shouldUseNativeValidation&&"all"===u.criteriaMode,function(t){var r=f?N:b;return n(t,p.map(O),r)})),t.mapLeft(function(t){return a(t,u)}),t.fold(function(t){return{values:{},errors:t}},function(t){return u.shouldUseNativeValidation&&i({},u),{values:t,errors:{}}}));var f}};export{E as ioTsResolver};
|
|
2
|
+
//# sourceMappingURL=io-ts.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io-ts.module.js","sources":["../src/arrayToPath.ts","../src/errorsToRecord.ts","../src/io-ts.ts"],"sourcesContent":["import * as Either from 'fp-ts/Either';\nimport { pipe } from 'fp-ts/function';\n\nconst arrayToPath = (paths: Either.Either<string, number>[]): string =>\n paths.reduce(\n (previous, path, index) =>\n pipe(\n path,\n Either.fold(\n (key) => `${index > 0 ? '.' : ''}${key}`,\n (key) => `[${key}]`,\n ),\n (path) => `${previous}${path}`,\n ),\n '',\n );\n\nexport default arrayToPath;\n","import * as t from 'io-ts';\nimport {\n IntersectionType,\n TaggedUnionType,\n UnionType,\n ValidationError,\n} from 'io-ts';\nimport { absurd, flow, identity, not, pipe } from 'fp-ts/function';\nimport * as ReadonlyArray from 'fp-ts/ReadonlyArray';\nimport * as Option from 'fp-ts/Option';\nimport * as Either from 'fp-ts/Either';\nimport * as SemiGroup from 'fp-ts/Semigroup';\nimport arrayToPath from './arrayToPath';\nimport * as ReadonlyRecord from 'fp-ts/ReadonlyRecord';\nimport { ErrorObject, FieldErrorWithPath } from './types';\n\nconst formatErrorPath = (context: t.Context): string =>\n pipe(\n context,\n ReadonlyArray.filterMapWithIndex((index, contextEntry) => {\n const previousIndex = index - 1;\n\n const shouldBeFiltered =\n context[previousIndex] === undefined ||\n context[previousIndex].type instanceof TaggedUnionType ||\n context[previousIndex].type instanceof UnionType ||\n context[previousIndex].type instanceof IntersectionType;\n\n return shouldBeFiltered ? Option.none : Option.some(contextEntry);\n }),\n ReadonlyArray.map(({ key }) => key),\n ReadonlyArray.map((key) =>\n pipe(\n key,\n (k) => parseInt(k, 10),\n Either.fromPredicate(not<number>(Number.isNaN), () => key),\n ),\n ),\n ReadonlyArray.toArray,\n arrayToPath,\n );\n\nconst formatError = (e: t.ValidationError): FieldErrorWithPath => {\n const path = formatErrorPath(e.context);\n\n const message = pipe(\n e.message,\n Either.fromNullable(e.context),\n Either.mapLeft(\n flow(\n ReadonlyArray.last,\n Option.map(\n (contextEntry) =>\n `expected ${contextEntry.type.name} but got ${JSON.stringify(\n contextEntry.actual,\n )}`,\n ),\n Option.getOrElseW(() =>\n absurd<string>('Error context is missing name' as never),\n ),\n ),\n ),\n Either.getOrElseW(identity),\n );\n\n const type = pipe(\n e.context,\n ReadonlyArray.last,\n Option.map((contextEntry) => contextEntry.type.name),\n Option.getOrElse(() => 'unknown'),\n );\n\n return { message, type, path };\n};\n\n// this is almost the same function like Semigroup.getObjectSemigroup but reversed\n// in order to get the first error\nconst getObjectSemigroup = <\n A extends Record<string, unknown> = never,\n>(): SemiGroup.Semigroup<A> => ({\n concat: (first, second) => Object.assign({}, second, first),\n});\n\nconst concatToSingleError = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n errors,\n ReadonlyArray.map((error) => ({\n [error.path]: {\n type: error.type,\n message: error.message,\n },\n })),\n (errors) => SemiGroup.fold(getObjectSemigroup<ErrorObject>())({}, errors),\n );\n\nconst appendSeveralErrors: SemiGroup.Semigroup<FieldErrorWithPath> = {\n concat: (a, b) => ({\n ...b,\n types: { ...a.types, [a.type]: a.message, [b.type]: b.message },\n }),\n};\n\nconst concatToMultipleErrors = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n ReadonlyRecord.fromFoldableMap(appendSeveralErrors, ReadonlyArray.Foldable)(\n errors,\n (error) => [error.path, error],\n ),\n ReadonlyRecord.map((errorWithPath) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { path, ...error } = errorWithPath;\n\n return error;\n }),\n );\n\nconst errorsToRecord =\n (validateAllFieldCriteria: boolean) =>\n (validationErrors: ReadonlyArray<ValidationError>): ErrorObject => {\n const concat = validateAllFieldCriteria\n ? concatToMultipleErrors\n : concatToSingleError;\n\n return pipe(validationErrors, ReadonlyArray.map(formatError), concat);\n };\n\nexport default errorsToRecord;\n","import * as Either from 'fp-ts/lib/Either';\nimport { pipe } from 'fp-ts/function';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport errorsToRecord from './errorsToRecord';\nimport { Resolver } from './types';\nimport { FieldErrors } from 'react-hook-form';\n\nexport const ioTsResolver: Resolver = (codec) => (values, _context, options) =>\n pipe(\n values,\n codec.decode,\n Either.mapLeft(\n errorsToRecord(\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n ),\n Either.mapLeft((errors) => toNestError(errors, options)),\n Either.fold(\n (errors) => ({\n values: {},\n errors,\n }),\n (values) => {\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options);\n\n return {\n values,\n errors: {} as FieldErrors<any>,\n };\n },\n ),\n );\n"],"names":["arrayToPath","paths","reduce","previous","path","index","pipe","Either","fold","key","formatError","e","context","ReadonlyArray","filterMapWithIndex","contextEntry","previousIndex","undefined","type","TaggedUnionType","UnionType","IntersectionType","Option","none","some","map","k","parseInt","fromPredicate","not","Number","isNaN","toArray","message","fromNullable","mapLeft","flow","last","name","JSON","stringify","actual","getOrElseW","absurd","identity","getOrElse","concatToSingleError","errors","error","SemiGroup","concat","first","second","Object","assign","appendSeveralErrors","a","b","types","concatToMultipleErrors","ReadonlyRecord","fromFoldableMap","Foldable","errorWithPath","ioTsResolver","codec","values","_context","options","decode","validateAllFieldCriteria","shouldUseNativeValidation","criteriaMode","validationErrors","toNestError","validateFieldsNatively"],"mappings":"6oBAGA,IAAMA,EAAc,SAACC,UACnBA,EAAMC,OACJ,SAACC,EAAUC,EAAMC,UACfC,EACEF,EACAG,EAAOC,KACL,SAACC,UAAWJ,EAAQ,EAAI,IAAM,IAAKI,GACnC,SAACA,aAAYA,QAEf,SAACL,YAAYD,EAAWC,KAE5B,gBC4BEM,EAAc,SAACC,GACnB,IA3BuBC,EA2BjBR,EA1BNE,EADuBM,EA2BMD,EAAEC,QAxB7BC,EAAcC,mBAAmB,SAACT,EAAOU,GACvC,IAAMC,EAAgBX,EAAQ,EAQ9B,YAL6BY,IAA3BL,EAAQI,IACRJ,EAAQI,GAAeE,gBAAgBC,GACvCP,EAAQI,GAAeE,gBAAgBE,GACvCR,EAAQI,GAAeE,gBAAgBG,EAEfC,EAAOC,KAAOD,EAAOE,KAAKT,KAEtDF,EAAcY,IAAI,qBAAGhB,MACrBI,EAAcY,IAAI,SAAChB,UACjBH,EACEG,EACA,SAACiB,UAAMC,SAASD,EAAG,KACnBnB,EAAOqB,cAAcC,EAAYC,OAAOC,OAAQ,kBAAMtB,OAG1DI,EAAcmB,QACdhC,GAiCF,MAAO,CAAEiC,QA3BO3B,EACdK,EAAEsB,QACF1B,EAAO2B,aAAavB,EAAEC,SACtBL,EAAO4B,QACLC,EACEvB,EAAcwB,KACdf,EAAOG,IACL,SAACV,qBACaA,EAAaG,KAAKoB,iBAAgBC,KAAKC,UACjDzB,EAAa0B,UAGnBnB,EAAOoB,WAAW,kBAChBC,EAAe,qCAIrBpC,EAAOmC,WAAWE,IAUF1B,KAPLZ,EACXK,EAAEC,QACFC,EAAcwB,KACdf,EAAOG,IAAI,SAACV,UAAiBA,EAAaG,KAAKoB,OAC/ChB,EAAOuB,UAAU,iBAAM,aAGDzC,KAAAA,IAWpB0C,EAAsB,SAC1BC,UAEAzC,EACEyC,EACAlC,EAAcY,IAAI,SAACuB,sBAChBA,EAAM5C,MAAO,CACZc,KAAM8B,EAAM9B,KACZe,QAASe,EAAMf,aAGnB,SAACc,UAAWE,EAAUzC,KAfM,CAC9B0C,OAAQ,SAACC,EAAOC,UAAWC,OAAOC,OAAO,GAAIF,EAAQD,KAcvCF,CAAkD,GAAIF,MAGhEQ,EAA+D,CACnEL,OAAQ,SAACM,EAAGC,qBACPA,GACHC,WAAYF,EAAEE,cAAQF,EAAEtC,MAAOsC,EAAEvB,UAAUwB,EAAEvC,MAAOuC,EAAExB,gBAIpD0B,EAAyB,SAC7BZ,UAEAzC,EACEsD,EAAeC,gBAAgBN,EAAqB1C,EAAciD,SAAlEF,CACEb,EACA,SAACC,SAAU,CAACA,EAAM5C,KAAM4C,KAE1BY,EAAenC,IAAI,SAACsC,GAIlB,0IAF2BA,SC3GpBC,EAAyB,SAACC,mBAAWC,EAAQC,EAAUC,UAClE9D,EACE4D,EACAD,EAAMI,OACN9D,EAAO4B,SD8GRmC,GC5GMF,EAAQG,2BAAsD,QAAzBH,EAAQI,sBD6GnDC,GACC,IAAMvB,EAASoB,EACXX,EACAb,EAEJ,OAAOxC,EAAKmE,EAAkB5D,EAAcY,IAAIf,GAAcwC,MC/G9D3C,EAAO4B,QAAQ,SAACY,UAAW2B,EAAY3B,EAAQqB,KAC/C7D,EAAOC,KACL,SAACuC,SAAY,CACXmB,OAAQ,GACRnB,OAAAA,IAEF,SAACmB,GAIC,OAHAE,EAAQG,2BACNI,EAAuB,GAAIP,GAEtB,CACLF,OAAAA,EACAnB,OAAQ,OD6FhB,IAACuB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("fp-ts/lib/Either"),require("fp-ts/function"),require("@hookform/resolvers"),require("io-ts"),require("fp-ts/ReadonlyArray"),require("fp-ts/Option"),require("fp-ts/Either"),require("fp-ts/Semigroup"),require("fp-ts/ReadonlyRecord")):"function"==typeof define&&define.amd?define(["exports","fp-ts/lib/Either","fp-ts/function","@hookform/resolvers","io-ts","fp-ts/ReadonlyArray","fp-ts/Option","fp-ts/Either","fp-ts/Semigroup","fp-ts/ReadonlyRecord"],t):t((e||self).hookformResolversIoTs={},e.Either$1,e._function,e.hookformResolvers,e.ioTs,e.ReadonlyArray,e.Option,e.Either,e.SemiGroup,e.ReadonlyRecord)}(this,function(e,t,r,n,o,i,u,f,a,p){function s(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,t}var c=s(t),l=s(i),d=s(u),y=s(f),m=s(a),v=s(p);function g(){return(g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var h=function(e){return e.reduce(function(e,t,n){return r.pipe(t,y.fold(function(e){return(n>0?".":"")+e},function(e){return"["+e+"]"}),function(t){return""+e+t})},"")},b=["path"],O=function(e){var t,n=r.pipe(t=e.context,l.filterMapWithIndex(function(e,r){var n=e-1;return void 0===t[n]||t[n].type instanceof o.TaggedUnionType||t[n].type instanceof o.UnionType||t[n].type instanceof o.IntersectionType?d.none:d.some(r)}),l.map(function(e){return e.key}),l.map(function(e){return r.pipe(e,function(e){return parseInt(e,10)},y.fromPredicate(r.not(Number.isNaN),function(){return e}))}),l.toArray,h);return{message:r.pipe(e.message,y.fromNullable(e.context),y.mapLeft(r.flow(l.last,d.map(function(e){return"expected "+e.type.name+" but got "+JSON.stringify(e.actual)}),d.getOrElseW(function(){return r.absurd("Error context is missing name")}))),y.getOrElseW(r.identity)),type:r.pipe(e.context,l.last,d.map(function(e){return e.type.name}),d.getOrElse(function(){return"unknown"})),path:n}},E=function(e){return r.pipe(e,l.map(function(e){var t;return(t={})[e.path]={type:e.type,message:e.message},t}),function(e){return m.fold({concat:function(e,t){return Object.assign({},t,e)}})({},e)})},R={concat:function(e,t){var r;return g({},t,{types:g({},e.types,(r={},r[e.type]=e.message,r[t.type]=t.message,r))})}},x=function(e){return r.pipe(v.fromFoldableMap(R,l.Foldable)(e,function(e){return[e.path,e]}),v.map(function(e){return function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t.indexOf(r=i[n])>=0||(o[r]=e[r]);return o}(e,b)}))};e.ioTsResolver=function(e){return function(t,o,i){return r.pipe(t,e.decode,c.mapLeft((u=!i.shouldUseNativeValidation&&"all"===i.criteriaMode,function(e){var t=u?x:E;return r.pipe(e,l.map(O),t)})),c.mapLeft(function(e){return n.toNestError(e,i)}),c.fold(function(e){return{values:{},errors:e}},function(e){return i.shouldUseNativeValidation&&n.validateFieldsNatively({},i),{values:e,errors:{}}}));var u}}});
|
|
2
|
+
//# sourceMappingURL=io-ts.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io-ts.umd.js","sources":["../src/arrayToPath.ts","../src/errorsToRecord.ts","../src/io-ts.ts"],"sourcesContent":["import * as Either from 'fp-ts/Either';\nimport { pipe } from 'fp-ts/function';\n\nconst arrayToPath = (paths: Either.Either<string, number>[]): string =>\n paths.reduce(\n (previous, path, index) =>\n pipe(\n path,\n Either.fold(\n (key) => `${index > 0 ? '.' : ''}${key}`,\n (key) => `[${key}]`,\n ),\n (path) => `${previous}${path}`,\n ),\n '',\n );\n\nexport default arrayToPath;\n","import * as t from 'io-ts';\nimport {\n IntersectionType,\n TaggedUnionType,\n UnionType,\n ValidationError,\n} from 'io-ts';\nimport { absurd, flow, identity, not, pipe } from 'fp-ts/function';\nimport * as ReadonlyArray from 'fp-ts/ReadonlyArray';\nimport * as Option from 'fp-ts/Option';\nimport * as Either from 'fp-ts/Either';\nimport * as SemiGroup from 'fp-ts/Semigroup';\nimport arrayToPath from './arrayToPath';\nimport * as ReadonlyRecord from 'fp-ts/ReadonlyRecord';\nimport { ErrorObject, FieldErrorWithPath } from './types';\n\nconst formatErrorPath = (context: t.Context): string =>\n pipe(\n context,\n ReadonlyArray.filterMapWithIndex((index, contextEntry) => {\n const previousIndex = index - 1;\n\n const shouldBeFiltered =\n context[previousIndex] === undefined ||\n context[previousIndex].type instanceof TaggedUnionType ||\n context[previousIndex].type instanceof UnionType ||\n context[previousIndex].type instanceof IntersectionType;\n\n return shouldBeFiltered ? Option.none : Option.some(contextEntry);\n }),\n ReadonlyArray.map(({ key }) => key),\n ReadonlyArray.map((key) =>\n pipe(\n key,\n (k) => parseInt(k, 10),\n Either.fromPredicate(not<number>(Number.isNaN), () => key),\n ),\n ),\n ReadonlyArray.toArray,\n arrayToPath,\n );\n\nconst formatError = (e: t.ValidationError): FieldErrorWithPath => {\n const path = formatErrorPath(e.context);\n\n const message = pipe(\n e.message,\n Either.fromNullable(e.context),\n Either.mapLeft(\n flow(\n ReadonlyArray.last,\n Option.map(\n (contextEntry) =>\n `expected ${contextEntry.type.name} but got ${JSON.stringify(\n contextEntry.actual,\n )}`,\n ),\n Option.getOrElseW(() =>\n absurd<string>('Error context is missing name' as never),\n ),\n ),\n ),\n Either.getOrElseW(identity),\n );\n\n const type = pipe(\n e.context,\n ReadonlyArray.last,\n Option.map((contextEntry) => contextEntry.type.name),\n Option.getOrElse(() => 'unknown'),\n );\n\n return { message, type, path };\n};\n\n// this is almost the same function like Semigroup.getObjectSemigroup but reversed\n// in order to get the first error\nconst getObjectSemigroup = <\n A extends Record<string, unknown> = never,\n>(): SemiGroup.Semigroup<A> => ({\n concat: (first, second) => Object.assign({}, second, first),\n});\n\nconst concatToSingleError = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n errors,\n ReadonlyArray.map((error) => ({\n [error.path]: {\n type: error.type,\n message: error.message,\n },\n })),\n (errors) => SemiGroup.fold(getObjectSemigroup<ErrorObject>())({}, errors),\n );\n\nconst appendSeveralErrors: SemiGroup.Semigroup<FieldErrorWithPath> = {\n concat: (a, b) => ({\n ...b,\n types: { ...a.types, [a.type]: a.message, [b.type]: b.message },\n }),\n};\n\nconst concatToMultipleErrors = (\n errors: ReadonlyArray<FieldErrorWithPath>,\n): ErrorObject =>\n pipe(\n ReadonlyRecord.fromFoldableMap(appendSeveralErrors, ReadonlyArray.Foldable)(\n errors,\n (error) => [error.path, error],\n ),\n ReadonlyRecord.map((errorWithPath) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { path, ...error } = errorWithPath;\n\n return error;\n }),\n );\n\nconst errorsToRecord =\n (validateAllFieldCriteria: boolean) =>\n (validationErrors: ReadonlyArray<ValidationError>): ErrorObject => {\n const concat = validateAllFieldCriteria\n ? concatToMultipleErrors\n : concatToSingleError;\n\n return pipe(validationErrors, ReadonlyArray.map(formatError), concat);\n };\n\nexport default errorsToRecord;\n","import * as Either from 'fp-ts/lib/Either';\nimport { pipe } from 'fp-ts/function';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport errorsToRecord from './errorsToRecord';\nimport { Resolver } from './types';\nimport { FieldErrors } from 'react-hook-form';\n\nexport const ioTsResolver: Resolver = (codec) => (values, _context, options) =>\n pipe(\n values,\n codec.decode,\n Either.mapLeft(\n errorsToRecord(\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n ),\n Either.mapLeft((errors) => toNestError(errors, options)),\n Either.fold(\n (errors) => ({\n values: {},\n errors,\n }),\n (values) => {\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options);\n\n return {\n values,\n errors: {} as FieldErrors<any>,\n };\n },\n ),\n );\n"],"names":["arrayToPath","paths","reduce","previous","path","index","pipe","Either","fold","key","formatError","e","context","ReadonlyArray","filterMapWithIndex","contextEntry","previousIndex","undefined","type","TaggedUnionType","UnionType","IntersectionType","Option","none","some","map","k","parseInt","fromPredicate","not","Number","isNaN","toArray","message","fromNullable","mapLeft","flow","last","name","JSON","stringify","actual","getOrElseW","absurd","identity","getOrElse","concatToSingleError","errors","error","SemiGroup","concat","first","second","Object","assign","appendSeveralErrors","a","b","types","concatToMultipleErrors","ReadonlyRecord","fromFoldableMap","Foldable","errorWithPath","codec","values","_context","options","decode","validateAllFieldCriteria","shouldUseNativeValidation","criteriaMode","validationErrors","toNestError","validateFieldsNatively"],"mappings":"4wCAGA,IAAMA,EAAc,SAACC,UACnBA,EAAMC,OACJ,SAACC,EAAUC,EAAMC,UACfC,OACEF,EACAG,EAAOC,KACL,SAACC,UAAWJ,EAAQ,EAAI,IAAM,IAAKI,GACnC,SAACA,aAAYA,QAEf,SAACL,YAAYD,EAAWC,KAE5B,gBC4BEM,EAAc,SAACC,GACnB,IA3BuBC,EA2BjBR,EA1BNE,OADuBM,EA2BMD,EAAEC,QAxB7BC,EAAcC,mBAAmB,SAACT,EAAOU,GACvC,IAAMC,EAAgBX,EAAQ,EAQ9B,YAL6BY,IAA3BL,EAAQI,IACRJ,EAAQI,GAAeE,gBAAgBC,mBACvCP,EAAQI,GAAeE,gBAAgBE,aACvCR,EAAQI,GAAeE,gBAAgBG,mBAEfC,EAAOC,KAAOD,EAAOE,KAAKT,KAEtDF,EAAcY,IAAI,qBAAGhB,MACrBI,EAAcY,IAAI,SAAChB,UACjBH,OACEG,EACA,SAACiB,UAAMC,SAASD,EAAG,KACnBnB,EAAOqB,cAAcC,MAAYC,OAAOC,OAAQ,kBAAMtB,OAG1DI,EAAcmB,QACdhC,GAiCF,MAAO,CAAEiC,QA3BO3B,OACdK,EAAEsB,QACF1B,EAAO2B,aAAavB,EAAEC,SACtBL,EAAO4B,QACLC,OACEvB,EAAcwB,KACdf,EAAOG,IACL,SAACV,qBACaA,EAAaG,KAAKoB,iBAAgBC,KAAKC,UACjDzB,EAAa0B,UAGnBnB,EAAOoB,WAAW,kBAChBC,SAAe,qCAIrBpC,EAAOmC,WAAWE,aAUF1B,KAPLZ,OACXK,EAAEC,QACFC,EAAcwB,KACdf,EAAOG,IAAI,SAACV,UAAiBA,EAAaG,KAAKoB,OAC/ChB,EAAOuB,UAAU,iBAAM,aAGDzC,KAAAA,IAWpB0C,EAAsB,SAC1BC,UAEAzC,OACEyC,EACAlC,EAAcY,IAAI,SAACuB,sBAChBA,EAAM5C,MAAO,CACZc,KAAM8B,EAAM9B,KACZe,QAASe,EAAMf,aAGnB,SAACc,UAAWE,EAAUzC,KAfM,CAC9B0C,OAAQ,SAACC,EAAOC,UAAWC,OAAOC,OAAO,GAAIF,EAAQD,KAcvCF,CAAkD,GAAIF,MAGhEQ,EAA+D,CACnEL,OAAQ,SAACM,EAAGC,qBACPA,GACHC,WAAYF,EAAEE,cAAQF,EAAEtC,MAAOsC,EAAEvB,UAAUwB,EAAEvC,MAAOuC,EAAExB,gBAIpD0B,EAAyB,SAC7BZ,UAEAzC,OACEsD,EAAeC,gBAAgBN,EAAqB1C,EAAciD,SAAlEF,CACEb,EACA,SAACC,SAAU,CAACA,EAAM5C,KAAM4C,KAE1BY,EAAenC,IAAI,SAACsC,GAIlB,0IAF2BA,wBC3GK,SAACC,mBAAWC,EAAQC,EAAUC,UAClE7D,OACE2D,EACAD,EAAMI,OACN7D,EAAO4B,SD8GRkC,GC5GMF,EAAQG,2BAAsD,QAAzBH,EAAQI,sBD6GnDC,GACC,IAAMtB,EAASmB,EACXV,EACAb,EAEJ,OAAOxC,OAAKkE,EAAkB3D,EAAcY,IAAIf,GAAcwC,MC/G9D3C,EAAO4B,QAAQ,SAACY,UAAW0B,cAAY1B,EAAQoB,KAC/C5D,EAAOC,KACL,SAACuC,SAAY,CACXkB,OAAQ,GACRlB,OAAAA,IAEF,SAACkB,GAIC,OAHAE,EAAQG,2BACNI,yBAAuB,GAAIP,GAEtB,CACLF,OAAAA,EACAlB,OAAQ,OD6FhB,IAACsB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as t from 'io-ts';
|
|
2
|
+
import { FieldError, ResolverOptions, ResolverResult, UnpackNestedValue } from 'react-hook-form';
|
|
3
|
+
export declare type Resolver = <TFieldValues, TInput extends unknown = unknown, TContext extends object = object>(codec: t.Decoder<TInput, UnpackNestedValue<TFieldValues>>) => (values: TInput, _context: TContext | undefined, options: ResolverOptions<TFieldValues>) => ResolverResult<TFieldValues>;
|
|
4
|
+
export declare type ErrorObject = Record<string, FieldError>;
|
|
5
|
+
export declare type FieldErrorWithPath = FieldError & {
|
|
6
|
+
path: string;
|
|
7
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "io-ts",
|
|
3
|
+
"amdName": "hookformResolversIoTs",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"description": "React Hook Form validation resolver: io-ts",
|
|
7
|
+
"main": "dist/io-ts.js",
|
|
8
|
+
"module": "dist/io-ts.module.js",
|
|
9
|
+
"umd:main": "dist/io-ts.umd.js",
|
|
10
|
+
"source": "src/index.ts",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"react-hook-form": "^7.0.0",
|
|
15
|
+
"@hookform/resolvers": "^2.0.0",
|
|
16
|
+
"io-ts": "^2.0.0",
|
|
17
|
+
"fp-ts": "^2.7.0"
|
|
18
|
+
}
|
|
19
|
+
}
|