@hookform/resolvers 3.0.0 → 3.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 +66 -5
- package/arktype/dist/arktype.d.ts +2 -0
- package/arktype/dist/arktype.js +2 -0
- package/arktype/dist/arktype.js.map +1 -0
- package/arktype/dist/arktype.mjs +2 -0
- package/arktype/dist/arktype.modern.mjs +2 -0
- package/arktype/dist/arktype.modern.mjs.map +1 -0
- package/arktype/dist/arktype.module.js +2 -0
- package/arktype/dist/arktype.module.js.map +1 -0
- package/arktype/dist/arktype.umd.js +2 -0
- package/arktype/dist/arktype.umd.js.map +1 -0
- package/arktype/dist/index.d.ts +2 -0
- package/arktype/dist/types.d.ts +9 -0
- package/arktype/package.json +17 -0
- package/arktype/src/__tests__/Form-native-validation.tsx +82 -0
- package/arktype/src/__tests__/Form.tsx +56 -0
- package/arktype/src/__tests__/__fixtures__/data.ts +67 -0
- package/arktype/src/__tests__/__snapshots__/arktype.ts.snap +76 -0
- package/arktype/src/__tests__/arktype.ts +26 -0
- package/arktype/src/arktype.ts +41 -0
- package/arktype/src/index.ts +2 -0
- package/arktype/src/types.ts +18 -0
- package/package.json +33 -21
- 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__/__snapshots__/typebox.ts.snap +56 -56
- package/typebox/src/typebox.ts +1 -1
package/README.md
CHANGED
|
@@ -24,12 +24,27 @@
|
|
|
24
24
|
|
|
25
25
|
- [React-hook-form validation resolver documentation ](https://react-hook-form.com/api/useform/#resolver)
|
|
26
26
|
|
|
27
|
+
### Supported resolvers
|
|
28
|
+
|
|
29
|
+
- [Yup](#Yup)
|
|
30
|
+
- [Zod](#Zod)
|
|
31
|
+
- [Superstruct](#Superstruct)
|
|
32
|
+
- [Joi](#Joi)
|
|
33
|
+
- [Class Validator](#Class-Validator)
|
|
34
|
+
- [io-ts](#io-ts)
|
|
35
|
+
- [Nope](#Nope)
|
|
36
|
+
- [computed-types](#computed-types)
|
|
37
|
+
- [typanion](#typanion)
|
|
38
|
+
- [Ajv](#Ajv)
|
|
39
|
+
- [TypeBox](#TypeBox)
|
|
40
|
+
- [ArkType](#ArkType)
|
|
41
|
+
|
|
27
42
|
## API
|
|
28
43
|
|
|
29
44
|
```
|
|
30
45
|
type Options = {
|
|
31
46
|
mode: 'async' | 'sync',
|
|
32
|
-
|
|
47
|
+
raw?: boolean
|
|
33
48
|
}
|
|
34
49
|
|
|
35
50
|
resolver(schema: object, schemaOptions?: object, resolverOptions: Options)
|
|
@@ -486,6 +501,37 @@ const App = () => {
|
|
|
486
501
|
};
|
|
487
502
|
```
|
|
488
503
|
|
|
504
|
+
### [ArkType](https://github.com/arktypeio/arktype)
|
|
505
|
+
|
|
506
|
+
TypeScript's 1:1 validator, optimized from editor to runtime
|
|
507
|
+
|
|
508
|
+
[](https://bundlephobia.com/result?p=arktype)
|
|
509
|
+
|
|
510
|
+
```typescript jsx
|
|
511
|
+
import { useForm } from 'react-hook-form';
|
|
512
|
+
import { arktypeResolver } from '@hookform/resolvers/arktype';
|
|
513
|
+
import { type } from 'arktype';
|
|
514
|
+
|
|
515
|
+
const schema = type({
|
|
516
|
+
username: 'string>1',
|
|
517
|
+
password: 'string>1',
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
const App = () => {
|
|
521
|
+
const { register, handleSubmit } = useForm({
|
|
522
|
+
resolver: arktypeResolver(schema),
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
return (
|
|
526
|
+
<form onSubmit={handleSubmit((d) => console.log(d))}>
|
|
527
|
+
<input {...register('username')} />
|
|
528
|
+
<input type="password" {...register('password')} />
|
|
529
|
+
<input type="submit" />
|
|
530
|
+
</form>
|
|
531
|
+
);
|
|
532
|
+
};
|
|
533
|
+
```
|
|
534
|
+
|
|
489
535
|
## Backers
|
|
490
536
|
|
|
491
537
|
Thanks goes to all our backers! [[Become a backer](https://opencollective.com/react-hook-form#backer)].
|
|
@@ -494,12 +540,27 @@ Thanks goes to all our backers! [[Become a backer](https://opencollective.com/re
|
|
|
494
540
|
<img src="https://opencollective.com/react-hook-form/backers.svg?width=950" />
|
|
495
541
|
</a>
|
|
496
542
|
|
|
497
|
-
|
|
543
|
+
### Sponsors
|
|
498
544
|
|
|
499
|
-
Thanks
|
|
545
|
+
Thanks go to these kind and lovely sponsors!
|
|
500
546
|
|
|
501
|
-
<a href=
|
|
502
|
-
<img src="https://opencollective.com/
|
|
547
|
+
<a target="_blank" href='https://wantedlyinc.com'>
|
|
548
|
+
<img width="94" src="https://images.opencollective.com/wantedly/d94e44e/logo/256.png" />
|
|
549
|
+
</a>
|
|
550
|
+
<a target="_blank" href='https://toss.im'>
|
|
551
|
+
<img width="94" src="https://images.opencollective.com/toss/3ed69b3/logo/256.png" />
|
|
552
|
+
</a>
|
|
553
|
+
<a target="_blank" href="https://graphcms.com">
|
|
554
|
+
<img width="94" src="https://avatars.githubusercontent.com/u/31031438" />
|
|
555
|
+
</a>
|
|
556
|
+
<a target="_blank" href="https://www.beekai.com/">
|
|
557
|
+
<img width="94" src="https://www.beekai.com/marketing/logo/logo.svg" />
|
|
558
|
+
</a>
|
|
559
|
+
<a target="_blank" href="https://kanamekey.com">
|
|
560
|
+
<img width="94" src="https://images.opencollective.com/kaname/d15fd98/logo/256.png" />
|
|
561
|
+
</a>
|
|
562
|
+
<a target="_blank" href="https://formcarry.com/">
|
|
563
|
+
<img width="94" src="https://images.opencollective.com/formcarry/a40a4ea/logo/256.png" />
|
|
503
564
|
</a>
|
|
504
565
|
|
|
505
566
|
## Contributors
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var r=require("@hookform/resolvers"),e=function(r){for(var e={};r.length;){var o=r[0],a=o.path.join(".");e[a]||(e[a]={message:o.message,type:o.code}),r.shift()}return e};exports.arktypeResolver=function(o,a,s){return void 0===s&&(s={}),function(a,t,i){var l=o(a);return l.problems?{values:{},errors:r.toNestError(e(l.problems),i)}:(i.shouldUseNativeValidation&&r.validateFieldsNatively({},i),{errors:{},values:s.raw?a:l.data})}};
|
|
2
|
+
//# sourceMappingURL=arktype.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arktype.js","sources":["../src/arktype.ts"],"sourcesContent":["import { FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Problems } from 'arktype';\n\nconst parseErrorSchema = (e: Problems) => {\n const errors: Record<string, FieldError> = {};\n for (; e.length; ) {\n const error = e[0];\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: error.code };\n }\n\n // @ts-expect-error - false positive Property 'shift' does not exist on type 'Problems'.\n e.shift();\n }\n\n return errors;\n};\n\nexport const arktypeResolver: Resolver =\n (schema, _schemaOptions, resolverOptions = {}) =>\n (values, _, options) => {\n const result = schema(values);\n\n if (result.problems) {\n return {\n values: {},\n errors: toNestError(parseErrorSchema(result.problems), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : result.data,\n };\n };\n"],"names":["parseErrorSchema","e","errors","length","error","_path","path","join","message","type","code","shift","schema","_schemaOptions","resolverOptions","values","_","options","result","problems","toNestError","shouldUseNativeValidation","validateFieldsNatively","raw","data"],"mappings":"qCAKMA,EAAmB,SAACC,GAExB,IADA,IAAMC,EAAqC,GACpCD,EAAEE,QAAU,CACjB,IAAMC,EAAQH,EAAE,GACVI,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAOG,KACVH,EAAOG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAIxDT,EAAEU,OACH,CAED,OAAOT,CACT,0BAGE,SAACU,EAAQC,EAAgBC,GAAoB,gBAApBA,IAAAA,EAAkB,CAAE,YAC5CC,EAAQC,EAAGC,GACV,IAAMC,EAASN,EAAOG,GAEtB,OAAIG,EAAOC,SACF,CACLJ,OAAQ,CAAA,EACRb,OAAQkB,EAAWA,YAACpB,EAAiBkB,EAAOC,UAAWF,KAI3DA,EAAQI,2BAA6BC,EAAsBA,uBAAC,GAAIL,GAEzD,CACLf,OAAQ,CAAiB,EACzBa,OAAQD,EAAgBS,IAAMR,EAASG,EAAOM,MAElD,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{toNestError as r,validateFieldsNatively as e}from"@hookform/resolvers";var o=function(r){for(var e={};r.length;){var o=r[0],a=o.path.join(".");e[a]||(e[a]={message:o.message,type:o.code}),r.shift()}return e},a=function(a,s,t){return void 0===t&&(t={}),function(s,n,i){var u=a(s);return u.problems?{values:{},errors:r(o(u.problems),i)}:(i.shouldUseNativeValidation&&e({},i),{errors:{},values:t.raw?s:u.data})}};export{a as arktypeResolver};
|
|
2
|
+
//# sourceMappingURL=arktype.module.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{toNestError as e,validateFieldsNatively as o}from"@hookform/resolvers";const r=e=>{const o={};for(;e.length;){const r=e[0],s=r.path.join(".");o[s]||(o[s]={message:r.message,type:r.code}),e.shift()}return o},s=(s,t,a={})=>(t,n,l)=>{const m=s(t);return m.problems?{values:{},errors:e(r(m.problems),l)}:(l.shouldUseNativeValidation&&o({},l),{errors:{},values:a.raw?t:m.data})};export{s as arktypeResolver};
|
|
2
|
+
//# sourceMappingURL=arktype.modern.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arktype.modern.mjs","sources":["../src/arktype.ts"],"sourcesContent":["import { FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Problems } from 'arktype';\n\nconst parseErrorSchema = (e: Problems) => {\n const errors: Record<string, FieldError> = {};\n for (; e.length; ) {\n const error = e[0];\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: error.code };\n }\n\n // @ts-expect-error - false positive Property 'shift' does not exist on type 'Problems'.\n e.shift();\n }\n\n return errors;\n};\n\nexport const arktypeResolver: Resolver =\n (schema, _schemaOptions, resolverOptions = {}) =>\n (values, _, options) => {\n const result = schema(values);\n\n if (result.problems) {\n return {\n values: {},\n errors: toNestError(parseErrorSchema(result.problems), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : result.data,\n };\n };\n"],"names":["parseErrorSchema","e","errors","length","error","_path","path","join","message","type","code","shift","arktypeResolver","schema","_schemaOptions","resolverOptions","values","_","options","result","problems","toNestError","shouldUseNativeValidation","validateFieldsNatively","raw","data"],"mappings":"8EAKA,MAAMA,EAAoBC,IACxB,MAAMC,EAAqC,CAAA,EAC3C,KAAOD,EAAEE,QAAU,CACjB,MAAMC,EAAQH,EAAE,GACVI,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAOG,KACVH,EAAOG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAIxDT,EAAEU,OACH,CAED,OAAOT,GAGIU,EACXA,CAACC,EAAQC,EAAgBC,EAAkB,CAAE,IAC7C,CAACC,EAAQC,EAAGC,KACV,MAAMC,EAASN,EAAOG,GAEtB,OAAIG,EAAOC,SACF,CACLJ,OAAQ,CAAE,EACVd,OAAQmB,EAAYrB,EAAiBmB,EAAOC,UAAWF,KAI3DA,EAAQI,2BAA6BC,EAAuB,CAAA,EAAIL,GAEzD,CACLhB,OAAQ,CAAiB,EACzBc,OAAQD,EAAgBS,IAAMR,EAASG,EAAOM"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{toNestError as r,validateFieldsNatively as e}from"@hookform/resolvers";var o=function(r){for(var e={};r.length;){var o=r[0],a=o.path.join(".");e[a]||(e[a]={message:o.message,type:o.code}),r.shift()}return e},a=function(a,s,t){return void 0===t&&(t={}),function(s,n,i){var u=a(s);return u.problems?{values:{},errors:r(o(u.problems),i)}:(i.shouldUseNativeValidation&&e({},i),{errors:{},values:t.raw?s:u.data})}};export{a as arktypeResolver};
|
|
2
|
+
//# sourceMappingURL=arktype.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arktype.module.js","sources":["../src/arktype.ts"],"sourcesContent":["import { FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Problems } from 'arktype';\n\nconst parseErrorSchema = (e: Problems) => {\n const errors: Record<string, FieldError> = {};\n for (; e.length; ) {\n const error = e[0];\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: error.code };\n }\n\n // @ts-expect-error - false positive Property 'shift' does not exist on type 'Problems'.\n e.shift();\n }\n\n return errors;\n};\n\nexport const arktypeResolver: Resolver =\n (schema, _schemaOptions, resolverOptions = {}) =>\n (values, _, options) => {\n const result = schema(values);\n\n if (result.problems) {\n return {\n values: {},\n errors: toNestError(parseErrorSchema(result.problems), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : result.data,\n };\n };\n"],"names":["parseErrorSchema","e","errors","length","error","_path","path","join","message","type","code","shift","arktypeResolver","schema","_schemaOptions","resolverOptions","values","_","options","result","problems","toNestError","shouldUseNativeValidation","validateFieldsNatively","raw","data"],"mappings":"8EAKA,IAAMA,EAAmB,SAACC,GAExB,IADA,IAAMC,EAAqC,GACpCD,EAAEE,QAAU,CACjB,IAAMC,EAAQH,EAAE,GACVI,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAOG,KACVH,EAAOG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAIxDT,EAAEU,OACH,CAED,OAAOT,CACT,EAEaU,EACX,SAACC,EAAQC,EAAgBC,GAAoB,gBAApBA,IAAAA,EAAkB,CAAE,YAC5CC,EAAQC,EAAGC,GACV,IAAMC,EAASN,EAAOG,GAEtB,OAAIG,EAAOC,SACF,CACLJ,OAAQ,CAAA,EACRd,OAAQmB,EAAYrB,EAAiBmB,EAAOC,UAAWF,KAI3DA,EAAQI,2BAA6BC,EAAuB,GAAIL,GAEzD,CACLhB,OAAQ,CAAiB,EACzBc,OAAQD,EAAgBS,IAAMR,EAASG,EAAOM,MAElD,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("@hookform/resolvers")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers"],o):o((e||self).hookformResolversArktype={},e.hookformResolvers)}(this,function(e,o){var r=function(e){for(var o={};e.length;){var r=e[0],s=r.path.join(".");o[s]||(o[s]={message:r.message,type:r.code}),e.shift()}return o};e.arktypeResolver=function(e,s,t){return void 0===t&&(t={}),function(s,n,i){var a=e(s);return a.problems?{values:{},errors:o.toNestError(r(a.problems),i)}:(i.shouldUseNativeValidation&&o.validateFieldsNatively({},i),{errors:{},values:t.raw?s:a.data})}}});
|
|
2
|
+
//# sourceMappingURL=arktype.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arktype.umd.js","sources":["../src/arktype.ts"],"sourcesContent":["import { FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Problems } from 'arktype';\n\nconst parseErrorSchema = (e: Problems) => {\n const errors: Record<string, FieldError> = {};\n for (; e.length; ) {\n const error = e[0];\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: error.code };\n }\n\n // @ts-expect-error - false positive Property 'shift' does not exist on type 'Problems'.\n e.shift();\n }\n\n return errors;\n};\n\nexport const arktypeResolver: Resolver =\n (schema, _schemaOptions, resolverOptions = {}) =>\n (values, _, options) => {\n const result = schema(values);\n\n if (result.problems) {\n return {\n values: {},\n errors: toNestError(parseErrorSchema(result.problems), options),\n };\n }\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : result.data,\n };\n };\n"],"names":["parseErrorSchema","e","errors","length","error","_path","path","join","message","type","code","shift","schema","_schemaOptions","resolverOptions","values","_","options","result","problems","toNestError","shouldUseNativeValidation","validateFieldsNatively","raw","data"],"mappings":"6TAKA,IAAMA,EAAmB,SAACC,GAExB,IADA,IAAMC,EAAqC,GACpCD,EAAEE,QAAU,CACjB,IAAMC,EAAQH,EAAE,GACVI,EAAQD,EAAME,KAAKC,KAAK,KAEzBL,EAAOG,KACVH,EAAOG,GAAS,CAAEG,QAASJ,EAAMI,QAASC,KAAML,EAAMM,OAIxDT,EAAEU,OACH,CAED,OAAOT,CACT,oBAGE,SAACU,EAAQC,EAAgBC,GAAoB,gBAApBA,IAAAA,EAAkB,CAAE,YAC5CC,EAAQC,EAAGC,GACV,IAAMC,EAASN,EAAOG,GAEtB,OAAIG,EAAOC,SACF,CACLJ,OAAQ,CAAA,EACRb,OAAQkB,EAAWA,YAACpB,EAAiBkB,EAAOC,UAAWF,KAI3DA,EAAQI,2BAA6BC,EAAsBA,uBAAC,GAAIL,GAEzD,CACLf,OAAQ,CAAiB,EACzBa,OAAQD,EAAgBS,IAAMR,EAASG,EAAOM,MAElD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FieldValues, ResolverResult, ResolverOptions } from 'react-hook-form';
|
|
2
|
+
import { Type } from 'arktype';
|
|
3
|
+
export type Resolver = <T extends Type<any>>(schema: T, schemaOptions?: never, factoryOptions?: {
|
|
4
|
+
/**
|
|
5
|
+
* Return the raw input values rather than the parsed values.
|
|
6
|
+
* @default false
|
|
7
|
+
*/
|
|
8
|
+
raw?: boolean;
|
|
9
|
+
}) => <TFieldValues extends FieldValues, TContext>(values: TFieldValues, context: TContext | undefined, options: ResolverOptions<TFieldValues>) => ResolverResult<TFieldValues>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hookform/resolvers/arktype",
|
|
3
|
+
"amdName": "hookformResolversArktype",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"description": "React Hook Form validation resolver: arktype",
|
|
7
|
+
"main": "dist/arktype.js",
|
|
8
|
+
"module": "dist/arktype.module.js",
|
|
9
|
+
"umd:main": "dist/arktype.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
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useForm } from 'react-hook-form';
|
|
3
|
+
import { render, screen } from '@testing-library/react';
|
|
4
|
+
import user from '@testing-library/user-event';
|
|
5
|
+
import { arktypeResolver } from '..';
|
|
6
|
+
import { type } from 'arktype';
|
|
7
|
+
|
|
8
|
+
const schema = type({
|
|
9
|
+
username: 'string>1',
|
|
10
|
+
password: 'string>1',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
type FormData = typeof schema.infer;
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
onSubmit: (data: FormData) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function TestComponent({ onSubmit }: Props) {
|
|
20
|
+
const { register, handleSubmit } = useForm<FormData>({
|
|
21
|
+
resolver: arktypeResolver(schema),
|
|
22
|
+
shouldUseNativeValidation: true,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
27
|
+
<input {...register('username')} placeholder="username" />
|
|
28
|
+
|
|
29
|
+
<input {...register('password')} placeholder="password" />
|
|
30
|
+
|
|
31
|
+
<button type="submit">submit</button>
|
|
32
|
+
</form>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
test("form's native validation with Zod", async () => {
|
|
37
|
+
const handleSubmit = vi.fn();
|
|
38
|
+
render(<TestComponent onSubmit={handleSubmit} />);
|
|
39
|
+
|
|
40
|
+
// username
|
|
41
|
+
let usernameField = screen.getByPlaceholderText(
|
|
42
|
+
/username/i,
|
|
43
|
+
) as HTMLInputElement;
|
|
44
|
+
expect(usernameField.validity.valid).toBe(true);
|
|
45
|
+
expect(usernameField.validationMessage).toBe('');
|
|
46
|
+
|
|
47
|
+
// password
|
|
48
|
+
let passwordField = screen.getByPlaceholderText(
|
|
49
|
+
/password/i,
|
|
50
|
+
) as HTMLInputElement;
|
|
51
|
+
expect(passwordField.validity.valid).toBe(true);
|
|
52
|
+
expect(passwordField.validationMessage).toBe('');
|
|
53
|
+
|
|
54
|
+
await user.click(screen.getByText(/submit/i));
|
|
55
|
+
|
|
56
|
+
// username
|
|
57
|
+
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
58
|
+
expect(usernameField.validity.valid).toBe(false);
|
|
59
|
+
expect(usernameField.validationMessage).toBe(
|
|
60
|
+
'username must be more than 1 characters (was 0)',
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// password
|
|
64
|
+
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
65
|
+
expect(passwordField.validity.valid).toBe(false);
|
|
66
|
+
expect(passwordField.validationMessage).toBe(
|
|
67
|
+
'password must be more than 1 characters (was 0)',
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
await user.type(screen.getByPlaceholderText(/username/i), 'joe');
|
|
71
|
+
await user.type(screen.getByPlaceholderText(/password/i), 'password');
|
|
72
|
+
|
|
73
|
+
// username
|
|
74
|
+
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
75
|
+
expect(usernameField.validity.valid).toBe(true);
|
|
76
|
+
expect(usernameField.validationMessage).toBe('');
|
|
77
|
+
|
|
78
|
+
// password
|
|
79
|
+
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
80
|
+
expect(passwordField.validity.valid).toBe(true);
|
|
81
|
+
expect(passwordField.validationMessage).toBe('');
|
|
82
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import user from '@testing-library/user-event';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { arktypeResolver } from '..';
|
|
6
|
+
import { type } from 'arktype';
|
|
7
|
+
|
|
8
|
+
const schema = type({
|
|
9
|
+
username: 'string>1',
|
|
10
|
+
password: 'string>1',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
type FormData = typeof schema.infer & { 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: arktypeResolver(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 arkType and TypeScript's integration", async () => {
|
|
42
|
+
const handleSubmit = vi.fn();
|
|
43
|
+
render(<TestComponent onSubmit={handleSubmit} />);
|
|
44
|
+
|
|
45
|
+
expect(screen.queryAllByRole('alert')).toHaveLength(0);
|
|
46
|
+
|
|
47
|
+
await user.click(screen.getByText(/submit/i));
|
|
48
|
+
|
|
49
|
+
expect(
|
|
50
|
+
screen.getByText('username must be more than 1 characters (was 0)'),
|
|
51
|
+
).toBeInTheDocument();
|
|
52
|
+
expect(
|
|
53
|
+
screen.getByText('password must be more than 1 characters (was 0)'),
|
|
54
|
+
).toBeInTheDocument();
|
|
55
|
+
expect(handleSubmit).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Field, InternalFieldName } from 'react-hook-form';
|
|
2
|
+
import { type, arrayOf, union } from 'arktype';
|
|
3
|
+
|
|
4
|
+
export const schema = type({
|
|
5
|
+
username: 'string>2',
|
|
6
|
+
password: union(['string>8', '&', '/.*[A-Za-z].*/'], ['/.*\\d.*/']),
|
|
7
|
+
repeatPassword: 'string>1',
|
|
8
|
+
accessToken: union('string', 'number'),
|
|
9
|
+
birthYear: '1900<number<2013',
|
|
10
|
+
email: 'email',
|
|
11
|
+
tags: arrayOf('string'),
|
|
12
|
+
enabled: 'boolean',
|
|
13
|
+
url: 'string>1',
|
|
14
|
+
'like?': arrayOf(
|
|
15
|
+
type({
|
|
16
|
+
id: 'number',
|
|
17
|
+
name: 'string>3',
|
|
18
|
+
}),
|
|
19
|
+
),
|
|
20
|
+
dateStr: 'Date',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const validData: typeof schema.infer = {
|
|
24
|
+
username: 'Doe',
|
|
25
|
+
password: 'Password123_',
|
|
26
|
+
repeatPassword: 'Password123_',
|
|
27
|
+
birthYear: 2000,
|
|
28
|
+
email: 'john@doe.com',
|
|
29
|
+
tags: ['tag1', 'tag2'],
|
|
30
|
+
enabled: true,
|
|
31
|
+
accessToken: 'accessToken',
|
|
32
|
+
url: 'https://react-hook-form.com/',
|
|
33
|
+
like: [
|
|
34
|
+
{
|
|
35
|
+
id: 1,
|
|
36
|
+
name: 'name',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
dateStr: new Date('2020-01-01'),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const invalidData = {
|
|
43
|
+
password: '___',
|
|
44
|
+
email: '',
|
|
45
|
+
birthYear: 'birthYear',
|
|
46
|
+
like: [{ id: 'z' }],
|
|
47
|
+
url: 'abc',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const fields: Record<InternalFieldName, Field['_f']> = {
|
|
51
|
+
username: {
|
|
52
|
+
ref: { name: 'username' },
|
|
53
|
+
name: 'username',
|
|
54
|
+
},
|
|
55
|
+
password: {
|
|
56
|
+
ref: { name: 'password' },
|
|
57
|
+
name: 'password',
|
|
58
|
+
},
|
|
59
|
+
email: {
|
|
60
|
+
ref: { name: 'email' },
|
|
61
|
+
name: 'email',
|
|
62
|
+
},
|
|
63
|
+
birthday: {
|
|
64
|
+
ref: { name: 'birthday' },
|
|
65
|
+
name: 'birthday',
|
|
66
|
+
},
|
|
67
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`arktypeResolver > should return a single error from arktypeResolver when validation fails 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"errors": {
|
|
6
|
+
"accessToken": {
|
|
7
|
+
"message": "accessToken must be defined",
|
|
8
|
+
"ref": undefined,
|
|
9
|
+
"type": "missing",
|
|
10
|
+
},
|
|
11
|
+
"birthYear": {
|
|
12
|
+
"message": "birthYear must be a number (was string)",
|
|
13
|
+
"ref": undefined,
|
|
14
|
+
"type": "domain",
|
|
15
|
+
},
|
|
16
|
+
"dateStr": {
|
|
17
|
+
"message": "dateStr must be defined",
|
|
18
|
+
"ref": undefined,
|
|
19
|
+
"type": "missing",
|
|
20
|
+
},
|
|
21
|
+
"email": {
|
|
22
|
+
"message": "email must be a valid email (was '')",
|
|
23
|
+
"ref": {
|
|
24
|
+
"name": "email",
|
|
25
|
+
},
|
|
26
|
+
"type": "regex",
|
|
27
|
+
},
|
|
28
|
+
"enabled": {
|
|
29
|
+
"message": "enabled must be defined",
|
|
30
|
+
"ref": undefined,
|
|
31
|
+
"type": "missing",
|
|
32
|
+
},
|
|
33
|
+
"like": [
|
|
34
|
+
{
|
|
35
|
+
"id": {
|
|
36
|
+
"message": "like/0/id must be a number (was string)",
|
|
37
|
+
"ref": undefined,
|
|
38
|
+
"type": "domain",
|
|
39
|
+
},
|
|
40
|
+
"name": {
|
|
41
|
+
"message": "like/0/name must be defined",
|
|
42
|
+
"ref": undefined,
|
|
43
|
+
"type": "missing",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
"password": {
|
|
48
|
+
"message": "At password, '___' must be...
|
|
49
|
+
• more than 8 characters
|
|
50
|
+
• a string matching /.*[A-Za-z].*/",
|
|
51
|
+
"ref": {
|
|
52
|
+
"name": "password",
|
|
53
|
+
},
|
|
54
|
+
"type": "multi",
|
|
55
|
+
},
|
|
56
|
+
"repeatPassword": {
|
|
57
|
+
"message": "repeatPassword must be defined",
|
|
58
|
+
"ref": undefined,
|
|
59
|
+
"type": "missing",
|
|
60
|
+
},
|
|
61
|
+
"tags": {
|
|
62
|
+
"message": "tags must be defined",
|
|
63
|
+
"ref": undefined,
|
|
64
|
+
"type": "missing",
|
|
65
|
+
},
|
|
66
|
+
"username": {
|
|
67
|
+
"message": "username must be defined",
|
|
68
|
+
"ref": {
|
|
69
|
+
"name": "username",
|
|
70
|
+
},
|
|
71
|
+
"type": "missing",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
"values": {},
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { arktypeResolver } from '..';
|
|
2
|
+
import { schema, validData, invalidData, fields } from './__fixtures__/data';
|
|
3
|
+
|
|
4
|
+
const shouldUseNativeValidation = false;
|
|
5
|
+
|
|
6
|
+
describe('arktypeResolver', () => {
|
|
7
|
+
it('should return values from arktypeResolver when validation pass & raw=true', async () => {
|
|
8
|
+
const result = await arktypeResolver(schema, undefined, {
|
|
9
|
+
raw: true,
|
|
10
|
+
})(validData, undefined, {
|
|
11
|
+
fields,
|
|
12
|
+
shouldUseNativeValidation,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should return a single error from arktypeResolver when validation fails', async () => {
|
|
19
|
+
const result = await arktypeResolver(schema)(invalidData, undefined, {
|
|
20
|
+
fields,
|
|
21
|
+
shouldUseNativeValidation,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(result).toMatchSnapshot();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FieldError, FieldErrors } from 'react-hook-form';
|
|
2
|
+
import { toNestError, validateFieldsNatively } from '@hookform/resolvers';
|
|
3
|
+
import type { Resolver } from './types';
|
|
4
|
+
import { Problems } from 'arktype';
|
|
5
|
+
|
|
6
|
+
const parseErrorSchema = (e: Problems) => {
|
|
7
|
+
const errors: Record<string, FieldError> = {};
|
|
8
|
+
for (; e.length; ) {
|
|
9
|
+
const error = e[0];
|
|
10
|
+
const _path = error.path.join('.');
|
|
11
|
+
|
|
12
|
+
if (!errors[_path]) {
|
|
13
|
+
errors[_path] = { message: error.message, type: error.code };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// @ts-expect-error - false positive Property 'shift' does not exist on type 'Problems'.
|
|
17
|
+
e.shift();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return errors;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const arktypeResolver: Resolver =
|
|
24
|
+
(schema, _schemaOptions, resolverOptions = {}) =>
|
|
25
|
+
(values, _, options) => {
|
|
26
|
+
const result = schema(values);
|
|
27
|
+
|
|
28
|
+
if (result.problems) {
|
|
29
|
+
return {
|
|
30
|
+
values: {},
|
|
31
|
+
errors: toNestError(parseErrorSchema(result.problems), options),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
options.shouldUseNativeValidation && validateFieldsNatively({}, options);
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
errors: {} as FieldErrors,
|
|
39
|
+
values: resolverOptions.raw ? values : result.data,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FieldValues, ResolverResult, ResolverOptions } from 'react-hook-form';
|
|
2
|
+
import { Type } from 'arktype';
|
|
3
|
+
|
|
4
|
+
export type Resolver = <T extends Type<any>>(
|
|
5
|
+
schema: T,
|
|
6
|
+
schemaOptions?: never,
|
|
7
|
+
factoryOptions?: {
|
|
8
|
+
/**
|
|
9
|
+
* Return the raw input values rather than the parsed values.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
raw?: boolean;
|
|
13
|
+
},
|
|
14
|
+
) => <TFieldValues extends FieldValues, TContext>(
|
|
15
|
+
values: TFieldValues,
|
|
16
|
+
context: TContext | undefined,
|
|
17
|
+
options: ResolverOptions<TFieldValues>,
|
|
18
|
+
) => ResolverResult<TFieldValues>;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hookform/resolvers",
|
|
3
3
|
"amdName": "hookformResolvers",
|
|
4
|
-
"version": "3.
|
|
5
|
-
"description": "React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox and Typanion",
|
|
4
|
+
"version": "3.1.0",
|
|
5
|
+
"description": "React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype and Typanion",
|
|
6
6
|
"main": "dist/resolvers.js",
|
|
7
7
|
"module": "dist/resolvers.module.js",
|
|
8
8
|
"umd:main": "dist/resolvers.umd.js",
|
|
@@ -87,6 +87,12 @@
|
|
|
87
87
|
"import": "./ajv/dist/ajv.mjs",
|
|
88
88
|
"require": "./ajv/dist/ajv.js"
|
|
89
89
|
},
|
|
90
|
+
"./arktype": {
|
|
91
|
+
"types": "./arktype/dist/index.d.ts",
|
|
92
|
+
"umd": "./arktype/dist/arktype.umd.js",
|
|
93
|
+
"import": "./arktype/dist/arktype.mjs",
|
|
94
|
+
"require": "./arktype/dist/arktype.js"
|
|
95
|
+
},
|
|
90
96
|
"./package.json": "./package.json",
|
|
91
97
|
"./*": "./*"
|
|
92
98
|
},
|
|
@@ -127,7 +133,10 @@
|
|
|
127
133
|
"ajv/dist",
|
|
128
134
|
"typebox/package.json",
|
|
129
135
|
"typebox/src",
|
|
130
|
-
"typebox/dist"
|
|
136
|
+
"typebox/dist",
|
|
137
|
+
"arktype/package.json",
|
|
138
|
+
"arktype/src",
|
|
139
|
+
"arktype/dist"
|
|
131
140
|
],
|
|
132
141
|
"publishConfig": {
|
|
133
142
|
"access": "public"
|
|
@@ -148,6 +157,7 @@
|
|
|
148
157
|
"build:typanion": "microbundle --cwd typanion --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
|
|
149
158
|
"build:ajv": "microbundle --cwd ajv --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
|
|
150
159
|
"build:typebox": "microbundle --cwd typebox --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm,@sinclair/typebox/value=value",
|
|
160
|
+
"build:arktype": "microbundle --cwd arktype --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
|
|
151
161
|
"postbuild": "node ./config/node-13-exports.js",
|
|
152
162
|
"lint": "eslint . --ext .ts,.js --ignore-path .gitignore",
|
|
153
163
|
"lint:types": "tsc",
|
|
@@ -173,7 +183,8 @@
|
|
|
173
183
|
"computed-types",
|
|
174
184
|
"typanion",
|
|
175
185
|
"ajv",
|
|
176
|
-
"TypeBox"
|
|
186
|
+
"TypeBox",
|
|
187
|
+
"arktype"
|
|
177
188
|
],
|
|
178
189
|
"repository": {
|
|
179
190
|
"type": "git",
|
|
@@ -186,51 +197,52 @@
|
|
|
186
197
|
},
|
|
187
198
|
"homepage": "https://react-hook-form.com",
|
|
188
199
|
"devDependencies": {
|
|
189
|
-
"@sinclair/typebox": "^0.
|
|
190
|
-
"@testing-library/dom": "^9.0
|
|
200
|
+
"@sinclair/typebox": "^0.27.6",
|
|
201
|
+
"@testing-library/dom": "^9.2.0",
|
|
191
202
|
"@testing-library/jest-dom": "^5.16.5",
|
|
192
203
|
"@testing-library/react": "^14.0.0",
|
|
193
204
|
"@testing-library/user-event": "^14.4.3",
|
|
194
|
-
"@types/node": "^18.15.
|
|
195
|
-
"@types/react": "^18.0.
|
|
205
|
+
"@types/node": "^18.15.11",
|
|
206
|
+
"@types/react": "^18.0.35",
|
|
196
207
|
"@types/testing-library__jest-dom": "^5.14.5",
|
|
197
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
198
|
-
"@typescript-eslint/parser": "^5.
|
|
208
|
+
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
|
209
|
+
"@typescript-eslint/parser": "^5.58.0",
|
|
199
210
|
"@vitejs/plugin-react": "^3.1.0",
|
|
200
211
|
"ajv": "^8.12.0",
|
|
201
212
|
"ajv-errors": "^3.0.0",
|
|
213
|
+
"arktype": "1.0.13-alpha",
|
|
202
214
|
"check-export-map": "^1.3.0",
|
|
203
215
|
"class-transformer": "^0.5.1",
|
|
204
216
|
"class-validator": "^0.14.0",
|
|
205
217
|
"computed-types": "^1.11.2",
|
|
206
218
|
"cross-env": "^7.0.3",
|
|
207
|
-
"eslint": "^8.
|
|
208
|
-
"eslint-config-prettier": "^8.
|
|
219
|
+
"eslint": "^8.38.0",
|
|
220
|
+
"eslint-config-prettier": "^8.8.0",
|
|
209
221
|
"fp-ts": "^2.13.1",
|
|
210
222
|
"husky": "^8.0.3",
|
|
211
223
|
"io-ts": "^2.2.20",
|
|
212
224
|
"io-ts-types": "^0.5.19",
|
|
213
|
-
"joi": "^17.
|
|
225
|
+
"joi": "^17.9.1",
|
|
214
226
|
"jsdom": "^21.1.1",
|
|
215
|
-
"lint-staged": "^13.2.
|
|
227
|
+
"lint-staged": "^13.2.1",
|
|
216
228
|
"microbundle": "^0.15.1",
|
|
217
229
|
"monocle-ts": "^2.3.13",
|
|
218
230
|
"newtype-ts": "^0.3.5",
|
|
219
231
|
"nope-validator": "^1.0.4",
|
|
220
232
|
"npm-run-all": "^4.1.5",
|
|
221
|
-
"prettier": "^2.8.
|
|
233
|
+
"prettier": "^2.8.7",
|
|
222
234
|
"react": "^18.2.0",
|
|
223
235
|
"react-dom": "^18.2.0",
|
|
224
|
-
"react-hook-form": "^7.43.
|
|
236
|
+
"react-hook-form": "^7.43.9",
|
|
225
237
|
"reflect-metadata": "^0.1.13",
|
|
226
238
|
"superstruct": "^1.0.3",
|
|
227
239
|
"typanion": "^3.12.1",
|
|
228
|
-
"typescript": "^5.0.
|
|
240
|
+
"typescript": "^5.0.4",
|
|
229
241
|
"vest": "^4.6.9",
|
|
230
|
-
"vite": "^4.2.
|
|
231
|
-
"vite-tsconfig-paths": "^4.0
|
|
232
|
-
"vitest": "^0.
|
|
233
|
-
"yup": "^1.0
|
|
242
|
+
"vite": "^4.2.1",
|
|
243
|
+
"vite-tsconfig-paths": "^4.2.0",
|
|
244
|
+
"vitest": "^0.30.1",
|
|
245
|
+
"yup": "^1.1.0",
|
|
234
246
|
"zod": "^3.21.4"
|
|
235
247
|
},
|
|
236
248
|
"peerDependencies": {
|
package/typebox/dist/typebox.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=require("react-hook-form"),r=require("@hookform/resolvers"),
|
|
1
|
+
var e=require("react-hook-form"),r=require("@hookform/resolvers"),a=require("@sinclair/typebox/value"),s=function(r,a){for(var s={};r.length;){var t=r[0],o=t.type,i=t.message,l=t.path.substring(1).replace(/\//g,".");if(s[l]||(s[l]={message:i,type:""+o}),a){var n=s[l].types,u=n&&n[""+o];s[l]=e.appendErrors(l,a,s,""+o,u?[].concat(u,t.message):t.message)}r.shift()}return s};exports.typeboxResolver=function(e){return function(t,o,i){try{var l=Array.from(a.Value.Errors(e,t));return i.shouldUseNativeValidation&&r.validateFieldsNatively({},i),Promise.resolve(l.length?{values:{},errors:r.toNestError(s(l,!i.shouldUseNativeValidation&&"all"===i.criteriaMode),i)}:{errors:{},values:t})}catch(e){return Promise.reject(e)}}};
|
|
2
2
|
//# sourceMappingURL=typebox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typebox.js","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors =
|
|
1
|
+
{"version":3,"file":"typebox.js","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors = Array.from(Value.Errors(schema, values));\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (!errors.length) {\n return {\n errors: {} as FieldErrors,\n values,\n };\n }\n\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(\n errors,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","_errors","validateAllFieldCriteria","errors","length","error","type","message","_path","path","substring","replace","types","messages","appendErrors","concat","shift","schema","values","_","options","Array","from","Value","Errors","shouldUseNativeValidation","validateFieldsNatively","Promise","resolve","toNestError","criteriaMode","e","reject"],"mappings":"uGAKMA,EAAmB,SACvBC,EACAC,GAGA,IADA,IAAMC,EAAqC,CAAE,EACtCF,EAAQG,QAAU,CACvB,IAAMC,EAAQJ,EAAQ,GACdK,EAAwBD,EAAxBC,KAAMC,EAAkBF,EAAlBE,QACRC,EAD0BH,EAATI,KACJC,UAAU,GAAGC,QAAQ,MAAO,KAM/C,GAJKR,EAAOK,KACVL,EAAOK,GAAS,CAAED,QAAAA,EAASD,KAAM,GAAKA,IAGpCJ,EAA0B,CAC5B,IAAMU,EAAQT,EAAOK,GAAOI,MACtBC,EAAWD,GAASA,EAAM,GAAKN,GAErCH,EAAOK,GAASM,EAAYA,aAC1BN,EACAN,EACAC,EACA,GAAKG,EACLO,EACK,GAAgBE,OAAOF,EAAsBR,EAAME,SACpDF,EAAME,QAEb,CAEDN,EAAQe,OACT,CAED,OAAOb,CACT,0BAGE,SAACc,GAAM,OAAA,SAAYC,EAAQC,EAAGC,GAAW,IACvC,IAAMjB,EAASkB,MAAMC,KAAKC,EAAAA,MAAMC,OAAOP,EAAQC,IAI/C,OAFAE,EAAQK,2BAA6BC,EAAAA,uBAAuB,CAAA,EAAIN,GAShEO,QAAAC,QAPKzB,EAAOC,OAOL,CACLc,OAAQ,CAAE,EACVf,OAAQ0B,EAAAA,YACN7B,EACEG,GACCiB,EAAQK,2BAAsD,QAAzBL,EAAQU,cAEhDV,IAbK,CACLjB,OAAQ,GACRe,OAAAA,GAcN,CAAC,MAAAa,GAAAJ,OAAAA,QAAAK,OAAAD,EAAA,CAAA,CAAA"}
|
package/typebox/dist/typebox.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{appendErrors as r}from"react-hook-form";import{validateFieldsNatively as e,toNestError as o}from"@hookform/resolvers";import{Value as t}from"@sinclair/typebox/value";var a=function(e,o){for(var t={};e.length;){var a=e[0],s=a.type,i=a.message,n=a.path.substring(1).replace(/\//g,".");if(t[n]||(t[n]={message:i,type:""+s}),o){var l=t[n].types,
|
|
1
|
+
import{appendErrors as r}from"react-hook-form";import{validateFieldsNatively as e,toNestError as o}from"@hookform/resolvers";import{Value as t}from"@sinclair/typebox/value";var a=function(e,o){for(var t={};e.length;){var a=e[0],s=a.type,i=a.message,n=a.path.substring(1).replace(/\//g,".");if(t[n]||(t[n]={message:i,type:""+s}),o){var l=t[n].types,m=l&&l[""+s];t[n]=r(n,o,t,""+s,m?[].concat(m,a.message):a.message)}e.shift()}return t},s=function(r){return function(s,i,n){try{var l=Array.from(t.Errors(r,s));return n.shouldUseNativeValidation&&e({},n),Promise.resolve(l.length?{values:{},errors:o(a(l,!n.shouldUseNativeValidation&&"all"===n.criteriaMode),n)}:{errors:{},values:s})}catch(r){return Promise.reject(r)}}};export{s as typeboxResolver};
|
|
2
2
|
//# sourceMappingURL=typebox.module.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{appendErrors as
|
|
1
|
+
import{appendErrors as r}from"react-hook-form";import{validateFieldsNatively as e,toNestError as o}from"@hookform/resolvers";import{Value as s}from"@sinclair/typebox/value";const t=(e,o)=>{const s={};for(;e.length;){const t=e[0],{type:a,message:i,path:n}=t,l=n.substring(1).replace(/\//g,".");if(s[l]||(s[l]={message:i,type:""+a}),o){const e=s[l].types,i=e&&e[""+a];s[l]=r(l,o,s,""+a,i?[].concat(i,t.message):t.message)}e.shift()}return s},a=r=>async(a,i,n)=>{const l=Array.from(s.Errors(r,a));return n.shouldUseNativeValidation&&e({},n),l.length?{values:{},errors:o(t(l,!n.shouldUseNativeValidation&&"all"===n.criteriaMode),n)}:{errors:{},values:a}};export{a as typeboxResolver};
|
|
2
2
|
//# sourceMappingURL=typebox.modern.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typebox.modern.mjs","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors =
|
|
1
|
+
{"version":3,"file":"typebox.modern.mjs","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors = Array.from(Value.Errors(schema, values));\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (!errors.length) {\n return {\n errors: {} as FieldErrors,\n values,\n };\n }\n\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(\n errors,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","_errors","validateAllFieldCriteria","errors","length","error","type","message","path","_path","substring","replace","types","messages","appendErrors","concat","shift","typeboxResolver","schema","async","values","_","options","Array","from","Value","Errors","shouldUseNativeValidation","validateFieldsNatively","toNestError","criteriaMode"],"mappings":"6KAKA,MAAMA,EAAmBA,CACvBC,EACAC,KAEA,MAAMC,EAAqC,CAAA,EAC3C,KAAOF,EAAQG,QAAU,CACvB,MAAMC,EAAQJ,EAAQ,IAChBK,KAAEA,EAAIC,QAAEA,EAAOC,KAAEA,GAASH,EAC1BI,EAAQD,EAAKE,UAAU,GAAGC,QAAQ,MAAO,KAM/C,GAJKR,EAAOM,KACVN,EAAOM,GAAS,CAAEF,UAASD,KAAM,GAAKA,IAGpCJ,EAA0B,CAC5B,MAAMU,EAAQT,EAAOM,GAAOG,MACtBC,EAAWD,GAASA,EAAM,GAAKN,GAErCH,EAAOM,GAASK,EACdL,EACAP,EACAC,EACA,GAAKG,EACLO,EACK,GAAgBE,OAAOF,EAAsBR,EAAME,SACpDF,EAAME,QAEb,CAEDN,EAAQe,OACT,CAED,OAAOb,GAGIc,EACVC,GAAWC,MAAOC,EAAQC,EAAGC,KAC5B,MAAMnB,EAASoB,MAAMC,KAAKC,EAAMC,OAAOR,EAAQE,IAI/C,OAFAE,EAAQK,2BAA6BC,EAAuB,CAAE,EAAEN,GAE3DnB,EAAOC,OAOL,CACLgB,OAAQ,CAAA,EACRjB,OAAQ0B,EACN7B,EACEG,GACCmB,EAAQK,2BAAsD,QAAzBL,EAAQQ,cAEhDR,IAbK,CACLnB,OAAQ,CAAA,EACRiB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{appendErrors as r}from"react-hook-form";import{validateFieldsNatively as e,toNestError as o}from"@hookform/resolvers";import{Value as t}from"@sinclair/typebox/value";var a=function(e,o){for(var t={};e.length;){var a=e[0],s=a.type,i=a.message,n=a.path.substring(1).replace(/\//g,".");if(t[n]||(t[n]={message:i,type:""+s}),o){var l=t[n].types,
|
|
1
|
+
import{appendErrors as r}from"react-hook-form";import{validateFieldsNatively as e,toNestError as o}from"@hookform/resolvers";import{Value as t}from"@sinclair/typebox/value";var a=function(e,o){for(var t={};e.length;){var a=e[0],s=a.type,i=a.message,n=a.path.substring(1).replace(/\//g,".");if(t[n]||(t[n]={message:i,type:""+s}),o){var l=t[n].types,m=l&&l[""+s];t[n]=r(n,o,t,""+s,m?[].concat(m,a.message):a.message)}e.shift()}return t},s=function(r){return function(s,i,n){try{var l=Array.from(t.Errors(r,s));return n.shouldUseNativeValidation&&e({},n),Promise.resolve(l.length?{values:{},errors:o(a(l,!n.shouldUseNativeValidation&&"all"===n.criteriaMode),n)}:{errors:{},values:s})}catch(r){return Promise.reject(r)}}};export{s as typeboxResolver};
|
|
2
2
|
//# sourceMappingURL=typebox.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typebox.module.js","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors =
|
|
1
|
+
{"version":3,"file":"typebox.module.js","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors = Array.from(Value.Errors(schema, values));\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (!errors.length) {\n return {\n errors: {} as FieldErrors,\n values,\n };\n }\n\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(\n errors,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","_errors","validateAllFieldCriteria","errors","length","error","type","message","_path","path","substring","replace","types","messages","appendErrors","concat","shift","typeboxResolver","schema","values","_","options","Array","from","Value","Errors","shouldUseNativeValidation","validateFieldsNatively","Promise","resolve","toNestError","criteriaMode","e","reject"],"mappings":"6KAKA,IAAMA,EAAmB,SACvBC,EACAC,GAGA,IADA,IAAMC,EAAqC,CAAE,EACtCF,EAAQG,QAAU,CACvB,IAAMC,EAAQJ,EAAQ,GACdK,EAAwBD,EAAxBC,KAAMC,EAAkBF,EAAlBE,QACRC,EAD0BH,EAATI,KACJC,UAAU,GAAGC,QAAQ,MAAO,KAM/C,GAJKR,EAAOK,KACVL,EAAOK,GAAS,CAAED,QAAAA,EAASD,KAAM,GAAKA,IAGpCJ,EAA0B,CAC5B,IAAMU,EAAQT,EAAOK,GAAOI,MACtBC,EAAWD,GAASA,EAAM,GAAKN,GAErCH,EAAOK,GAASM,EACdN,EACAN,EACAC,EACA,GAAKG,EACLO,EACK,GAAgBE,OAAOF,EAAsBR,EAAME,SACpDF,EAAME,QAEb,CAEDN,EAAQe,OACT,CAED,OAAOb,CACT,EAEac,EACX,SAACC,GAAM,OAAA,SAAYC,EAAQC,EAAGC,GAAW,IACvC,IAAMlB,EAASmB,MAAMC,KAAKC,EAAMC,OAAOP,EAAQC,IAI/C,OAFAE,EAAQK,2BAA6BC,EAAuB,CAAA,EAAIN,GAShEO,QAAAC,QAPK1B,EAAOC,OAOL,CACLe,OAAQ,CAAE,EACVhB,OAAQ2B,EACN9B,EACEG,GACCkB,EAAQK,2BAAsD,QAAzBL,EAAQU,cAEhDV,IAbK,CACLlB,OAAQ,GACRgB,OAAAA,GAcN,CAAC,MAAAa,GAAAJ,OAAAA,QAAAK,OAAAD,EAAA,CAAA,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("react-hook-form"),require("@hookform/resolvers"),require("@sinclair/typebox/value")):"function"==typeof define&&define.amd?define(["exports","react-hook-form","@hookform/resolvers","@sinclair/typebox/value"],r):r((e||self).hookformResolversTypebox={},e.ReactHookForm,e.hookformResolvers,e.value)}(this,function(e,r,o,t){var s=function(e,o){for(var t={};e.length;){var s=e[0],a=s.type,i=s.message,
|
|
1
|
+
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("react-hook-form"),require("@hookform/resolvers"),require("@sinclair/typebox/value")):"function"==typeof define&&define.amd?define(["exports","react-hook-form","@hookform/resolvers","@sinclair/typebox/value"],r):r((e||self).hookformResolversTypebox={},e.ReactHookForm,e.hookformResolvers,e.value)}(this,function(e,r,o,t){var s=function(e,o){for(var t={};e.length;){var s=e[0],a=s.type,i=s.message,l=s.path.substring(1).replace(/\//g,".");if(t[l]||(t[l]={message:i,type:""+a}),o){var n=t[l].types,f=n&&n[""+a];t[l]=r.appendErrors(l,o,t,""+a,f?[].concat(f,s.message):s.message)}e.shift()}return t};e.typeboxResolver=function(e){return function(r,a,i){try{var l=Array.from(t.Value.Errors(e,r));return i.shouldUseNativeValidation&&o.validateFieldsNatively({},i),Promise.resolve(l.length?{values:{},errors:o.toNestError(s(l,!i.shouldUseNativeValidation&&"all"===i.criteriaMode),i)}:{errors:{},values:r})}catch(e){return Promise.reject(e)}}}});
|
|
2
2
|
//# sourceMappingURL=typebox.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typebox.umd.js","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors =
|
|
1
|
+
{"version":3,"file":"typebox.umd.js","sources":["../src/typebox.ts"],"sourcesContent":["import { appendErrors, FieldError, FieldErrors } from 'react-hook-form';\nimport { toNestError, validateFieldsNatively } from '@hookform/resolvers';\nimport type { Resolver } from './types';\nimport { Value, ValueError } from '@sinclair/typebox/value';\n\nconst parseErrorSchema = (\n _errors: ValueError[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; _errors.length; ) {\n const error = _errors[0];\n const { type, message, path } = error;\n const _path = path.substring(1).replace(/\\//g, '.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: '' + type };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types['' + type];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '' + type,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n _errors.shift();\n }\n\n return errors;\n};\n\nexport const typeboxResolver: Resolver =\n (schema) => async (values, _, options) => {\n const errors = Array.from(Value.Errors(schema, values));\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (!errors.length) {\n return {\n errors: {} as FieldErrors,\n values,\n };\n }\n\n return {\n values: {},\n errors: toNestError(\n parseErrorSchema(\n errors,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","_errors","validateAllFieldCriteria","errors","length","error","type","message","_path","path","substring","replace","types","messages","appendErrors","concat","shift","schema","values","_","options","Array","from","Value","Errors","shouldUseNativeValidation","validateFieldsNatively","Promise","resolve","toNestError","criteriaMode","e","reject"],"mappings":"mcAKA,IAAMA,EAAmB,SACvBC,EACAC,GAGA,IADA,IAAMC,EAAqC,CAAE,EACtCF,EAAQG,QAAU,CACvB,IAAMC,EAAQJ,EAAQ,GACdK,EAAwBD,EAAxBC,KAAMC,EAAkBF,EAAlBE,QACRC,EAD0BH,EAATI,KACJC,UAAU,GAAGC,QAAQ,MAAO,KAM/C,GAJKR,EAAOK,KACVL,EAAOK,GAAS,CAAED,QAAAA,EAASD,KAAM,GAAKA,IAGpCJ,EAA0B,CAC5B,IAAMU,EAAQT,EAAOK,GAAOI,MACtBC,EAAWD,GAASA,EAAM,GAAKN,GAErCH,EAAOK,GAASM,EAAYA,aAC1BN,EACAN,EACAC,EACA,GAAKG,EACLO,EACK,GAAgBE,OAAOF,EAAsBR,EAAME,SACpDF,EAAME,QAEb,CAEDN,EAAQe,OACT,CAED,OAAOb,CACT,oBAGE,SAACc,GAAM,OAAA,SAAYC,EAAQC,EAAGC,GAAW,IACvC,IAAMjB,EAASkB,MAAMC,KAAKC,EAAAA,MAAMC,OAAOP,EAAQC,IAI/C,OAFAE,EAAQK,2BAA6BC,EAAAA,uBAAuB,CAAA,EAAIN,GAShEO,QAAAC,QAPKzB,EAAOC,OAOL,CACLc,OAAQ,CAAE,EACVf,OAAQ0B,EAAAA,YACN7B,EACEG,GACCiB,EAAQK,2BAAsD,QAAzBL,EAAQU,cAEhDV,IAbK,CACLjB,OAAQ,GACRe,OAAAA,GAcN,CAAC,MAAAa,GAAAJ,OAAAA,QAAAK,OAAAD,EAAA,CAAA,CAAA"}
|
|
@@ -4,43 +4,43 @@ exports[`typeboxResolver > should return a single error from typeboxResolver whe
|
|
|
4
4
|
{
|
|
5
5
|
"errors": {
|
|
6
6
|
"accessToken": {
|
|
7
|
-
"message": "Expected
|
|
7
|
+
"message": "Expected value of union",
|
|
8
8
|
"ref": undefined,
|
|
9
|
-
"type": "
|
|
9
|
+
"type": "53",
|
|
10
10
|
},
|
|
11
11
|
"birthYear": {
|
|
12
12
|
"message": "Expected number",
|
|
13
13
|
"ref": undefined,
|
|
14
|
-
"type": "
|
|
14
|
+
"type": "29",
|
|
15
15
|
},
|
|
16
16
|
"dateStr": {
|
|
17
|
-
"message": "Expected
|
|
17
|
+
"message": "Expected Date object",
|
|
18
18
|
"ref": undefined,
|
|
19
|
-
"type": "
|
|
19
|
+
"type": "11",
|
|
20
20
|
},
|
|
21
21
|
"email": {
|
|
22
22
|
"message": "Expected string to match format 'email'",
|
|
23
23
|
"ref": {
|
|
24
24
|
"name": "email",
|
|
25
25
|
},
|
|
26
|
-
"type": "
|
|
26
|
+
"type": "48",
|
|
27
27
|
},
|
|
28
28
|
"enabled": {
|
|
29
|
-
"message": "Expected
|
|
29
|
+
"message": "Expected boolean",
|
|
30
30
|
"ref": undefined,
|
|
31
|
-
"type": "
|
|
31
|
+
"type": "10",
|
|
32
32
|
},
|
|
33
33
|
"like": [
|
|
34
34
|
{
|
|
35
35
|
"id": {
|
|
36
36
|
"message": "Expected number",
|
|
37
37
|
"ref": undefined,
|
|
38
|
-
"type": "
|
|
38
|
+
"type": "29",
|
|
39
39
|
},
|
|
40
40
|
"name": {
|
|
41
|
-
"message": "Expected
|
|
41
|
+
"message": "Expected string",
|
|
42
42
|
"ref": undefined,
|
|
43
|
-
"type": "
|
|
43
|
+
"type": "43",
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
46
|
],
|
|
@@ -49,24 +49,24 @@ exports[`typeboxResolver > should return a single error from typeboxResolver whe
|
|
|
49
49
|
"ref": {
|
|
50
50
|
"name": "password",
|
|
51
51
|
},
|
|
52
|
-
"type": "
|
|
52
|
+
"type": "44",
|
|
53
53
|
},
|
|
54
54
|
"repeatPassword": {
|
|
55
|
-
"message": "Expected
|
|
55
|
+
"message": "Expected string",
|
|
56
56
|
"ref": undefined,
|
|
57
|
-
"type": "
|
|
57
|
+
"type": "43",
|
|
58
58
|
},
|
|
59
59
|
"tags": {
|
|
60
|
-
"message": "Expected
|
|
60
|
+
"message": "Expected array",
|
|
61
61
|
"ref": undefined,
|
|
62
|
-
"type": "
|
|
62
|
+
"type": "0",
|
|
63
63
|
},
|
|
64
64
|
"username": {
|
|
65
|
-
"message": "Expected
|
|
65
|
+
"message": "Expected string",
|
|
66
66
|
"ref": {
|
|
67
67
|
"name": "username",
|
|
68
68
|
},
|
|
69
|
-
"type": "
|
|
69
|
+
"type": "43",
|
|
70
70
|
},
|
|
71
71
|
},
|
|
72
72
|
"values": {},
|
|
@@ -77,31 +77,31 @@ exports[`typeboxResolver > should return all the errors from typeboxResolver whe
|
|
|
77
77
|
{
|
|
78
78
|
"errors": {
|
|
79
79
|
"accessToken": {
|
|
80
|
-
"message": "Expected
|
|
80
|
+
"message": "Expected value of union",
|
|
81
81
|
"ref": undefined,
|
|
82
|
-
"type": "
|
|
82
|
+
"type": "53",
|
|
83
83
|
"types": {
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
84
|
+
"29": "Expected number",
|
|
85
|
+
"39": "Expected required property",
|
|
86
|
+
"43": "Expected string",
|
|
87
|
+
"53": "Expected value of union",
|
|
88
88
|
},
|
|
89
89
|
},
|
|
90
90
|
"birthYear": {
|
|
91
91
|
"message": "Expected number",
|
|
92
92
|
"ref": undefined,
|
|
93
|
-
"type": "
|
|
93
|
+
"type": "29",
|
|
94
94
|
"types": {
|
|
95
|
-
"
|
|
95
|
+
"29": "Expected number",
|
|
96
96
|
},
|
|
97
97
|
},
|
|
98
98
|
"dateStr": {
|
|
99
|
-
"message": "Expected
|
|
99
|
+
"message": "Expected Date object",
|
|
100
100
|
"ref": undefined,
|
|
101
|
-
"type": "
|
|
101
|
+
"type": "11",
|
|
102
102
|
"types": {
|
|
103
|
-
"
|
|
104
|
-
"
|
|
103
|
+
"11": "Expected Date object",
|
|
104
|
+
"39": "Expected required property",
|
|
105
105
|
},
|
|
106
106
|
},
|
|
107
107
|
"email": {
|
|
@@ -109,18 +109,18 @@ exports[`typeboxResolver > should return all the errors from typeboxResolver whe
|
|
|
109
109
|
"ref": {
|
|
110
110
|
"name": "email",
|
|
111
111
|
},
|
|
112
|
-
"type": "
|
|
112
|
+
"type": "48",
|
|
113
113
|
"types": {
|
|
114
|
-
"
|
|
114
|
+
"48": "Expected string to match format 'email'",
|
|
115
115
|
},
|
|
116
116
|
},
|
|
117
117
|
"enabled": {
|
|
118
|
-
"message": "Expected
|
|
118
|
+
"message": "Expected boolean",
|
|
119
119
|
"ref": undefined,
|
|
120
|
-
"type": "
|
|
120
|
+
"type": "10",
|
|
121
121
|
"types": {
|
|
122
|
-
"
|
|
123
|
-
"
|
|
122
|
+
"10": "Expected boolean",
|
|
123
|
+
"39": "Expected required property",
|
|
124
124
|
},
|
|
125
125
|
},
|
|
126
126
|
"like": [
|
|
@@ -128,18 +128,18 @@ exports[`typeboxResolver > should return all the errors from typeboxResolver whe
|
|
|
128
128
|
"id": {
|
|
129
129
|
"message": "Expected number",
|
|
130
130
|
"ref": undefined,
|
|
131
|
-
"type": "
|
|
131
|
+
"type": "29",
|
|
132
132
|
"types": {
|
|
133
|
-
"
|
|
133
|
+
"29": "Expected number",
|
|
134
134
|
},
|
|
135
135
|
},
|
|
136
136
|
"name": {
|
|
137
|
-
"message": "Expected
|
|
137
|
+
"message": "Expected string",
|
|
138
138
|
"ref": undefined,
|
|
139
|
-
"type": "
|
|
139
|
+
"type": "43",
|
|
140
140
|
"types": {
|
|
141
|
-
"
|
|
142
|
-
"
|
|
141
|
+
"39": "Expected required property",
|
|
142
|
+
"43": "Expected string",
|
|
143
143
|
},
|
|
144
144
|
},
|
|
145
145
|
},
|
|
@@ -149,39 +149,39 @@ exports[`typeboxResolver > should return all the errors from typeboxResolver whe
|
|
|
149
149
|
"ref": {
|
|
150
150
|
"name": "password",
|
|
151
151
|
},
|
|
152
|
-
"type": "
|
|
152
|
+
"type": "44",
|
|
153
153
|
"types": {
|
|
154
|
-
"
|
|
155
|
-
"
|
|
154
|
+
"44": "Expected string length greater or equal to 8",
|
|
155
|
+
"46": "Expected string to match pattern ^(.*[A-Za-z\\\\d].*)$",
|
|
156
156
|
},
|
|
157
157
|
},
|
|
158
158
|
"repeatPassword": {
|
|
159
|
-
"message": "Expected
|
|
159
|
+
"message": "Expected string",
|
|
160
160
|
"ref": undefined,
|
|
161
|
-
"type": "
|
|
161
|
+
"type": "43",
|
|
162
162
|
"types": {
|
|
163
|
-
"
|
|
164
|
-
"
|
|
163
|
+
"39": "Expected required property",
|
|
164
|
+
"43": "Expected string",
|
|
165
165
|
},
|
|
166
166
|
},
|
|
167
167
|
"tags": {
|
|
168
|
-
"message": "Expected
|
|
168
|
+
"message": "Expected array",
|
|
169
169
|
"ref": undefined,
|
|
170
|
-
"type": "
|
|
170
|
+
"type": "0",
|
|
171
171
|
"types": {
|
|
172
172
|
"0": "Expected array",
|
|
173
|
-
"
|
|
173
|
+
"39": "Expected required property",
|
|
174
174
|
},
|
|
175
175
|
},
|
|
176
176
|
"username": {
|
|
177
|
-
"message": "Expected
|
|
177
|
+
"message": "Expected string",
|
|
178
178
|
"ref": {
|
|
179
179
|
"name": "username",
|
|
180
180
|
},
|
|
181
|
-
"type": "
|
|
181
|
+
"type": "43",
|
|
182
182
|
"types": {
|
|
183
|
-
"
|
|
184
|
-
"
|
|
183
|
+
"39": "Expected required property",
|
|
184
|
+
"43": "Expected string",
|
|
185
185
|
},
|
|
186
186
|
},
|
|
187
187
|
},
|
package/typebox/src/typebox.ts
CHANGED
|
@@ -40,7 +40,7 @@ const parseErrorSchema = (
|
|
|
40
40
|
|
|
41
41
|
export const typeboxResolver: Resolver =
|
|
42
42
|
(schema) => async (values, _, options) => {
|
|
43
|
-
const errors =
|
|
43
|
+
const errors = Array.from(Value.Errors(schema, values));
|
|
44
44
|
|
|
45
45
|
options.shouldUseNativeValidation && validateFieldsNatively({}, options);
|
|
46
46
|
|