@hookform/resolvers 3.10.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -6
- package/ajv/dist/ajv.d.ts +20 -0
- package/ajv/dist/ajv.js +1 -1
- package/ajv/dist/ajv.js.map +1 -1
- package/ajv/dist/ajv.mjs +1 -1
- package/ajv/dist/ajv.modern.mjs +1 -1
- package/ajv/dist/ajv.modern.mjs.map +1 -1
- package/ajv/dist/ajv.module.js +1 -1
- package/ajv/dist/ajv.module.js.map +1 -1
- package/ajv/dist/ajv.umd.js +1 -1
- package/ajv/dist/ajv.umd.js.map +1 -1
- package/ajv/dist/types.d.ts +8 -0
- package/ajv/src/__tests__/__fixtures__/data-errors.ts +216 -0
- package/ajv/src/__tests__/__snapshots__/ajv-errors.ts.snap +462 -0
- package/ajv/src/__tests__/__snapshots__/ajv.ts.snap +6 -6
- package/ajv/src/__tests__/ajv-errors.ts +227 -0
- package/ajv/src/ajv.ts +47 -14
- package/ajv/src/types.ts +8 -0
- package/arktype/dist/arktype.d.ts +20 -2
- package/arktype/dist/arktype.js +1 -1
- package/arktype/dist/arktype.js.map +1 -1
- package/arktype/dist/arktype.mjs +1 -1
- package/arktype/dist/arktype.modern.mjs +1 -1
- package/arktype/dist/arktype.modern.mjs.map +1 -1
- package/arktype/dist/arktype.module.js +1 -1
- package/arktype/dist/arktype.module.js.map +1 -1
- package/arktype/dist/arktype.umd.js +1 -1
- package/arktype/dist/arktype.umd.js.map +1 -1
- package/arktype/dist/index.d.ts +0 -1
- package/arktype/package.json +1 -1
- package/arktype/src/__tests__/Form-native-validation.tsx +3 -3
- package/arktype/src/__tests__/Form.tsx +34 -8
- package/arktype/src/__tests__/__fixtures__/data.ts +2 -2
- package/arktype/src/__tests__/__snapshots__/arktype.ts.snap +22 -415
- package/arktype/src/arktype.ts +46 -15
- package/arktype/src/index.ts +0 -1
- package/class-validator/dist/class-validator.d.ts +29 -2
- package/class-validator/dist/class-validator.js +1 -1
- package/class-validator/dist/class-validator.js.map +1 -1
- package/class-validator/dist/class-validator.mjs +1 -1
- package/class-validator/dist/class-validator.modern.mjs +1 -1
- package/class-validator/dist/class-validator.modern.mjs.map +1 -1
- package/class-validator/dist/class-validator.module.js +1 -1
- package/class-validator/dist/class-validator.module.js.map +1 -1
- package/class-validator/dist/class-validator.umd.js +1 -1
- package/class-validator/dist/class-validator.umd.js.map +1 -1
- package/class-validator/dist/index.d.ts +0 -1
- package/class-validator/src/__tests__/Form.tsx +26 -0
- package/class-validator/src/__tests__/__fixtures__/data.ts +1 -1
- package/class-validator/src/__tests__/class-validator.ts +22 -11
- package/class-validator/src/class-validator.ts +47 -13
- package/class-validator/src/index.ts +0 -1
- package/computed-types/dist/computed-types.d.ts +18 -2
- package/computed-types/dist/computed-types.js.map +1 -1
- package/computed-types/dist/computed-types.mjs +1 -1
- package/computed-types/dist/computed-types.modern.mjs +1 -1
- package/computed-types/dist/computed-types.modern.mjs.map +1 -1
- package/computed-types/dist/computed-types.module.js +1 -1
- package/computed-types/dist/computed-types.module.js.map +1 -1
- package/computed-types/dist/computed-types.umd.js.map +1 -1
- package/computed-types/dist/index.d.ts +0 -1
- package/computed-types/src/__tests__/Form-native-validation.tsx +2 -4
- package/computed-types/src/__tests__/Form.tsx +30 -6
- package/computed-types/src/__tests__/__fixtures__/data.ts +1 -1
- package/computed-types/src/__tests__/computed-types.ts +2 -0
- package/computed-types/src/computed-types.ts +24 -7
- package/computed-types/src/index.ts +0 -1
- package/dist/resolvers.js +1 -1
- package/dist/resolvers.js.map +1 -1
- package/dist/resolvers.mjs +1 -1
- package/dist/resolvers.mjs.map +1 -1
- package/dist/resolvers.module.js +1 -1
- package/dist/resolvers.module.js.map +1 -1
- package/dist/resolvers.umd.js +1 -1
- package/dist/resolvers.umd.js.map +1 -1
- package/effect-ts/dist/effect-ts.d.ts +19 -2
- package/effect-ts/dist/effect-ts.js +1 -1
- package/effect-ts/dist/effect-ts.js.map +1 -1
- package/effect-ts/dist/effect-ts.mjs +1 -1
- package/effect-ts/dist/effect-ts.modern.mjs +1 -1
- package/effect-ts/dist/effect-ts.modern.mjs.map +1 -1
- package/effect-ts/dist/effect-ts.module.js +1 -1
- package/effect-ts/dist/effect-ts.module.js.map +1 -1
- package/effect-ts/dist/effect-ts.umd.js +1 -1
- package/effect-ts/dist/effect-ts.umd.js.map +1 -1
- package/effect-ts/dist/index.d.ts +0 -1
- package/effect-ts/src/__tests__/Form.tsx +30 -4
- package/effect-ts/src/__tests__/__fixtures__/data.ts +1 -1
- package/effect-ts/src/__tests__/__snapshots__/effect-ts.ts.snap +35 -1
- package/effect-ts/src/__tests__/effect-ts.ts +61 -0
- package/effect-ts/src/effect-ts.ts +60 -13
- package/effect-ts/src/index.ts +0 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.d.ts +21 -0
- package/fluentvalidation-ts/dist/fluentvalidation-ts.js +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.js.map +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.mjs +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.modern.mjs +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.modern.mjs.map +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.module.js +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.module.js.map +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.umd.js +1 -1
- package/fluentvalidation-ts/dist/fluentvalidation-ts.umd.js.map +1 -1
- package/fluentvalidation-ts/src/fluentvalidation-ts.ts +24 -3
- package/io-ts/dist/errorsToRecord.d.ts +5 -1
- package/io-ts/dist/index.d.ts +0 -1
- package/io-ts/dist/io-ts.d.ts +19 -2
- package/io-ts/dist/io-ts.js +1 -1
- package/io-ts/dist/io-ts.js.map +1 -1
- package/io-ts/dist/io-ts.mjs +1 -1
- package/io-ts/dist/io-ts.modern.mjs +1 -1
- package/io-ts/dist/io-ts.modern.mjs.map +1 -1
- package/io-ts/dist/io-ts.module.js +1 -1
- package/io-ts/dist/io-ts.module.js.map +1 -1
- package/io-ts/dist/io-ts.umd.js +1 -1
- package/io-ts/dist/io-ts.umd.js.map +1 -1
- package/io-ts/src/__tests__/Form-native-validation.tsx +4 -11
- package/io-ts/src/__tests__/Form.tsx +30 -6
- package/io-ts/src/__tests__/__fixtures__/data.ts +2 -19
- package/io-ts/src/errorsToRecord.ts +4 -1
- package/io-ts/src/index.ts +0 -1
- package/io-ts/src/io-ts.ts +47 -25
- package/joi/dist/joi.d.ts +17 -0
- package/joi/dist/joi.js.map +1 -1
- package/joi/dist/joi.modern.mjs.map +1 -1
- package/joi/dist/joi.module.js.map +1 -1
- package/joi/dist/joi.umd.js.map +1 -1
- package/joi/src/joi.ts +17 -0
- package/nope/dist/nope.d.ts +17 -0
- package/nope/dist/nope.js +1 -1
- package/nope/dist/nope.js.map +1 -1
- package/nope/dist/nope.mjs +1 -1
- package/nope/dist/nope.modern.mjs.map +1 -1
- package/nope/dist/nope.module.js +1 -1
- package/nope/dist/nope.module.js.map +1 -1
- package/nope/dist/nope.umd.js +1 -1
- package/nope/dist/nope.umd.js.map +1 -1
- package/nope/src/nope.ts +17 -0
- package/package.json +49 -34
- package/standard-schema/dist/index.d.ts +1 -0
- package/standard-schema/dist/standard-schema.d.ts +25 -0
- package/standard-schema/dist/standard-schema.js +2 -0
- package/standard-schema/dist/standard-schema.js.map +1 -0
- package/standard-schema/dist/standard-schema.mjs +2 -0
- package/standard-schema/dist/standard-schema.modern.mjs +2 -0
- package/standard-schema/dist/standard-schema.modern.mjs.map +1 -0
- package/standard-schema/dist/standard-schema.module.js +2 -0
- package/standard-schema/dist/standard-schema.module.js.map +1 -0
- package/standard-schema/dist/standard-schema.umd.js +2 -0
- package/standard-schema/dist/standard-schema.umd.js.map +1 -0
- package/standard-schema/package.json +18 -0
- package/standard-schema/src/__tests__/Form-native-validation.tsx +82 -0
- package/standard-schema/src/__tests__/Form.tsx +82 -0
- package/standard-schema/src/__tests__/__fixtures__/data.ts +88 -0
- package/standard-schema/src/__tests__/__snapshots__/standard-schema.ts.snap +250 -0
- package/standard-schema/src/__tests__/standard-schema.ts +56 -0
- package/standard-schema/src/index.ts +1 -0
- package/standard-schema/src/standard-schema.ts +88 -0
- package/superstruct/dist/index.d.ts +0 -1
- package/superstruct/dist/superstruct.d.ts +22 -2
- package/superstruct/dist/superstruct.js +1 -1
- package/superstruct/dist/superstruct.js.map +1 -1
- package/superstruct/dist/superstruct.mjs +1 -1
- package/superstruct/dist/superstruct.modern.mjs +1 -1
- package/superstruct/dist/superstruct.modern.mjs.map +1 -1
- package/superstruct/dist/superstruct.module.js +1 -1
- package/superstruct/dist/superstruct.module.js.map +1 -1
- package/superstruct/dist/superstruct.umd.js +1 -1
- package/superstruct/dist/superstruct.umd.js.map +1 -1
- package/superstruct/src/__tests__/Form.tsx +26 -0
- package/superstruct/src/__tests__/__fixtures__/data.ts +1 -1
- package/superstruct/src/index.ts +0 -1
- package/superstruct/src/superstruct.ts +32 -10
- package/typanion/dist/index.d.ts +0 -1
- package/typanion/dist/typanion.d.ts +18 -2
- package/typanion/dist/typanion.js.map +1 -1
- package/typanion/dist/typanion.mjs +1 -1
- package/typanion/dist/typanion.modern.mjs +1 -1
- package/typanion/dist/typanion.modern.mjs.map +1 -1
- package/typanion/dist/typanion.module.js +1 -1
- package/typanion/dist/typanion.module.js.map +1 -1
- package/typanion/dist/typanion.umd.js.map +1 -1
- package/typanion/src/__tests__/Form-native-validation.tsx +6 -14
- package/typanion/src/__tests__/Form.tsx +32 -8
- package/typanion/src/__tests__/__fixtures__/data.ts +9 -9
- package/typanion/src/__tests__/typanion.ts +3 -3
- package/typanion/src/index.ts +0 -1
- package/typanion/src/typanion.ts +32 -9
- package/typebox/dist/index.d.ts +0 -1
- package/typebox/dist/typebox.d.ts +20 -2
- package/typebox/dist/typebox.js +1 -1
- package/typebox/dist/typebox.js.map +1 -1
- package/typebox/dist/typebox.mjs +1 -1
- package/typebox/dist/typebox.modern.mjs +1 -1
- package/typebox/dist/typebox.modern.mjs.map +1 -1
- package/typebox/dist/typebox.module.js +1 -1
- package/typebox/dist/typebox.module.js.map +1 -1
- package/typebox/dist/typebox.umd.js +1 -1
- package/typebox/dist/typebox.umd.js.map +1 -1
- package/typebox/src/__tests__/Form-compiler.tsx +4 -8
- package/typebox/src/__tests__/Form.tsx +32 -6
- package/typebox/src/__tests__/__fixtures__/data.ts +1 -1
- package/typebox/src/__tests__/__snapshots__/typebox-compiler.ts.snap +21 -21
- package/typebox/src/__tests__/__snapshots__/typebox.ts.snap +21 -21
- package/typebox/src/index.ts +0 -1
- package/typebox/src/typebox.ts +33 -7
- package/typeschema/dist/typeschema.d.ts +17 -0
- package/typeschema/dist/typeschema.js +1 -1
- package/typeschema/dist/typeschema.js.map +1 -1
- package/typeschema/dist/typeschema.mjs +1 -1
- package/typeschema/dist/typeschema.modern.mjs +1 -1
- package/typeschema/dist/typeschema.modern.mjs.map +1 -1
- package/typeschema/dist/typeschema.module.js +1 -1
- package/typeschema/dist/typeschema.module.js.map +1 -1
- package/typeschema/dist/typeschema.umd.js +1 -1
- package/typeschema/dist/typeschema.umd.js.map +1 -1
- package/typeschema/src/typeschema.ts +20 -1
- package/valibot/dist/index.d.ts +0 -1
- package/valibot/dist/valibot.d.ts +31 -2
- package/valibot/dist/valibot.js +1 -1
- package/valibot/dist/valibot.js.map +1 -1
- package/valibot/dist/valibot.mjs +1 -1
- package/valibot/dist/valibot.modern.mjs +1 -1
- package/valibot/dist/valibot.modern.mjs.map +1 -1
- package/valibot/dist/valibot.module.js +1 -1
- package/valibot/dist/valibot.module.js.map +1 -1
- package/valibot/dist/valibot.umd.js +1 -1
- package/valibot/dist/valibot.umd.js.map +1 -1
- package/valibot/package.json +1 -1
- package/valibot/src/__tests__/Form.tsx +26 -0
- package/valibot/src/__tests__/__fixtures__/data.ts +7 -3
- package/valibot/src/__tests__/valibot.ts +1 -1
- package/valibot/src/index.ts +0 -1
- package/valibot/src/valibot.ts +55 -6
- package/vest/dist/vest.d.ts +18 -0
- package/vest/dist/vest.js.map +1 -1
- package/vest/dist/vest.modern.mjs.map +1 -1
- package/vest/dist/vest.module.js.map +1 -1
- package/vest/dist/vest.umd.js.map +1 -1
- package/vest/src/vest.ts +18 -0
- package/vine/dist/index.d.ts +0 -1
- package/vine/dist/vine.d.ts +25 -2
- package/vine/dist/vine.js +1 -1
- package/vine/dist/vine.js.map +1 -1
- package/vine/dist/vine.mjs +1 -1
- package/vine/dist/vine.modern.mjs +1 -1
- package/vine/dist/vine.modern.mjs.map +1 -1
- package/vine/dist/vine.module.js +1 -1
- package/vine/dist/vine.module.js.map +1 -1
- package/vine/dist/vine.umd.js +1 -1
- package/vine/dist/vine.umd.js.map +1 -1
- package/vine/src/__tests__/Form-native-validation.tsx +2 -4
- package/vine/src/__tests__/Form.tsx +30 -6
- package/vine/src/__tests__/__fixtures__/data.ts +1 -1
- package/vine/src/index.ts +0 -1
- package/vine/src/vine.ts +38 -10
- package/yup/dist/yup.d.ts +18 -7
- package/yup/dist/yup.js +1 -1
- package/yup/dist/yup.js.map +1 -1
- package/yup/dist/yup.mjs +1 -1
- package/yup/dist/yup.modern.mjs +1 -1
- package/yup/dist/yup.modern.mjs.map +1 -1
- package/yup/dist/yup.module.js +1 -1
- package/yup/dist/yup.module.js.map +1 -1
- package/yup/dist/yup.umd.js +1 -1
- package/yup/dist/yup.umd.js.map +1 -1
- package/yup/src/yup.ts +22 -11
- package/zod/dist/index.d.ts +0 -1
- package/zod/dist/zod.d.ts +25 -2
- package/zod/dist/zod.js +1 -1
- package/zod/dist/zod.js.map +1 -1
- package/zod/dist/zod.mjs +1 -1
- package/zod/dist/zod.modern.mjs +1 -1
- package/zod/dist/zod.modern.mjs.map +1 -1
- package/zod/dist/zod.module.js +1 -1
- package/zod/dist/zod.module.js.map +1 -1
- package/zod/dist/zod.umd.js +1 -1
- package/zod/dist/zod.umd.js.map +1 -1
- package/zod/src/__tests__/Form.tsx +30 -6
- package/zod/src/__tests__/__fixtures__/data.ts +3 -3
- package/zod/src/index.ts +0 -1
- package/zod/src/zod.ts +40 -9
- package/arktype/dist/types.d.ts +0 -9
- package/arktype/src/types.ts +0 -18
- package/class-validator/dist/types.d.ts +0 -12
- package/class-validator/src/types.ts +0 -16
- package/computed-types/dist/types.d.ts +0 -2
- package/computed-types/src/types.ts +0 -13
- package/effect-ts/dist/types.d.ts +0 -4
- package/effect-ts/src/types.ts +0 -12
- package/io-ts/dist/types.d.ts +0 -7
- package/io-ts/src/types.ts +0 -18
- package/superstruct/dist/types.d.ts +0 -11
- package/superstruct/src/types.ts +0 -20
- package/typanion/dist/types.d.ts +0 -9
- package/typanion/src/types.ts +0 -20
- package/typebox/dist/types.d.ts +0 -4
- package/typebox/src/types.ts +0 -11
- package/valibot/dist/types.d.ts +0 -13
- package/valibot/src/types.ts +0 -34
- package/vine/dist/types.d.ts +0 -6
- package/vine/src/types.ts +0 -13
- package/zod/dist/types.d.ts +0 -13
- package/zod/src/types.ts +0 -22
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { ajvResolver } from '..';
|
|
2
|
+
import * as fixture from './__fixtures__/data-errors';
|
|
3
|
+
|
|
4
|
+
const shouldUseNativeValidation = false;
|
|
5
|
+
|
|
6
|
+
describe('ajvResolver with errorMessage', () => {
|
|
7
|
+
it('should return values when validation pass', async () => {
|
|
8
|
+
expect(
|
|
9
|
+
await ajvResolver(fixture.schemaA)(fixture.validDataA, undefined, {
|
|
10
|
+
fields: fixture.fieldsA,
|
|
11
|
+
criteriaMode: 'all',
|
|
12
|
+
shouldUseNativeValidation,
|
|
13
|
+
}),
|
|
14
|
+
).toEqual({
|
|
15
|
+
values: fixture.validDataA,
|
|
16
|
+
errors: {},
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should return customized error messages when validation fails', async () => {
|
|
21
|
+
expect(
|
|
22
|
+
await ajvResolver(fixture.schemaA)(
|
|
23
|
+
fixture.invalidDataA,
|
|
24
|
+
{},
|
|
25
|
+
{
|
|
26
|
+
fields: fixture.fieldsA,
|
|
27
|
+
criteriaMode: 'all',
|
|
28
|
+
shouldUseNativeValidation,
|
|
29
|
+
},
|
|
30
|
+
),
|
|
31
|
+
).toMatchSnapshot();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return customized error messages when requirement fails', async () => {
|
|
35
|
+
expect(
|
|
36
|
+
await ajvResolver(fixture.schemaA)({}, undefined, {
|
|
37
|
+
fields: fixture.fieldsA,
|
|
38
|
+
criteriaMode: 'all',
|
|
39
|
+
shouldUseNativeValidation,
|
|
40
|
+
}),
|
|
41
|
+
).toMatchSnapshot();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return customized error messages when some properties are undefined', async () => {
|
|
45
|
+
expect(
|
|
46
|
+
await ajvResolver(fixture.schemaA, undefined, { mode: 'sync' })(
|
|
47
|
+
fixture.undefinedDataA,
|
|
48
|
+
undefined,
|
|
49
|
+
{
|
|
50
|
+
fields: fixture.fieldsA,
|
|
51
|
+
criteriaMode: 'all',
|
|
52
|
+
shouldUseNativeValidation,
|
|
53
|
+
},
|
|
54
|
+
),
|
|
55
|
+
).toMatchSnapshot();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should return the same customized message for all validation failures', async () => {
|
|
59
|
+
expect(
|
|
60
|
+
await ajvResolver(fixture.schemaB)(
|
|
61
|
+
fixture.invalidDataB,
|
|
62
|
+
{},
|
|
63
|
+
{
|
|
64
|
+
fields: fixture.fieldsRest,
|
|
65
|
+
criteriaMode: 'all',
|
|
66
|
+
shouldUseNativeValidation,
|
|
67
|
+
},
|
|
68
|
+
),
|
|
69
|
+
).toMatchSnapshot();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should return the same customized error message when requirement fails', async () => {
|
|
73
|
+
expect(
|
|
74
|
+
await ajvResolver(fixture.schemaB)({}, undefined, {
|
|
75
|
+
fields: fixture.fieldsRest,
|
|
76
|
+
criteriaMode: 'all',
|
|
77
|
+
shouldUseNativeValidation,
|
|
78
|
+
}),
|
|
79
|
+
).toMatchSnapshot();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should return the same customized message when some properties are undefined', async () => {
|
|
83
|
+
expect(
|
|
84
|
+
await ajvResolver(fixture.schemaB)(fixture.undefinedDataB, undefined, {
|
|
85
|
+
fields: fixture.fieldsRest,
|
|
86
|
+
criteriaMode: 'all',
|
|
87
|
+
shouldUseNativeValidation,
|
|
88
|
+
}),
|
|
89
|
+
).toMatchSnapshot();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should return customized error messages for certain keywords when walidation fails', async () => {
|
|
93
|
+
expect(
|
|
94
|
+
await ajvResolver(fixture.schemaC)(
|
|
95
|
+
fixture.invalidDataC,
|
|
96
|
+
{},
|
|
97
|
+
{
|
|
98
|
+
fields: fixture.fieldsRest,
|
|
99
|
+
criteriaMode: 'all',
|
|
100
|
+
shouldUseNativeValidation,
|
|
101
|
+
},
|
|
102
|
+
),
|
|
103
|
+
).toMatchSnapshot();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should return customized error messages for certain keywords when requirement fails', async () => {
|
|
107
|
+
expect(
|
|
108
|
+
await ajvResolver(fixture.schemaC)({}, undefined, {
|
|
109
|
+
fields: fixture.fieldsRest,
|
|
110
|
+
criteriaMode: 'all',
|
|
111
|
+
shouldUseNativeValidation,
|
|
112
|
+
}),
|
|
113
|
+
).toMatchSnapshot();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should return customized error messages for certain keywords when some properties are undefined', async () => {
|
|
117
|
+
expect(
|
|
118
|
+
await ajvResolver(fixture.schemaC)(fixture.undefinedDataC, undefined, {
|
|
119
|
+
fields: fixture.fieldsRest,
|
|
120
|
+
criteriaMode: 'all',
|
|
121
|
+
shouldUseNativeValidation,
|
|
122
|
+
}),
|
|
123
|
+
).toMatchSnapshot();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should return different messages for different properties when walidation fails', async () => {
|
|
127
|
+
expect(
|
|
128
|
+
await ajvResolver(fixture.schemaD)(
|
|
129
|
+
fixture.invalidDataD,
|
|
130
|
+
{},
|
|
131
|
+
{
|
|
132
|
+
fields: fixture.fieldsRest,
|
|
133
|
+
criteriaMode: 'all',
|
|
134
|
+
shouldUseNativeValidation,
|
|
135
|
+
},
|
|
136
|
+
),
|
|
137
|
+
).toMatchSnapshot();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should return different messages for different properties when requirement fails', async () => {
|
|
141
|
+
expect(
|
|
142
|
+
await ajvResolver(fixture.schemaD)({}, undefined, {
|
|
143
|
+
fields: fixture.fieldsRest,
|
|
144
|
+
criteriaMode: 'all',
|
|
145
|
+
shouldUseNativeValidation,
|
|
146
|
+
}),
|
|
147
|
+
).toMatchSnapshot();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should return different messages for different properties when some properties are undefined', async () => {
|
|
151
|
+
expect(
|
|
152
|
+
await ajvResolver(fixture.schemaD)(fixture.undefinedDataD, undefined, {
|
|
153
|
+
fields: fixture.fieldsRest,
|
|
154
|
+
criteriaMode: 'all',
|
|
155
|
+
shouldUseNativeValidation,
|
|
156
|
+
}),
|
|
157
|
+
).toMatchSnapshot();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should return customized errors for properties/items when walidation fails', async () => {
|
|
161
|
+
expect(
|
|
162
|
+
await ajvResolver(fixture.schemaE)(
|
|
163
|
+
fixture.invalidDataE,
|
|
164
|
+
{},
|
|
165
|
+
{
|
|
166
|
+
fields: fixture.fieldsRest,
|
|
167
|
+
criteriaMode: 'all',
|
|
168
|
+
shouldUseNativeValidation,
|
|
169
|
+
},
|
|
170
|
+
),
|
|
171
|
+
).toMatchSnapshot();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should return customized errors for properties/items when requirement fails', async () => {
|
|
175
|
+
expect(
|
|
176
|
+
await ajvResolver(fixture.schemaE)({}, undefined, {
|
|
177
|
+
fields: fixture.fieldsRest,
|
|
178
|
+
criteriaMode: 'all',
|
|
179
|
+
shouldUseNativeValidation,
|
|
180
|
+
}),
|
|
181
|
+
).toMatchSnapshot();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('should return customized errors for properties/items when some properties are undefined', async () => {
|
|
185
|
+
expect(
|
|
186
|
+
await ajvResolver(fixture.schemaE)(fixture.undefinedDataE, undefined, {
|
|
187
|
+
fields: fixture.fieldsRest,
|
|
188
|
+
criteriaMode: 'all',
|
|
189
|
+
shouldUseNativeValidation,
|
|
190
|
+
}),
|
|
191
|
+
).toMatchSnapshot();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('should return a default message if there is no specific message for the error when walidation fails', async () => {
|
|
195
|
+
expect(
|
|
196
|
+
await ajvResolver(fixture.schemaF)(
|
|
197
|
+
fixture.invalidDataF,
|
|
198
|
+
{},
|
|
199
|
+
{
|
|
200
|
+
fields: fixture.fieldsRest,
|
|
201
|
+
criteriaMode: 'all',
|
|
202
|
+
shouldUseNativeValidation,
|
|
203
|
+
},
|
|
204
|
+
),
|
|
205
|
+
).toMatchSnapshot();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should return a default message if there is no specific message for the error when requirement fails', async () => {
|
|
209
|
+
expect(
|
|
210
|
+
await ajvResolver(fixture.schemaF)({}, undefined, {
|
|
211
|
+
fields: fixture.fieldsRest,
|
|
212
|
+
criteriaMode: 'all',
|
|
213
|
+
shouldUseNativeValidation,
|
|
214
|
+
}),
|
|
215
|
+
).toMatchSnapshot();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should return a default message if there is no specific message for the error when some properties are undefined', async () => {
|
|
219
|
+
expect(
|
|
220
|
+
await ajvResolver(fixture.schemaF)(fixture.undefinedDataF, undefined, {
|
|
221
|
+
fields: fixture.fieldsRest,
|
|
222
|
+
criteriaMode: 'all',
|
|
223
|
+
shouldUseNativeValidation,
|
|
224
|
+
}),
|
|
225
|
+
).toMatchSnapshot();
|
|
226
|
+
});
|
|
227
|
+
});
|
package/ajv/src/ajv.ts
CHANGED
|
@@ -2,49 +2,82 @@ import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';
|
|
|
2
2
|
import Ajv, { DefinedError } from 'ajv';
|
|
3
3
|
import ajvErrors from 'ajv-errors';
|
|
4
4
|
import { FieldError, appendErrors } from 'react-hook-form';
|
|
5
|
-
import { Resolver } from './types';
|
|
5
|
+
import { AjvError, Resolver } from './types';
|
|
6
6
|
|
|
7
7
|
const parseErrorSchema = (
|
|
8
|
-
ajvErrors:
|
|
8
|
+
ajvErrors: AjvError[],
|
|
9
9
|
validateAllFieldCriteria: boolean,
|
|
10
10
|
) => {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const parsedErrors: Record<string, FieldError> = {};
|
|
12
|
+
|
|
13
|
+
const reduceError = (error: AjvError) => {
|
|
14
|
+
// Ajv will return empty instancePath when require error
|
|
13
15
|
if (error.keyword === 'required') {
|
|
14
|
-
error.instancePath +=
|
|
16
|
+
error.instancePath += `/${error.params.missingProperty}`;
|
|
15
17
|
}
|
|
16
|
-
});
|
|
17
18
|
|
|
18
|
-
return ajvErrors.reduce<Record<string, FieldError>>((previous, error) => {
|
|
19
19
|
// `/deepObject/data` -> `deepObject.data`
|
|
20
20
|
const path = error.instancePath.substring(1).replace(/\//g, '.');
|
|
21
21
|
|
|
22
|
-
if (!
|
|
23
|
-
|
|
22
|
+
if (!parsedErrors[path]) {
|
|
23
|
+
parsedErrors[path] = {
|
|
24
24
|
message: error.message,
|
|
25
25
|
type: error.keyword,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (validateAllFieldCriteria) {
|
|
30
|
-
const types =
|
|
30
|
+
const types = parsedErrors[path].types;
|
|
31
31
|
const messages = types && types[error.keyword];
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
parsedErrors[path] = appendErrors(
|
|
34
34
|
path,
|
|
35
35
|
validateAllFieldCriteria,
|
|
36
|
-
|
|
36
|
+
parsedErrors,
|
|
37
37
|
error.keyword,
|
|
38
38
|
messages
|
|
39
39
|
? ([] as string[]).concat(messages as string[], error.message || '')
|
|
40
40
|
: error.message,
|
|
41
41
|
) as FieldError;
|
|
42
42
|
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
for (let index = 0; index < ajvErrors.length; index += 1) {
|
|
46
|
+
const error = ajvErrors[index];
|
|
47
|
+
|
|
48
|
+
if (error.keyword === 'errorMessage') {
|
|
49
|
+
error.params.errors.forEach((originalError) => {
|
|
50
|
+
originalError.message = error.message;
|
|
51
|
+
reduceError(originalError);
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
reduceError(error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
43
57
|
|
|
44
|
-
|
|
45
|
-
}, {});
|
|
58
|
+
return parsedErrors;
|
|
46
59
|
};
|
|
47
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Creates a resolver for react-hook-form using Ajv schema validation
|
|
63
|
+
* @param {Schema} schema - The Ajv schema to validate against
|
|
64
|
+
* @param {Object} schemaOptions - Additional schema validation options
|
|
65
|
+
* @param {Object} resolverOptions - Additional resolver configuration
|
|
66
|
+
* @param {string} [resolverOptions.mode='async'] - Validation mode
|
|
67
|
+
* @returns {Resolver<Schema>} A resolver function compatible with react-hook-form
|
|
68
|
+
* @example
|
|
69
|
+
* const schema = ajv.compile({
|
|
70
|
+
* type: 'object',
|
|
71
|
+
* properties: {
|
|
72
|
+
* name: { type: 'string' },
|
|
73
|
+
* age: { type: 'number' }
|
|
74
|
+
* }
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* useForm({
|
|
78
|
+
* resolver: ajvResolver(schema)
|
|
79
|
+
* });
|
|
80
|
+
*/
|
|
48
81
|
export const ajvResolver: Resolver =
|
|
49
82
|
(schema, schemaOptions, resolverOptions = {}) =>
|
|
50
83
|
async (values, _, options) => {
|
package/ajv/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Ajv from 'ajv';
|
|
2
|
+
import type { DefinedError, ErrorObject } from 'ajv';
|
|
2
3
|
import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
|
|
3
4
|
|
|
4
5
|
export type Resolver = <T>(
|
|
@@ -10,3 +11,10 @@ export type Resolver = <T>(
|
|
|
10
11
|
context: TContext | undefined,
|
|
11
12
|
options: ResolverOptions<TFieldValues>,
|
|
12
13
|
) => Promise<ResolverResult<TFieldValues>>;
|
|
14
|
+
|
|
15
|
+
// ajv doesn't export any types for errors with `keyword='errorMessage'`
|
|
16
|
+
type ErrorMessage = ErrorObject<
|
|
17
|
+
'errorMessage',
|
|
18
|
+
{ errors: (DefinedError & { emUsed: boolean })[] }
|
|
19
|
+
>;
|
|
20
|
+
export type AjvError = ErrorMessage | DefinedError;
|
|
@@ -1,2 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { Type } from 'arktype';
|
|
2
|
+
import { Resolver } from 'react-hook-form';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a resolver for react-hook-form using Arktype schema validation
|
|
5
|
+
* @param {Schema} schema - The Arktype schema to validate against
|
|
6
|
+
* @param {Object} resolverOptions - Additional resolver configuration
|
|
7
|
+
* @param {string} [resolverOptions.mode='raw'] - Return the raw input values rather than the parsed values
|
|
8
|
+
* @returns {Resolver<Schema['inferOut']>} A resolver function compatible with react-hook-form
|
|
9
|
+
* @example
|
|
10
|
+
* const schema = type({
|
|
11
|
+
* username: 'string>2'
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* useForm({
|
|
15
|
+
* resolver: arktypeResolver(schema)
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
export declare function arktypeResolver<Schema extends Type<any, any>>(schema: Schema, _schemaOptions?: never, resolverOptions?: {
|
|
19
|
+
raw?: boolean;
|
|
20
|
+
}): Resolver<Schema['inferOut']>;
|
package/arktype/dist/arktype.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var r=require("@hookform/resolvers"),e=require("arktype");exports.arktypeResolver=function(
|
|
1
|
+
var r=require("@hookform/resolvers"),e=require("arktype");function o(r){for(var e=[].concat(r),o={};e.length;){var s=e[0],t=s.path.join(".");o[t]||(o[t]={message:s.message,type:s.code}),e.shift()}return o}exports.arktypeResolver=function(s,t,a){return void 0===a&&(a={}),function(t,i,n){var v=s(t);return v instanceof e.ArkErrors?{values:{},errors:r.toNestErrors(o(v),n)}:(n.shouldUseNativeValidation&&r.validateFieldsNatively({},n),{errors:{},values:a.raw?Object.assign({},t):v})}};
|
|
2
2
|
//# sourceMappingURL=arktype.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arktype.js","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors } from 'arktype';\nimport { FieldError, FieldErrors } from 'react-hook-form';\
|
|
1
|
+
{"version":3,"file":"arktype.js","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors, Type } from 'arktype';\nimport { FieldError, FieldErrors, Resolver } from 'react-hook-form';\n\nfunction parseErrorSchema(arkErrors: ArkErrors): Record<string, FieldError> {\n const errors = [...arkErrors];\n const fieldsErrors: Record<string, FieldError> = {};\n\n for (; errors.length; ) {\n const error = errors[0];\n const _path = error.path.join('.');\n\n if (!fieldsErrors[_path]) {\n fieldsErrors[_path] = { message: error.message, type: error.code };\n }\n\n errors.shift();\n }\n\n return fieldsErrors;\n}\n\n/**\n * Creates a resolver for react-hook-form using Arktype schema validation\n * @param {Schema} schema - The Arktype schema to validate against\n * @param {Object} resolverOptions - Additional resolver configuration\n * @param {string} [resolverOptions.mode='raw'] - Return the raw input values rather than the parsed values\n * @returns {Resolver<Schema['inferOut']>} A resolver function compatible with react-hook-form\n * @example\n * const schema = type({\n * username: 'string>2'\n * });\n *\n * useForm({\n * resolver: arktypeResolver(schema)\n * });\n */\nexport function arktypeResolver<Schema extends Type<any, any>>(\n schema: Schema,\n _schemaOptions?: never,\n resolverOptions: {\n raw?: boolean;\n } = {},\n): Resolver<Schema['inferOut']> {\n return (values, _, options) => {\n const out = schema(values);\n\n if (out instanceof ArkErrors) {\n return {\n values: {},\n errors: toNestErrors(parseErrorSchema(out), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? Object.assign({}, values) : out,\n };\n };\n}\n"],"names":["parseErrorSchema","arkErrors","errors","concat","fieldsErrors","length","error","_path","path","join","message","type","code","shift","schema","_schemaOptions","resolverOptions","values","_","options","out","ArkErrors","toNestErrors","shouldUseNativeValidation","validateFieldsNatively","raw","Object","assign"],"mappings":"0DAIA,SAASA,EAAiBC,GAIxB,IAHA,IAAMC,EAAMC,GAAAA,OAAOF,GACbG,EAA2C,CAAE,EAE5CF,EAAOG,QAAU,CACtB,IAAMC,EAAQJ,EAAO,GACfK,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAaG,KAChBH,EAAaG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAG9DV,EAAOW,OACT,CAEA,OAAOT,CACT,kCAkBEU,EACAC,EACAC,GAIA,gBAJAA,IAAAA,EAEI,CAAE,GAEEC,SAAAA,EAAQC,EAAGC,GACjB,IAAMC,EAAMN,EAAOG,GAEnB,OAAIG,aAAeC,YACV,CACLJ,OAAQ,CAAE,EACVf,OAAQoB,EAAAA,aAAatB,EAAiBoB,GAAMD,KAIhDA,EAAQI,2BAA6BC,yBAAuB,CAAA,EAAIL,GAEzD,CACLjB,OAAQ,GACRe,OAAQD,EAAgBS,IAAMC,OAAOC,OAAO,GAAIV,GAAUG,GAE9D,CACF"}
|
package/arktype/dist/arktype.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{toNestErrors as r,validateFieldsNatively as
|
|
1
|
+
import{toNestErrors as r,validateFieldsNatively as e}from"@hookform/resolvers";import{ArkErrors as o}from"arktype";function t(r){for(var e=[].concat(r),o={};e.length;){var t=e[0],a=t.path.join(".");o[a]||(o[a]={message:t.message,type:t.code}),e.shift()}return o}function a(a,n,s){return void 0===s&&(s={}),function(n,i,f){var u=a(n);return u instanceof o?{values:{},errors:r(t(u),f)}:(f.shouldUseNativeValidation&&e({},f),{errors:{},values:s.raw?Object.assign({},n):u})}}export{a as arktypeResolver};
|
|
2
2
|
//# sourceMappingURL=arktype.module.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{toNestErrors as r,validateFieldsNatively as
|
|
1
|
+
import{toNestErrors as r,validateFieldsNatively as e}from"@hookform/resolvers";import{ArkErrors as o}from"arktype";function t(r){const e=[...r],o={};for(;e.length;){const r=e[0],t=r.path.join(".");o[t]||(o[t]={message:r.message,type:r.code}),e.shift()}return o}function s(s,n,a={}){return(n,i,c)=>{const f=s(n);return f instanceof o?{values:{},errors:r(t(f),c)}:(c.shouldUseNativeValidation&&e({},c),{errors:{},values:a.raw?Object.assign({},n):f})}}export{s as arktypeResolver};
|
|
2
2
|
//# sourceMappingURL=arktype.modern.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arktype.modern.mjs","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors } from 'arktype';\nimport { FieldError, FieldErrors } from 'react-hook-form';\
|
|
1
|
+
{"version":3,"file":"arktype.modern.mjs","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors, Type } from 'arktype';\nimport { FieldError, FieldErrors, Resolver } from 'react-hook-form';\n\nfunction parseErrorSchema(arkErrors: ArkErrors): Record<string, FieldError> {\n const errors = [...arkErrors];\n const fieldsErrors: Record<string, FieldError> = {};\n\n for (; errors.length; ) {\n const error = errors[0];\n const _path = error.path.join('.');\n\n if (!fieldsErrors[_path]) {\n fieldsErrors[_path] = { message: error.message, type: error.code };\n }\n\n errors.shift();\n }\n\n return fieldsErrors;\n}\n\n/**\n * Creates a resolver for react-hook-form using Arktype schema validation\n * @param {Schema} schema - The Arktype schema to validate against\n * @param {Object} resolverOptions - Additional resolver configuration\n * @param {string} [resolverOptions.mode='raw'] - Return the raw input values rather than the parsed values\n * @returns {Resolver<Schema['inferOut']>} A resolver function compatible with react-hook-form\n * @example\n * const schema = type({\n * username: 'string>2'\n * });\n *\n * useForm({\n * resolver: arktypeResolver(schema)\n * });\n */\nexport function arktypeResolver<Schema extends Type<any, any>>(\n schema: Schema,\n _schemaOptions?: never,\n resolverOptions: {\n raw?: boolean;\n } = {},\n): Resolver<Schema['inferOut']> {\n return (values, _, options) => {\n const out = schema(values);\n\n if (out instanceof ArkErrors) {\n return {\n values: {},\n errors: toNestErrors(parseErrorSchema(out), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? Object.assign({}, values) : out,\n };\n };\n}\n"],"names":["parseErrorSchema","arkErrors","errors","fieldsErrors","length","error","_path","path","join","message","type","code","shift","arktypeResolver","schema","_schemaOptions","resolverOptions","values","_","options","out","ArkErrors","toNestErrors","shouldUseNativeValidation","validateFieldsNatively","raw","Object","assign"],"mappings":"mHAIA,SAASA,EAAiBC,GACxB,MAAMC,EAAS,IAAID,GACbE,EAA2C,GAEjD,KAAOD,EAAOE,QAAU,CACtB,MAAMC,EAAQH,EAAO,GACfI,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAaG,KAChBH,EAAaG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAG9DT,EAAOU,OACT,CAEA,OAAOT,CACT,CAiBM,SAAUU,EACdC,EACAC,EACAC,EAEI,CAAE,GAEN,MAAO,CAACC,EAAQC,EAAGC,KACjB,MAAMC,EAAMN,EAAOG,GAEnB,OAAIG,aAAeC,EACV,CACLJ,OAAQ,CAAE,EACVf,OAAQoB,EAAatB,EAAiBoB,GAAMD,KAIhDA,EAAQI,2BAA6BC,EAAuB,CAAE,EAAEL,GAEzD,CACLjB,OAAQ,CAAA,EACRe,OAAQD,EAAgBS,IAAMC,OAAOC,OAAO,GAAIV,GAAUG,IAGhE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{toNestErrors as r,validateFieldsNatively as
|
|
1
|
+
import{toNestErrors as r,validateFieldsNatively as e}from"@hookform/resolvers";import{ArkErrors as o}from"arktype";function t(r){for(var e=[].concat(r),o={};e.length;){var t=e[0],a=t.path.join(".");o[a]||(o[a]={message:t.message,type:t.code}),e.shift()}return o}function a(a,n,s){return void 0===s&&(s={}),function(n,i,f){var u=a(n);return u instanceof o?{values:{},errors:r(t(u),f)}:(f.shouldUseNativeValidation&&e({},f),{errors:{},values:s.raw?Object.assign({},n):u})}}export{a as arktypeResolver};
|
|
2
2
|
//# sourceMappingURL=arktype.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arktype.module.js","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors } from 'arktype';\nimport { FieldError, FieldErrors } from 'react-hook-form';\
|
|
1
|
+
{"version":3,"file":"arktype.module.js","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors, Type } from 'arktype';\nimport { FieldError, FieldErrors, Resolver } from 'react-hook-form';\n\nfunction parseErrorSchema(arkErrors: ArkErrors): Record<string, FieldError> {\n const errors = [...arkErrors];\n const fieldsErrors: Record<string, FieldError> = {};\n\n for (; errors.length; ) {\n const error = errors[0];\n const _path = error.path.join('.');\n\n if (!fieldsErrors[_path]) {\n fieldsErrors[_path] = { message: error.message, type: error.code };\n }\n\n errors.shift();\n }\n\n return fieldsErrors;\n}\n\n/**\n * Creates a resolver for react-hook-form using Arktype schema validation\n * @param {Schema} schema - The Arktype schema to validate against\n * @param {Object} resolverOptions - Additional resolver configuration\n * @param {string} [resolverOptions.mode='raw'] - Return the raw input values rather than the parsed values\n * @returns {Resolver<Schema['inferOut']>} A resolver function compatible with react-hook-form\n * @example\n * const schema = type({\n * username: 'string>2'\n * });\n *\n * useForm({\n * resolver: arktypeResolver(schema)\n * });\n */\nexport function arktypeResolver<Schema extends Type<any, any>>(\n schema: Schema,\n _schemaOptions?: never,\n resolverOptions: {\n raw?: boolean;\n } = {},\n): Resolver<Schema['inferOut']> {\n return (values, _, options) => {\n const out = schema(values);\n\n if (out instanceof ArkErrors) {\n return {\n values: {},\n errors: toNestErrors(parseErrorSchema(out), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? Object.assign({}, values) : out,\n };\n };\n}\n"],"names":["parseErrorSchema","arkErrors","errors","concat","fieldsErrors","length","error","_path","path","join","message","type","code","shift","arktypeResolver","schema","_schemaOptions","resolverOptions","values","_","options","out","ArkErrors","toNestErrors","shouldUseNativeValidation","validateFieldsNatively","raw","Object","assign"],"mappings":"mHAIA,SAASA,EAAiBC,GAIxB,IAHA,IAAMC,EAAMC,GAAAA,OAAOF,GACbG,EAA2C,CAAE,EAE5CF,EAAOG,QAAU,CACtB,IAAMC,EAAQJ,EAAO,GACfK,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAaG,KAChBH,EAAaG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAG9DV,EAAOW,OACT,CAEA,OAAOT,CACT,UAiBgBU,EACdC,EACAC,EACAC,GAIA,gBAJAA,IAAAA,EAEI,CAAE,GAEEC,SAAAA,EAAQC,EAAGC,GACjB,IAAMC,EAAMN,EAAOG,GAEnB,OAAIG,aAAeC,EACV,CACLJ,OAAQ,CAAE,EACVhB,OAAQqB,EAAavB,EAAiBqB,GAAMD,KAIhDA,EAAQI,2BAA6BC,EAAuB,CAAA,EAAIL,GAEzD,CACLlB,OAAQ,GACRgB,OAAQD,EAAgBS,IAAMC,OAAOC,OAAO,GAAIV,GAAUG,GAE9D,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("@hookform/resolvers"),require("arktype")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers","arktype"],o):o((e||self).hookformResolversArktype={},e.hookformResolvers,e.arktype)}(this,function(e,o,r){e.arktypeResolver=function(e,
|
|
1
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("@hookform/resolvers"),require("arktype")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers","arktype"],o):o((e||self).hookformResolversArktype={},e.hookformResolvers,e.arktype)}(this,function(e,o,r){function t(e){for(var o=[].concat(e),r={};o.length;){var t=o[0],s=t.path.join(".");r[s]||(r[s]={message:t.message,type:t.code}),o.shift()}return r}e.arktypeResolver=function(e,s,n){return void 0===n&&(n={}),function(s,i,a){var f=e(s);return f instanceof r.ArkErrors?{values:{},errors:o.toNestErrors(t(f),a)}:(a.shouldUseNativeValidation&&o.validateFieldsNatively({},a),{errors:{},values:n.raw?Object.assign({},s):f})}}});
|
|
2
2
|
//# sourceMappingURL=arktype.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arktype.umd.js","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors } from 'arktype';\nimport { FieldError, FieldErrors } from 'react-hook-form';\
|
|
1
|
+
{"version":3,"file":"arktype.umd.js","sources":["../src/arktype.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { ArkErrors, Type } from 'arktype';\nimport { FieldError, FieldErrors, Resolver } from 'react-hook-form';\n\nfunction parseErrorSchema(arkErrors: ArkErrors): Record<string, FieldError> {\n const errors = [...arkErrors];\n const fieldsErrors: Record<string, FieldError> = {};\n\n for (; errors.length; ) {\n const error = errors[0];\n const _path = error.path.join('.');\n\n if (!fieldsErrors[_path]) {\n fieldsErrors[_path] = { message: error.message, type: error.code };\n }\n\n errors.shift();\n }\n\n return fieldsErrors;\n}\n\n/**\n * Creates a resolver for react-hook-form using Arktype schema validation\n * @param {Schema} schema - The Arktype schema to validate against\n * @param {Object} resolverOptions - Additional resolver configuration\n * @param {string} [resolverOptions.mode='raw'] - Return the raw input values rather than the parsed values\n * @returns {Resolver<Schema['inferOut']>} A resolver function compatible with react-hook-form\n * @example\n * const schema = type({\n * username: 'string>2'\n * });\n *\n * useForm({\n * resolver: arktypeResolver(schema)\n * });\n */\nexport function arktypeResolver<Schema extends Type<any, any>>(\n schema: Schema,\n _schemaOptions?: never,\n resolverOptions: {\n raw?: boolean;\n } = {},\n): Resolver<Schema['inferOut']> {\n return (values, _, options) => {\n const out = schema(values);\n\n if (out instanceof ArkErrors) {\n return {\n values: {},\n errors: toNestErrors(parseErrorSchema(out), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? Object.assign({}, values) : out,\n };\n };\n}\n"],"names":["parseErrorSchema","arkErrors","errors","concat","fieldsErrors","length","error","_path","path","join","message","type","code","shift","schema","_schemaOptions","resolverOptions","values","_","options","out","ArkErrors","toNestErrors","shouldUseNativeValidation","validateFieldsNatively","raw","Object","assign"],"mappings":"sWAIA,SAASA,EAAiBC,GAIxB,IAHA,IAAMC,EAAMC,GAAAA,OAAOF,GACbG,EAA2C,CAAE,EAE5CF,EAAOG,QAAU,CACtB,IAAMC,EAAQJ,EAAO,GACfK,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAaG,KAChBH,EAAaG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAG9DV,EAAOW,OACT,CAEA,OAAOT,CACT,4BAkBEU,EACAC,EACAC,GAIA,gBAJAA,IAAAA,EAEI,CAAE,GAEEC,SAAAA,EAAQC,EAAGC,GACjB,IAAMC,EAAMN,EAAOG,GAEnB,OAAIG,aAAeC,YACV,CACLJ,OAAQ,CAAE,EACVf,OAAQoB,EAAAA,aAAatB,EAAiBoB,GAAMD,KAIhDA,EAAQI,2BAA6BC,yBAAuB,CAAA,EAAIL,GAEzD,CACLjB,OAAQ,GACRe,OAAQD,EAAgBS,IAAMC,OAAOC,OAAO,GAAIV,GAAUG,GAE9D,CACF"}
|
package/arktype/dist/index.d.ts
CHANGED
package/arktype/package.json
CHANGED
|
@@ -33,7 +33,7 @@ function TestComponent({ onSubmit }: Props) {
|
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
test("form's native validation with
|
|
36
|
+
test("form's native validation with Arktype", async () => {
|
|
37
37
|
const handleSubmit = vi.fn();
|
|
38
38
|
render(<TestComponent onSubmit={handleSubmit} />);
|
|
39
39
|
|
|
@@ -57,14 +57,14 @@ test("form's native validation with Zod", async () => {
|
|
|
57
57
|
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
58
58
|
expect(usernameField.validity.valid).toBe(false);
|
|
59
59
|
expect(usernameField.validationMessage).toBe(
|
|
60
|
-
'username must be
|
|
60
|
+
'username must be at least length 2',
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
// password
|
|
64
64
|
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
65
65
|
expect(passwordField.validity.valid).toBe(false);
|
|
66
66
|
expect(passwordField.validationMessage).toBe(
|
|
67
|
-
'password must be
|
|
67
|
+
'password must be at least length 2',
|
|
68
68
|
);
|
|
69
69
|
|
|
70
70
|
await user.type(screen.getByPlaceholderText(/username/i), 'joe');
|
|
@@ -12,16 +12,16 @@ const schema = type({
|
|
|
12
12
|
|
|
13
13
|
type FormData = typeof schema.infer & { unusedProperty: string };
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
onSubmit
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
function TestComponent({
|
|
16
|
+
onSubmit,
|
|
17
|
+
}: {
|
|
18
|
+
onSubmit: (data: typeof schema.infer) => void;
|
|
19
|
+
}) {
|
|
20
20
|
const {
|
|
21
21
|
register,
|
|
22
22
|
handleSubmit,
|
|
23
23
|
formState: { errors },
|
|
24
|
-
} = useForm
|
|
24
|
+
} = useForm({
|
|
25
25
|
resolver: arktypeResolver(schema), // Useful to check TypeScript regressions
|
|
26
26
|
});
|
|
27
27
|
|
|
@@ -47,10 +47,36 @@ test("form's validation with arkType and TypeScript's integration", async () =>
|
|
|
47
47
|
await user.click(screen.getByText(/submit/i));
|
|
48
48
|
|
|
49
49
|
expect(
|
|
50
|
-
screen.getByText('username must be
|
|
50
|
+
screen.getByText('username must be at least length 2'),
|
|
51
51
|
).toBeInTheDocument();
|
|
52
52
|
expect(
|
|
53
|
-
screen.getByText('password must be
|
|
53
|
+
screen.getByText('password must be at least length 2'),
|
|
54
54
|
).toBeInTheDocument();
|
|
55
55
|
expect(handleSubmit).not.toHaveBeenCalled();
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
export function TestComponentManualType({
|
|
59
|
+
onSubmit,
|
|
60
|
+
}: {
|
|
61
|
+
onSubmit: (data: FormData) => void;
|
|
62
|
+
}) {
|
|
63
|
+
const {
|
|
64
|
+
register,
|
|
65
|
+
handleSubmit,
|
|
66
|
+
formState: { errors },
|
|
67
|
+
} = useForm<typeof schema.infer, undefined, FormData>({
|
|
68
|
+
resolver: arktypeResolver(schema), // Useful to check TypeScript regressions
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
73
|
+
<input {...register('username')} />
|
|
74
|
+
{errors.username && <span role="alert">{errors.username.message}</span>}
|
|
75
|
+
|
|
76
|
+
<input {...register('password')} />
|
|
77
|
+
{errors.password && <span role="alert">{errors.password.message}</span>}
|
|
78
|
+
|
|
79
|
+
<button type="submit">submit</button>
|
|
80
|
+
</form>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -7,7 +7,7 @@ export const schema = type({
|
|
|
7
7
|
repeatPassword: 'string>1',
|
|
8
8
|
accessToken: 'string|number',
|
|
9
9
|
birthYear: '1900<number<2013',
|
|
10
|
-
email: 'email',
|
|
10
|
+
email: 'string.email',
|
|
11
11
|
tags: 'string[]',
|
|
12
12
|
enabled: 'boolean',
|
|
13
13
|
url: 'string>1',
|
|
@@ -43,7 +43,7 @@ export const invalidData = {
|
|
|
43
43
|
birthYear: 'birthYear',
|
|
44
44
|
like: [{ id: 'z' }],
|
|
45
45
|
url: 'abc',
|
|
46
|
-
};
|
|
46
|
+
} as any as typeof schema.infer;
|
|
47
47
|
|
|
48
48
|
export const fields: Record<InternalFieldName, Field['_f']> = {
|
|
49
49
|
username: {
|