@hookform/resolvers 3.3.4 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,6 +45,7 @@
45
45
  - [TypeBox](#typebox)
46
46
  - [ArkType](#arktype)
47
47
  - [Valibot](#valibot)
48
+ - [effect-ts](#effect-ts)
48
49
  - [Backers](#backers)
49
50
  - [Sponsors](#sponsors)
50
51
  - [Contributors](#contributors)
@@ -576,6 +577,57 @@ const App = () => {
576
577
  };
577
578
  ```
578
579
 
580
+ ### [effect-ts](https://github.com/Effect-TS/effect)
581
+
582
+ A powerful TypeScript framework that provides a fully-fledged functional effect system with a rich standard library.
583
+
584
+ [![npm](https://img.shields.io/bundlephobia/minzip/valibot?style=for-the-badge)](https://bundlephobia.com/result?p=effect)
585
+
586
+ ```typescript jsx
587
+ import React from 'react';
588
+ import { useForm } from 'react-hook-form';
589
+ import { effectTsResolver } from '@hookform/resolvers/effect-ts';
590
+ import { Schema } from '@effect/schema';
591
+
592
+ const schema = Schema.Struct({
593
+ username: Schema.String.pipe(
594
+ Schema.nonEmpty({ message: () => 'username required' }),
595
+ ),
596
+ password: Schema.String.pipe(
597
+ Schema.nonEmpty({ message: () => 'password required' }),
598
+ ),
599
+ });
600
+
601
+ type FormData = Schema.Schema.Type<typeof schema>;
602
+
603
+ interface Props {
604
+ onSubmit: (data: FormData) => void;
605
+ }
606
+
607
+ function TestComponent({ onSubmit }: Props) {
608
+ const {
609
+ register,
610
+ handleSubmit,
611
+ formState: { errors },
612
+ // provide generic if TS has issues inferring types
613
+ } = useForm<FormData>({
614
+ resolver: effectTsResolver(schema),
615
+ });
616
+
617
+ return (
618
+ <form onSubmit={handleSubmit(onSubmit)}>
619
+ <input {...register('username')} />
620
+ {errors.username && <span role="alert">{errors.username.message}</span>}
621
+
622
+ <input {...register('password')} />
623
+ {errors.password && <span role="alert">{errors.password.message}</span>}
624
+
625
+ <button type="submit">submit</button>
626
+ </form>
627
+ );
628
+ }
629
+ ```
630
+
579
631
  ## Backers
580
632
 
581
633
  Thanks goes to all our backers! [[Become a backer](https://opencollective.com/react-hook-form#backer)].
package/dist/resolvers.js CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("react-hook-form"),r=function(r,t,i){if(r&&"reportValidity"in r){var s=e.get(i,t);r.setCustomValidity(s&&s.message||""),r.reportValidity()}},t=function(e,t){var i=function(i){var s=t.fields[i];s&&s.ref&&"reportValidity"in s.ref?r(s.ref,i,e):s.refs&&s.refs.forEach(function(t){return r(t,i,e)})};for(var s in t.fields)i(s)},i=function(e,r){return e.some(function(e){return e.startsWith(r+".")})};exports.toNestErrors=function(r,s){s.shouldUseNativeValidation&&t(r,s);var a={};for(var n in r){var o=e.get(s.fields,n),f=Object.assign(r[n]||{},{ref:o&&o.ref});if(i(s.names||Object.keys(r),n)){var u=Object.assign({},e.get(a,n));e.set(u,"root",f),e.set(a,n,u)}else e.set(a,n,f)}return a},exports.validateFieldsNatively=t;
1
+ var e=require("react-hook-form");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=/*#__PURE__*/r(require("lodash.set")),i=function(r,t,i){if(r&&"reportValidity"in r){var a=e.get(i,t);r.setCustomValidity(a&&a.message||""),r.reportValidity()}},a=function(e,r){var t=function(t){var a=r.fields[t];a&&a.ref&&"reportValidity"in a.ref?i(a.ref,t,e):a.refs&&a.refs.forEach(function(r){return i(r,t,e)})};for(var a in r.fields)t(a)},f=function(e,r){return e.some(function(e){return e.startsWith(r+".")})};exports.toNestErrors=function(r,i){i.shouldUseNativeValidation&&a(r,i);var n={};for(var o in r){var s=e.get(i.fields,o),u=Object.assign(r[o]||{},{ref:s&&s.ref});if(f(i.names||Object.keys(r),o)){var l=Object.assign({},e.get(n,o));t.default(l,"root",u),t.default(n,o,l)}else t.default(n,o,u)}return n},exports.validateFieldsNatively=a;
2
2
  //# sourceMappingURL=resolvers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n set,\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","_loop","field","fields","refs","forEach","isNameInFieldArray","names","name","some","n","startsWith","shouldUseNativeValidation","fieldErrors","path","Object","assign","keys","fieldArrayErrors","set"],"mappings":"iCASMA,EAAoB,SACxBC,EACAC,EACAC,GAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,IAAMG,EAAQC,MAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,CACH,EAGaC,EAAyB,SACpCL,EACAM,GACQ,IAAAC,EAAAA,SAAAR,GAEN,IAAMS,EAAQF,EAAQG,OAAOV,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAME,MACfF,EAAME,KAAKC,QAAQ,SAACb,GAAqB,OACvCD,EAAkBC,EAAKC,EAAWC,EAAO,EAG9C,EATD,IAAK,IAAMD,KAAaO,EAAQG,OAAMF,EAAAR,EAUxC,ECAMa,EAAqB,SACzBC,EACAC,GAAuB,OACpBD,EAAME,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC,uBA7BpB,SAC1Bd,EACAM,GAEAA,EAAQY,2BAA6Bb,EAAuBL,EAAQM,GAEpE,IAAMa,EAAc,GACpB,IAAK,IAAMC,KAAQpB,EAAQ,CACzB,IAAMQ,EAAQN,EAAGA,IAACI,EAAQG,OAAQW,GAC5BnB,EAAQoB,OAAOC,OAAOtB,EAAOoB,IAAS,CAAE,EAAE,CAC9CtB,IAAKU,GAASA,EAAMV,MAGtB,GAAIc,EAAmBN,EAAQO,OAASQ,OAAOE,KAAKvB,GAASoB,GAAO,CAClE,IAAMI,EAAmBH,OAAOC,OAAO,CAAA,EAAIpB,EAAGA,IAACiB,EAAaC,IAE5DK,EAAGA,IAACD,EAAkB,OAAQvB,GAC9BwB,EAAGA,IAACN,EAAaC,EAAMI,EACxB,MACCC,EAAGA,IAACN,EAAaC,EAAMnB,EAE1B,CAED,OAAOkB,CACT"}
1
+ {"version":3,"file":"resolvers.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport set from 'lodash.set';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","_loop","field","fields","refs","forEach","isNameInFieldArray","names","name","some","n","startsWith","shouldUseNativeValidation","fieldErrors","path","Object","assign","keys","fieldArrayErrors","set"],"mappings":"qJASMA,EAAoB,SACxBC,EACAC,EACAC,GAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,IAAMG,EAAQC,MAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,CACH,EAGaC,EAAyB,SACpCL,EACAM,GACQ,IAAAC,EAAAA,SAAAR,GAEN,IAAMS,EAAQF,EAAQG,OAAOV,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAME,MACfF,EAAME,KAAKC,QAAQ,SAACb,GAAqB,OACvCD,EAAkBC,EAAKC,EAAWC,EAAO,EAG9C,EATD,IAAK,IAAMD,KAAaO,EAAQG,OAAMF,EAAAR,EAUxC,ECAMa,EAAqB,SACzBC,EACAC,UACGD,EAAME,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC,uBA7BpB,SAC1Bd,EACAM,GAEAA,EAAQY,2BAA6Bb,EAAuBL,EAAQM,GAEpE,IAAMa,EAAc,GACpB,IAAK,IAAMC,KAAQpB,EAAQ,CACzB,IAAMQ,EAAQN,EAAGA,IAACI,EAAQG,OAAQW,GAC5BnB,EAAQoB,OAAOC,OAAOtB,EAAOoB,IAAS,CAAE,EAAE,CAC9CtB,IAAKU,GAASA,EAAMV,MAGtB,GAAIc,EAAmBN,EAAQO,OAASQ,OAAOE,KAAKvB,GAASoB,GAAO,CAClE,IAAMI,EAAmBH,OAAOC,OAAO,CAAA,EAAIpB,EAAGA,IAACiB,EAAaC,IAE5DK,EAAG,QAACD,EAAkB,OAAQvB,GAC9BwB,EAAG,QAACN,EAAaC,EAAMI,EACxB,MACCC,EAAG,QAACN,EAAaC,EAAMnB,EAE1B,CAED,OAAOkB,CACT"}
@@ -1,2 +1,2 @@
1
- import{get as r,set as e}from"react-hook-form";var t=function(e,t,i){if(e&&"reportValidity"in e){var n=r(i,t);e.setCustomValidity(n&&n.message||""),e.reportValidity()}},i=function(r,e){var i=function(i){var n=e.fields[i];n&&n.ref&&"reportValidity"in n.ref?t(n.ref,i,r):n.refs&&n.refs.forEach(function(e){return t(e,i,r)})};for(var n in e.fields)i(n)},n=function(t,n){n.shouldUseNativeValidation&&i(t,n);var f={};for(var a in t){var s=r(n.fields,a),u=Object.assign(t[a]||{},{ref:s&&s.ref});if(o(n.names||Object.keys(t),a)){var c=Object.assign({},r(f,a));e(c,"root",u),e(f,a,c)}else e(f,a,u)}return f},o=function(r,e){return r.some(function(r){return r.startsWith(e+".")})};export{n as toNestErrors,i as validateFieldsNatively};
1
+ import{get as r}from"react-hook-form";import t from"lodash.set";var e=function(t,e,i){if(t&&"reportValidity"in t){var o=r(i,e);t.setCustomValidity(o&&o.message||""),t.reportValidity()}},i=function(r,t){var i=function(i){var o=t.fields[i];o&&o.ref&&"reportValidity"in o.ref?e(o.ref,i,r):o.refs&&o.refs.forEach(function(t){return e(t,i,r)})};for(var o in t.fields)i(o)},o=function(e,o){o.shouldUseNativeValidation&&i(e,o);var f={};for(var a in e){var s=r(o.fields,a),u=Object.assign(e[a]||{},{ref:s&&s.ref});if(n(o.names||Object.keys(e),a)){var c=Object.assign({},r(f,a));t(c,"root",u),t(f,a,c)}else t(f,a,u)}return f},n=function(r,t){return r.some(function(r){return r.startsWith(t+".")})};export{o as toNestErrors,i as validateFieldsNatively};
2
2
  //# sourceMappingURL=resolvers.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.mjs","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n set,\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","fields","field","refs","forEach","toNestErrors","shouldUseNativeValidation","fieldErrors","path","Object","assign","isNameInFieldArray","names","keys","fieldArrayErrors","set","name","some","n","startsWith"],"mappings":"+CASA,MAAMA,EAAoBA,CACxBC,EACAC,EACAC,KAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,MAAMG,EAAQC,EAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,GAIUC,EAAyBA,CACpCL,EACAM,KAEA,IAAK,MAAMP,KAAaO,EAAQC,OAAQ,CACtC,MAAMC,EAAQF,EAAQC,OAAOR,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAMC,MACfD,EAAMC,KAAKC,QAASZ,GAClBD,EAAkBC,EAAKC,EAAWC,GAGvC,GCzBUW,EAAeA,CAC1BX,EACAM,KAEAA,EAAQM,2BAA6BP,EAAuBL,EAAQM,GAEpE,MAAMO,EAAc,CAAA,EACpB,IAAK,MAAMC,KAAQd,EAAQ,CACzB,MAAMQ,EAAQN,EAAII,EAAQC,OAAQO,GAC5Bb,EAAQc,OAAOC,OAAOhB,EAAOc,IAAS,GAAI,CAC9ChB,IAAKU,GAASA,EAAMV,MAGtB,GAAImB,EAAmBX,EAAQY,OAASH,OAAOI,KAAKnB,GAASc,GAAO,CAClE,MAAMM,EAAmBL,OAAOC,OAAO,CAAA,EAAId,EAAIW,EAAaC,IAE5DO,EAAID,EAAkB,OAAQnB,GAC9BoB,EAAIR,EAAaC,EAAMM,EACxB,MACCC,EAAIR,EAAaC,EAAMb,EAE1B,CAED,OAAOY,GAGHI,EAAqBA,CACzBC,EACAI,IACGJ,EAAMK,KAAMC,GAAMA,EAAEC,WAAWH,EAAO"}
1
+ {"version":3,"file":"resolvers.mjs","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport set from 'lodash.set';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","fields","field","refs","forEach","toNestErrors","shouldUseNativeValidation","fieldErrors","path","Object","assign","isNameInFieldArray","names","keys","fieldArrayErrors","set","name","some","n","startsWith"],"mappings":"gEASA,MAAMA,EAAoBA,CACxBC,EACAC,EACAC,KAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,MAAMG,EAAQC,EAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,GAIUC,EAAyBA,CACpCL,EACAM,KAEA,IAAK,MAAMP,KAAaO,EAAQC,OAAQ,CACtC,MAAMC,EAAQF,EAAQC,OAAOR,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAMC,MACfD,EAAMC,KAAKC,QAASZ,GAClBD,EAAkBC,EAAKC,EAAWC,GAGvC,GCzBUW,EAAeA,CAC1BX,EACAM,KAEAA,EAAQM,2BAA6BP,EAAuBL,EAAQM,GAEpE,MAAMO,EAAc,CAAA,EACpB,IAAK,MAAMC,KAAQd,EAAQ,CACzB,MAAMQ,EAAQN,EAAII,EAAQC,OAAQO,GAC5Bb,EAAQc,OAAOC,OAAOhB,EAAOc,IAAS,GAAI,CAC9ChB,IAAKU,GAASA,EAAMV,MAGtB,GAAImB,EAAmBX,EAAQY,OAASH,OAAOI,KAAKnB,GAASc,GAAO,CAClE,MAAMM,EAAmBL,OAAOC,OAAO,CAAA,EAAId,EAAIW,EAAaC,IAE5DO,EAAID,EAAkB,OAAQnB,GAC9BoB,EAAIR,EAAaC,EAAMM,EACxB,MACCC,EAAIR,EAAaC,EAAMb,EAE1B,CAED,OAAOY,GAGHI,EAAqBA,CACzBC,EACAI,IACGJ,EAAMK,KAAMC,GAAMA,EAAEC,WAAWH,EAAO"}
@@ -1,2 +1,2 @@
1
- import{get as r,set as e}from"react-hook-form";var t=function(e,t,i){if(e&&"reportValidity"in e){var n=r(i,t);e.setCustomValidity(n&&n.message||""),e.reportValidity()}},i=function(r,e){var i=function(i){var n=e.fields[i];n&&n.ref&&"reportValidity"in n.ref?t(n.ref,i,r):n.refs&&n.refs.forEach(function(e){return t(e,i,r)})};for(var n in e.fields)i(n)},n=function(t,n){n.shouldUseNativeValidation&&i(t,n);var f={};for(var a in t){var s=r(n.fields,a),u=Object.assign(t[a]||{},{ref:s&&s.ref});if(o(n.names||Object.keys(t),a)){var c=Object.assign({},r(f,a));e(c,"root",u),e(f,a,c)}else e(f,a,u)}return f},o=function(r,e){return r.some(function(r){return r.startsWith(e+".")})};export{n as toNestErrors,i as validateFieldsNatively};
1
+ import{get as r}from"react-hook-form";import t from"lodash.set";var e=function(t,e,i){if(t&&"reportValidity"in t){var o=r(i,e);t.setCustomValidity(o&&o.message||""),t.reportValidity()}},i=function(r,t){var i=function(i){var o=t.fields[i];o&&o.ref&&"reportValidity"in o.ref?e(o.ref,i,r):o.refs&&o.refs.forEach(function(t){return e(t,i,r)})};for(var o in t.fields)i(o)},o=function(e,o){o.shouldUseNativeValidation&&i(e,o);var f={};for(var a in e){var s=r(o.fields,a),u=Object.assign(e[a]||{},{ref:s&&s.ref});if(n(o.names||Object.keys(e),a)){var c=Object.assign({},r(f,a));t(c,"root",u),t(f,a,c)}else t(f,a,u)}return f},n=function(r,t){return r.some(function(r){return r.startsWith(t+".")})};export{o as toNestErrors,i as validateFieldsNatively};
2
2
  //# sourceMappingURL=resolvers.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.module.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n set,\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","_loop","field","fields","refs","forEach","toNestErrors","shouldUseNativeValidation","fieldErrors","path","Object","assign","isNameInFieldArray","names","keys","fieldArrayErrors","set","name","some","n","startsWith"],"mappings":"+CASA,IAAMA,EAAoB,SACxBC,EACAC,EACAC,GAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,IAAMG,EAAQC,EAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,CACH,EAGaC,EAAyB,SACpCL,EACAM,GACQ,IAAAC,EAAAA,SAAAR,GAEN,IAAMS,EAAQF,EAAQG,OAAOV,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAME,MACfF,EAAME,KAAKC,QAAQ,SAACb,GAAqB,OACvCD,EAAkBC,EAAKC,EAAWC,EAAO,EAG9C,EATD,IAAK,IAAMD,KAAaO,EAAQG,OAAMF,EAAAR,EAUxC,EC1Baa,EAAe,SAC1BZ,EACAM,GAEAA,EAAQO,2BAA6BR,EAAuBL,EAAQM,GAEpE,IAAMQ,EAAc,GACpB,IAAK,IAAMC,KAAQf,EAAQ,CACzB,IAAMQ,EAAQN,EAAII,EAAQG,OAAQM,GAC5Bd,EAAQe,OAAOC,OAAOjB,EAAOe,IAAS,CAAE,EAAE,CAC9CjB,IAAKU,GAASA,EAAMV,MAGtB,GAAIoB,EAAmBZ,EAAQa,OAASH,OAAOI,KAAKpB,GAASe,GAAO,CAClE,IAAMM,EAAmBL,OAAOC,OAAO,CAAA,EAAIf,EAAIY,EAAaC,IAE5DO,EAAID,EAAkB,OAAQpB,GAC9BqB,EAAIR,EAAaC,EAAMM,EACxB,MACCC,EAAIR,EAAaC,EAAMd,EAE1B,CAED,OAAOa,CACT,EAEMI,EAAqB,SACzBC,EACAI,GAAuB,OACpBJ,EAAMK,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC"}
1
+ {"version":3,"file":"resolvers.module.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport set from 'lodash.set';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","_loop","field","fields","refs","forEach","toNestErrors","shouldUseNativeValidation","fieldErrors","path","Object","assign","isNameInFieldArray","names","keys","fieldArrayErrors","set","name","some","n","startsWith"],"mappings":"gEASA,IAAMA,EAAoB,SACxBC,EACAC,EACAC,GAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,IAAMG,EAAQC,EAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,CACH,EAGaC,EAAyB,SACpCL,EACAM,GACQ,IAAAC,EAAAA,SAAAR,GAEN,IAAMS,EAAQF,EAAQG,OAAOV,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAME,MACfF,EAAME,KAAKC,QAAQ,SAACb,GAAqB,OACvCD,EAAkBC,EAAKC,EAAWC,EAAO,EAG9C,EATD,IAAK,IAAMD,KAAaO,EAAQG,OAAMF,EAAAR,EAUxC,EC1Baa,EAAe,SAC1BZ,EACAM,GAEAA,EAAQO,2BAA6BR,EAAuBL,EAAQM,GAEpE,IAAMQ,EAAc,GACpB,IAAK,IAAMC,KAAQf,EAAQ,CACzB,IAAMQ,EAAQN,EAAII,EAAQG,OAAQM,GAC5Bd,EAAQe,OAAOC,OAAOjB,EAAOe,IAAS,CAAE,EAAE,CAC9CjB,IAAKU,GAASA,EAAMV,MAGtB,GAAIoB,EAAmBZ,EAAQa,OAASH,OAAOI,KAAKpB,GAASe,GAAO,CAClE,IAAMM,EAAmBL,OAAOC,OAAO,CAAA,EAAIf,EAAIY,EAAaC,IAE5DO,EAAID,EAAkB,OAAQpB,GAC9BqB,EAAIR,EAAaC,EAAMM,EACxB,MACCC,EAAIR,EAAaC,EAAMd,EAE1B,CAED,OAAOa,CACT,EAEMI,EAAqB,SACzBC,EACAI,UACGJ,EAAMK,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC"}
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react-hook-form")):"function"==typeof define&&define.amd?define(["exports","react-hook-form"],t):t((e||self).hookformResolvers={},e.ReactHookForm)}(this,function(e,t){var r=function(e,r,o){if(e&&"reportValidity"in e){var i=t.get(o,r);e.setCustomValidity(i&&i.message||""),e.reportValidity()}},o=function(e,t){var o=function(o){var i=t.fields[o];i&&i.ref&&"reportValidity"in i.ref?r(i.ref,o,e):i.refs&&i.refs.forEach(function(t){return r(t,o,e)})};for(var i in t.fields)o(i)},i=function(e,t){return e.some(function(e){return e.startsWith(t+".")})};e.toNestErrors=function(e,r){r.shouldUseNativeValidation&&o(e,r);var n={};for(var f in e){var s=t.get(r.fields,f),a=Object.assign(e[f]||{},{ref:s&&s.ref});if(i(r.names||Object.keys(e),f)){var d=Object.assign({},t.get(n,f));t.set(d,"root",a),t.set(n,f,d)}else t.set(n,f,a)}return n},e.validateFieldsNatively=o});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react-hook-form"),require("lodash.set")):"function"==typeof define&&define.amd?define(["exports","react-hook-form","lodash.set"],t):t((e||self).hookformResolvers={},e.ReactHookForm,e.set)}(this,function(e,t,r){function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=/*#__PURE__*/o(r),f=function(e,r,o){if(e&&"reportValidity"in e){var i=t.get(o,r);e.setCustomValidity(i&&i.message||""),e.reportValidity()}},n=function(e,t){var r=function(r){var o=t.fields[r];o&&o.ref&&"reportValidity"in o.ref?f(o.ref,r,e):o.refs&&o.refs.forEach(function(t){return f(t,r,e)})};for(var o in t.fields)r(o)},a=function(e,t){return e.some(function(e){return e.startsWith(t+".")})};e.toNestErrors=function(e,r){r.shouldUseNativeValidation&&n(e,r);var o={};for(var f in e){var s=t.get(r.fields,f),u=Object.assign(e[f]||{},{ref:s&&s.ref});if(a(r.names||Object.keys(e),f)){var d=Object.assign({},t.get(o,f));i.default(d,"root",u),i.default(o,f,d)}else i.default(o,f,u)}return o},e.validateFieldsNatively=n});
2
2
  //# sourceMappingURL=resolvers.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.umd.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n set,\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","_loop","field","fields","refs","forEach","isNameInFieldArray","names","name","some","n","startsWith","shouldUseNativeValidation","fieldErrors","path","Object","assign","keys","fieldArrayErrors","set"],"mappings":"0SASA,IAAMA,EAAoB,SACxBC,EACAC,EACAC,GAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,IAAMG,EAAQC,MAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,CACH,EAGaC,EAAyB,SACpCL,EACAM,GACQ,IAAAC,EAAAA,SAAAR,GAEN,IAAMS,EAAQF,EAAQG,OAAOV,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAME,MACfF,EAAME,KAAKC,QAAQ,SAACb,GAAqB,OACvCD,EAAkBC,EAAKC,EAAWC,EAAO,EAG9C,EATD,IAAK,IAAMD,KAAaO,EAAQG,OAAMF,EAAAR,EAUxC,ECAMa,EAAqB,SACzBC,EACAC,GAAuB,OACpBD,EAAME,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC,iBA7BpB,SAC1Bd,EACAM,GAEAA,EAAQY,2BAA6Bb,EAAuBL,EAAQM,GAEpE,IAAMa,EAAc,GACpB,IAAK,IAAMC,KAAQpB,EAAQ,CACzB,IAAMQ,EAAQN,EAAGA,IAACI,EAAQG,OAAQW,GAC5BnB,EAAQoB,OAAOC,OAAOtB,EAAOoB,IAAS,CAAE,EAAE,CAC9CtB,IAAKU,GAASA,EAAMV,MAGtB,GAAIc,EAAmBN,EAAQO,OAASQ,OAAOE,KAAKvB,GAASoB,GAAO,CAClE,IAAMI,EAAmBH,OAAOC,OAAO,CAAA,EAAIpB,EAAGA,IAACiB,EAAaC,IAE5DK,EAAGA,IAACD,EAAkB,OAAQvB,GAC9BwB,EAAGA,IAACN,EAAaC,EAAMI,EACxB,MACCC,EAAGA,IAACN,EAAaC,EAAMnB,EAE1B,CAED,OAAOkB,CACT"}
1
+ {"version":3,"file":"resolvers.umd.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n get,\n FieldError,\n ResolverOptions,\n Ref,\n FieldErrors,\n FieldValues,\n} from 'react-hook-form';\n\nconst setCustomValidity = (\n ref: Ref,\n fieldPath: string,\n errors: FieldErrors,\n) => {\n if (ref && 'reportValidity' in ref) {\n const error = get(errors, fieldPath) as FieldError | undefined;\n ref.setCustomValidity((error && error.message) || '');\n\n ref.reportValidity();\n }\n};\n\n// Native validation (web only)\nexport const validateFieldsNatively = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): void => {\n for (const fieldPath in options.fields) {\n const field = options.fields[fieldPath];\n if (field && field.ref && 'reportValidity' in field.ref) {\n setCustomValidity(field.ref, fieldPath, errors);\n } else if (field.refs) {\n field.refs.forEach((ref: HTMLInputElement) =>\n setCustomValidity(ref, fieldPath, errors),\n );\n }\n }\n};\n","import {\n get,\n FieldErrors,\n Field,\n ResolverOptions,\n FieldValues,\n InternalFieldName,\n} from 'react-hook-form';\nimport set from 'lodash.set';\nimport { validateFieldsNatively } from './validateFieldsNatively';\n\nexport const toNestErrors = <TFieldValues extends FieldValues>(\n errors: FieldErrors,\n options: ResolverOptions<TFieldValues>,\n): FieldErrors<TFieldValues> => {\n options.shouldUseNativeValidation && validateFieldsNatively(errors, options);\n\n const fieldErrors = {} as FieldErrors<TFieldValues>;\n for (const path in errors) {\n const field = get(options.fields, path) as Field['_f'] | undefined;\n const error = Object.assign(errors[path] || {}, {\n ref: field && field.ref,\n });\n\n if (isNameInFieldArray(options.names || Object.keys(errors), path)) {\n const fieldArrayErrors = Object.assign({}, get(fieldErrors, path));\n\n set(fieldArrayErrors, 'root', error);\n set(fieldErrors, path, fieldArrayErrors);\n } else {\n set(fieldErrors, path, error);\n }\n }\n\n return fieldErrors;\n};\n\nconst isNameInFieldArray = (\n names: InternalFieldName[],\n name: InternalFieldName,\n) => names.some((n) => n.startsWith(name + '.'));\n"],"names":["setCustomValidity","ref","fieldPath","errors","error","get","message","reportValidity","validateFieldsNatively","options","_loop","field","fields","refs","forEach","isNameInFieldArray","names","name","some","n","startsWith","shouldUseNativeValidation","fieldErrors","path","Object","assign","keys","fieldArrayErrors","set"],"mappings":"qbASMA,EAAoB,SACxBC,EACAC,EACAC,GAEA,GAAIF,GAAO,mBAAoBA,EAAK,CAClC,IAAMG,EAAQC,MAAIF,EAAQD,GAC1BD,EAAID,kBAAmBI,GAASA,EAAME,SAAY,IAElDL,EAAIM,gBACL,CACH,EAGaC,EAAyB,SACpCL,EACAM,GACQ,IAAAC,EAAAA,SAAAR,GAEN,IAAMS,EAAQF,EAAQG,OAAOV,GACzBS,GAASA,EAAMV,KAAO,mBAAoBU,EAAMV,IAClDD,EAAkBW,EAAMV,IAAKC,EAAWC,GAC/BQ,EAAME,MACfF,EAAME,KAAKC,QAAQ,SAACb,GAAqB,OACvCD,EAAkBC,EAAKC,EAAWC,EAAO,EAG9C,EATD,IAAK,IAAMD,KAAaO,EAAQG,OAAMF,EAAAR,EAUxC,ECAMa,EAAqB,SACzBC,EACAC,UACGD,EAAME,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC,iBA7BpB,SAC1Bd,EACAM,GAEAA,EAAQY,2BAA6Bb,EAAuBL,EAAQM,GAEpE,IAAMa,EAAc,GACpB,IAAK,IAAMC,KAAQpB,EAAQ,CACzB,IAAMQ,EAAQN,EAAGA,IAACI,EAAQG,OAAQW,GAC5BnB,EAAQoB,OAAOC,OAAOtB,EAAOoB,IAAS,CAAE,EAAE,CAC9CtB,IAAKU,GAASA,EAAMV,MAGtB,GAAIc,EAAmBN,EAAQO,OAASQ,OAAOE,KAAKvB,GAASoB,GAAO,CAClE,IAAMI,EAAmBH,OAAOC,OAAO,CAAA,EAAIpB,EAAGA,IAACiB,EAAaC,IAE5DK,EAAG,QAACD,EAAkB,OAAQvB,GAC9BwB,EAAG,QAACN,EAAaC,EAAMI,EACxB,MACCC,EAAG,QAACN,EAAaC,EAAMnB,EAE1B,CAED,OAAOkB,CACT"}
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from './types';
2
+ export declare const effectTsResolver: Resolver;
@@ -0,0 +1,2 @@
1
+ var e=require("@effect/schema/ParseResult"),r=require("@effect/schema/ArrayFormatter"),t=require("@hookform/resolvers");function n(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var o=/*#__PURE__*/n(require("effect/Effect"));exports.effectTsResolver=function(n,u){return void 0===u&&(u={errors:"all",onExcessProperty:"ignore"}),function(c,a,s){return e.decodeUnknown(n,u)(c).pipe(o.catchAll(function(e){return o.flip(r.formatIssue(e))}),o.mapError(function(e){var r=e.reduce(function(e,r){return e[r.path.join(".")]={message:r.message,type:r._tag},e},{});return t.toNestErrors(r,s)}),o.tap(function(){return o.sync(function(){return s.shouldUseNativeValidation&&t.validateFieldsNatively({},s)})}),o.match({onFailure:function(e){return{errors:e,values:{}}},onSuccess:function(e){return{errors:{},values:e}}}),o.runPromise)}};
2
+ //# sourceMappingURL=effect-ts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-ts.js","sources":["../src/effect-ts.ts"],"sourcesContent":["import { decodeUnknown } from '@effect/schema/ParseResult';\nimport { formatIssue } from '@effect/schema/ArrayFormatter';\nimport { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport * as Effect from 'effect/Effect';\nimport type { FieldErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nexport const effectTsResolver: Resolver =\n (schema, config = { errors: 'all', onExcessProperty: 'ignore' }) =>\n (values, _, options) => {\n return decodeUnknown(\n schema,\n config,\n )(values).pipe(\n Effect.catchAll((parseIssue) => Effect.flip(formatIssue(parseIssue))),\n Effect.mapError((issues) => {\n const errors = issues.reduce((acc, current) => {\n const key = current.path.join('.');\n acc[key] = { message: current.message, type: current._tag };\n return acc;\n }, {} as FieldErrors);\n\n return toNestErrors(errors, options);\n }),\n Effect.tap(() =>\n Effect.sync(\n () =>\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options),\n ),\n ),\n Effect.match({\n onFailure: (errors) => ({ errors, values: {} }),\n onSuccess: (result) => ({ errors: {}, values: result }),\n }),\n Effect.runPromise,\n );\n };\n"],"names":["schema","config","errors","onExcessProperty","values","_","options","decodeUnknown","pipe","Effect","catchAll","parseIssue","flip","formatIssue","mapError","issues","reduce","acc","current","path","join","message","type","_tag","toNestErrors","tap","sync","shouldUseNativeValidation","validateFieldsNatively","match","onFailure","onSuccess","result","runPromise"],"mappings":"8cAQE,SAACA,EAAQC,GAAsD,YAAtDA,IAAAA,IAAAA,EAAS,CAAEC,OAAQ,MAAOC,iBAAkB,WACpDC,SAAAA,EAAQC,EAAGC,GACV,OAAOC,EAAAA,cACLP,EACAC,EAFKM,CAGLH,GAAQI,KACRC,EAAOC,SAAS,SAACC,GAAe,OAAAF,EAAOG,KAAKC,EAAWA,YAACF,GAAY,GACpEF,EAAOK,SAAS,SAACC,GACf,IAAMb,EAASa,EAAOC,OAAO,SAACC,EAAKC,GAGjC,OADAD,EADYC,EAAQC,KAAKC,KAAK,MACnB,CAAEC,QAASH,EAAQG,QAASC,KAAMJ,EAAQK,MAC9CN,CACT,EAAG,CAAA,GAEH,OAAOO,EAAYA,aAACtB,EAAQI,EAC9B,GACAG,EAAOgB,IAAI,WACT,OAAAhB,EAAOiB,KACL,WACE,OAAApB,EAAQqB,2BACRC,yBAAuB,CAAA,EAAItB,EAAQ,EACtC,GAEHG,EAAOoB,MAAM,CACXC,UAAW,SAAC5B,GAAY,MAAA,CAAEA,OAAAA,EAAQE,OAAQ,CAAA,EAAI,EAC9C2B,UAAW,SAACC,GAAM,MAAM,CAAE9B,OAAQ,CAAA,EAAIE,OAAQ4B,EAAQ,IAExDvB,EAAOwB,WAEX,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{decodeUnknown as r}from"@effect/schema/ParseResult";import{formatIssue as e}from"@effect/schema/ArrayFormatter";import{toNestErrors as t,validateFieldsNatively as o}from"@hookform/resolvers";import*as n from"effect/Effect";var u=function(u,s){return void 0===s&&(s={errors:"all",onExcessProperty:"ignore"}),function(a,c,f){return r(u,s)(a).pipe(n.catchAll(function(r){return n.flip(e(r))}),n.mapError(function(r){var e=r.reduce(function(r,e){return r[e.path.join(".")]={message:e.message,type:e._tag},r},{});return t(e,f)}),n.tap(function(){return n.sync(function(){return f.shouldUseNativeValidation&&o({},f)})}),n.match({onFailure:function(r){return{errors:r,values:{}}},onSuccess:function(r){return{errors:{},values:r}}}),n.runPromise)}};export{u as effectTsResolver};
2
+ //# sourceMappingURL=effect-ts.module.js.map
@@ -0,0 +1,2 @@
1
+ import{decodeUnknown as r}from"@effect/schema/ParseResult";import{formatIssue as e}from"@effect/schema/ArrayFormatter";import{toNestErrors as o,validateFieldsNatively as s}from"@hookform/resolvers";import*as t from"effect/Effect";const a=(a,m={errors:"all",onExcessProperty:"ignore"})=>(c,f,i)=>r(a,m)(c).pipe(t.catchAll(r=>t.flip(e(r))),t.mapError(r=>{const e=r.reduce((r,e)=>(r[e.path.join(".")]={message:e.message,type:e._tag},r),{});return o(e,i)}),t.tap(()=>t.sync(()=>i.shouldUseNativeValidation&&s({},i))),t.match({onFailure:r=>({errors:r,values:{}}),onSuccess:r=>({errors:{},values:r})}),t.runPromise);export{a as effectTsResolver};
2
+ //# sourceMappingURL=effect-ts.modern.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-ts.modern.mjs","sources":["../src/effect-ts.ts"],"sourcesContent":["import { decodeUnknown } from '@effect/schema/ParseResult';\nimport { formatIssue } from '@effect/schema/ArrayFormatter';\nimport { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport * as Effect from 'effect/Effect';\nimport type { FieldErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nexport const effectTsResolver: Resolver =\n (schema, config = { errors: 'all', onExcessProperty: 'ignore' }) =>\n (values, _, options) => {\n return decodeUnknown(\n schema,\n config,\n )(values).pipe(\n Effect.catchAll((parseIssue) => Effect.flip(formatIssue(parseIssue))),\n Effect.mapError((issues) => {\n const errors = issues.reduce((acc, current) => {\n const key = current.path.join('.');\n acc[key] = { message: current.message, type: current._tag };\n return acc;\n }, {} as FieldErrors);\n\n return toNestErrors(errors, options);\n }),\n Effect.tap(() =>\n Effect.sync(\n () =>\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options),\n ),\n ),\n Effect.match({\n onFailure: (errors) => ({ errors, values: {} }),\n onSuccess: (result) => ({ errors: {}, values: result }),\n }),\n Effect.runPromise,\n );\n };\n"],"names":["effectTsResolver","schema","config","errors","onExcessProperty","values","_","options","decodeUnknown","pipe","Effect","catchAll","parseIssue","flip","formatIssue","mapError","issues","reduce","acc","current","path","join","message","type","_tag","toNestErrors","tap","sync","shouldUseNativeValidation","validateFieldsNatively","match","onFailure","onSuccess","result","runPromise"],"mappings":"sOAOa,MAAAA,EACXA,CAACC,EAAQC,EAAS,CAAEC,OAAQ,MAAOC,iBAAkB,YACrD,CAACC,EAAQC,EAAGC,IACHC,EACLP,EACAC,EAFKM,CAGLH,GAAQI,KACRC,EAAOC,SAAUC,GAAeF,EAAOG,KAAKC,EAAYF,KACxDF,EAAOK,SAAUC,IACf,MAAMb,EAASa,EAAOC,OAAO,CAACC,EAAKC,KAEjCD,EADYC,EAAQC,KAAKC,KAAK,MACnB,CAAEC,QAASH,EAAQG,QAASC,KAAMJ,EAAQK,MAC9CN,GACN,CAAiB,GAEpB,OAAOO,EAAatB,EAAQI,EAAO,GAErCG,EAAOgB,IAAI,IACThB,EAAOiB,KACL,IACEpB,EAAQqB,2BACRC,EAAuB,CAAE,EAAEtB,KAGjCG,EAAOoB,MAAM,CACXC,UAAY5B,IAAY,CAAEA,SAAQE,OAAQ,KAC1C2B,UAAYC,IAAM,CAAQ9B,OAAQ,GAAIE,OAAQ4B,MAEhDvB,EAAOwB"}
@@ -0,0 +1,2 @@
1
+ import{decodeUnknown as r}from"@effect/schema/ParseResult";import{formatIssue as e}from"@effect/schema/ArrayFormatter";import{toNestErrors as t,validateFieldsNatively as o}from"@hookform/resolvers";import*as n from"effect/Effect";var u=function(u,s){return void 0===s&&(s={errors:"all",onExcessProperty:"ignore"}),function(a,c,f){return r(u,s)(a).pipe(n.catchAll(function(r){return n.flip(e(r))}),n.mapError(function(r){var e=r.reduce(function(r,e){return r[e.path.join(".")]={message:e.message,type:e._tag},r},{});return t(e,f)}),n.tap(function(){return n.sync(function(){return f.shouldUseNativeValidation&&o({},f)})}),n.match({onFailure:function(r){return{errors:r,values:{}}},onSuccess:function(r){return{errors:{},values:r}}}),n.runPromise)}};export{u as effectTsResolver};
2
+ //# sourceMappingURL=effect-ts.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-ts.module.js","sources":["../src/effect-ts.ts"],"sourcesContent":["import { decodeUnknown } from '@effect/schema/ParseResult';\nimport { formatIssue } from '@effect/schema/ArrayFormatter';\nimport { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport * as Effect from 'effect/Effect';\nimport type { FieldErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nexport const effectTsResolver: Resolver =\n (schema, config = { errors: 'all', onExcessProperty: 'ignore' }) =>\n (values, _, options) => {\n return decodeUnknown(\n schema,\n config,\n )(values).pipe(\n Effect.catchAll((parseIssue) => Effect.flip(formatIssue(parseIssue))),\n Effect.mapError((issues) => {\n const errors = issues.reduce((acc, current) => {\n const key = current.path.join('.');\n acc[key] = { message: current.message, type: current._tag };\n return acc;\n }, {} as FieldErrors);\n\n return toNestErrors(errors, options);\n }),\n Effect.tap(() =>\n Effect.sync(\n () =>\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options),\n ),\n ),\n Effect.match({\n onFailure: (errors) => ({ errors, values: {} }),\n onSuccess: (result) => ({ errors: {}, values: result }),\n }),\n Effect.runPromise,\n );\n };\n"],"names":["effectTsResolver","schema","config","errors","onExcessProperty","values","_","options","decodeUnknown","pipe","Effect","catchAll","parseIssue","flip","formatIssue","mapError","issues","reduce","acc","current","path","join","message","type","_tag","toNestErrors","tap","sync","shouldUseNativeValidation","validateFieldsNatively","match","onFailure","onSuccess","result","runPromise"],"mappings":"sOAOa,IAAAA,EACX,SAACC,EAAQC,GAAsD,YAAtDA,IAAAA,IAAAA,EAAS,CAAEC,OAAQ,MAAOC,iBAAkB,WACpDC,SAAAA,EAAQC,EAAGC,GACV,OAAOC,EACLP,EACAC,EAFKM,CAGLH,GAAQI,KACRC,EAAOC,SAAS,SAACC,GAAe,OAAAF,EAAOG,KAAKC,EAAYF,GAAY,GACpEF,EAAOK,SAAS,SAACC,GACf,IAAMb,EAASa,EAAOC,OAAO,SAACC,EAAKC,GAGjC,OADAD,EADYC,EAAQC,KAAKC,KAAK,MACnB,CAAEC,QAASH,EAAQG,QAASC,KAAMJ,EAAQK,MAC9CN,CACT,EAAG,CAAA,GAEH,OAAOO,EAAatB,EAAQI,EAC9B,GACAG,EAAOgB,IAAI,WACT,OAAAhB,EAAOiB,KACL,WACE,OAAApB,EAAQqB,2BACRC,EAAuB,CAAA,EAAItB,EAAQ,EACtC,GAEHG,EAAOoB,MAAM,CACXC,UAAW,SAAC5B,GAAY,MAAA,CAAEA,OAAAA,EAAQE,OAAQ,CAAA,EAAI,EAC9C2B,UAAW,SAACC,GAAM,MAAM,CAAE9B,OAAQ,CAAA,EAAIE,OAAQ4B,EAAQ,IAExDvB,EAAOwB,WAEX,CAAC"}
@@ -0,0 +1,2 @@
1
+ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@effect/schema/ParseResult"),require("@effect/schema/ArrayFormatter"),require("@hookform/resolvers"),require("effect/Effect")):"function"==typeof define&&define.amd?define(["exports","@effect/schema/ParseResult","@effect/schema/ArrayFormatter","@hookform/resolvers","effect/Effect"],r):r((e||self).hookformResolversEffectTs={},e.ParseResult,e.EffectSchemaArrayFormatter,e.hookformResolvers,e.Effect)}(this,function(e,r,t,o,n){function f(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var o=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,o.get?o:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var s=/*#__PURE__*/f(n);e.effectTsResolver=function(e,n){return void 0===n&&(n={errors:"all",onExcessProperty:"ignore"}),function(f,u,c){return r.decodeUnknown(e,n)(f).pipe(s.catchAll(function(e){return s.flip(t.formatIssue(e))}),s.mapError(function(e){var r=e.reduce(function(e,r){return e[r.path.join(".")]={message:r.message,type:r._tag},e},{});return o.toNestErrors(r,c)}),s.tap(function(){return s.sync(function(){return c.shouldUseNativeValidation&&o.validateFieldsNatively({},c)})}),s.match({onFailure:function(e){return{errors:e,values:{}}},onSuccess:function(e){return{errors:{},values:e}}}),s.runPromise)}}});
2
+ //# sourceMappingURL=effect-ts.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-ts.umd.js","sources":["../src/effect-ts.ts"],"sourcesContent":["import { decodeUnknown } from '@effect/schema/ParseResult';\nimport { formatIssue } from '@effect/schema/ArrayFormatter';\nimport { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport * as Effect from 'effect/Effect';\nimport type { FieldErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nexport const effectTsResolver: Resolver =\n (schema, config = { errors: 'all', onExcessProperty: 'ignore' }) =>\n (values, _, options) => {\n return decodeUnknown(\n schema,\n config,\n )(values).pipe(\n Effect.catchAll((parseIssue) => Effect.flip(formatIssue(parseIssue))),\n Effect.mapError((issues) => {\n const errors = issues.reduce((acc, current) => {\n const key = current.path.join('.');\n acc[key] = { message: current.message, type: current._tag };\n return acc;\n }, {} as FieldErrors);\n\n return toNestErrors(errors, options);\n }),\n Effect.tap(() =>\n Effect.sync(\n () =>\n options.shouldUseNativeValidation &&\n validateFieldsNatively({}, options),\n ),\n ),\n Effect.match({\n onFailure: (errors) => ({ errors, values: {} }),\n onSuccess: (result) => ({ errors: {}, values: result }),\n }),\n Effect.runPromise,\n );\n };\n"],"names":["schema","config","errors","onExcessProperty","values","_","options","decodeUnknown","pipe","Effect","catchAll","parseIssue","flip","formatIssue","mapError","issues","reduce","acc","current","path","join","message","type","_tag","toNestErrors","tap","sync","shouldUseNativeValidation","validateFieldsNatively","match","onFailure","onSuccess","result","runPromise"],"mappings":"s2BAQE,SAACA,EAAQC,GAAsD,YAAtDA,IAAAA,IAAAA,EAAS,CAAEC,OAAQ,MAAOC,iBAAkB,WACpDC,SAAAA,EAAQC,EAAGC,GACV,OAAOC,EAAAA,cACLP,EACAC,EAFKM,CAGLH,GAAQI,KACRC,EAAOC,SAAS,SAACC,GAAe,OAAAF,EAAOG,KAAKC,EAAWA,YAACF,GAAY,GACpEF,EAAOK,SAAS,SAACC,GACf,IAAMb,EAASa,EAAOC,OAAO,SAACC,EAAKC,GAGjC,OADAD,EADYC,EAAQC,KAAKC,KAAK,MACnB,CAAEC,QAASH,EAAQG,QAASC,KAAMJ,EAAQK,MAC9CN,CACT,EAAG,CAAA,GAEH,OAAOO,EAAYA,aAACtB,EAAQI,EAC9B,GACAG,EAAOgB,IAAI,WACT,OAAAhB,EAAOiB,KACL,WACE,OAAApB,EAAQqB,2BACRC,yBAAuB,CAAA,EAAItB,EAAQ,EACtC,GAEHG,EAAOoB,MAAM,CACXC,UAAW,SAAC5B,GAAY,MAAA,CAAEA,OAAAA,EAAQE,OAAQ,CAAA,EAAI,EAC9C2B,UAAW,SAACC,GAAM,MAAM,CAAE9B,OAAQ,CAAA,EAAIE,OAAQ4B,EAAQ,IAExDvB,EAAOwB,WAEX,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './effect-ts';
2
+ export * from './types';
@@ -0,0 +1,4 @@
1
+ import { Schema } from '@effect/schema';
2
+ import { ParseOptions } from '@effect/schema/AST';
3
+ import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
4
+ export type Resolver = <A extends FieldValues, I, TContext>(schema: Schema.Schema<A, I>, config?: ParseOptions) => (values: FieldValues, _context: TContext | undefined, options: ResolverOptions<A>) => Promise<ResolverResult<A>>;
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@hookform/resolvers/effect-ts",
3
+ "amdName": "hookformResolversEffectTs",
4
+ "version": "1.0.0",
5
+ "private": true,
6
+ "description": "React Hook Form validation resolver: effect-ts",
7
+ "main": "dist/effect-ts.js",
8
+ "module": "dist/effect-ts.module.js",
9
+ "umd:main": "dist/effect-ts.umd.js",
10
+ "source": "src/index.ts",
11
+ "types": "dist/index.d.ts",
12
+ "license": "MIT",
13
+ "peerDependencies": {
14
+ "@hookform/resolvers": "^2.0.0",
15
+ "@effect/schema": "^0.66.14",
16
+ "effect": "^3.1.2",
17
+ "react-hook-form": "^7.0.0"
18
+ }
19
+ }
@@ -0,0 +1,88 @@
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 { effectTsResolver } from '..';
6
+ import { Schema } from '@effect/schema';
7
+
8
+ const USERNAME_REQUIRED_MESSAGE = 'username field is required';
9
+ const PASSWORD_REQUIRED_MESSAGE = 'password field is required';
10
+
11
+ const schema = Schema.Struct({
12
+ username: Schema.String.pipe(
13
+ Schema.nonEmpty({ message: () => USERNAME_REQUIRED_MESSAGE }),
14
+ ),
15
+ password: Schema.String.pipe(
16
+ Schema.nonEmpty({ message: () => PASSWORD_REQUIRED_MESSAGE }),
17
+ ),
18
+ });
19
+
20
+ interface FormData {
21
+ username: string;
22
+ password: string;
23
+ }
24
+
25
+ interface Props {
26
+ onSubmit: (data: FormData) => void;
27
+ }
28
+
29
+ function TestComponent({ onSubmit }: Props) {
30
+ const { register, handleSubmit } = useForm<FormData>({
31
+ resolver: effectTsResolver(schema),
32
+ shouldUseNativeValidation: true,
33
+ });
34
+
35
+ return (
36
+ <form onSubmit={handleSubmit(onSubmit)}>
37
+ <input {...register('username')} placeholder="username" />
38
+
39
+ <input {...register('password')} placeholder="password" />
40
+
41
+ <button type="submit">submit</button>
42
+ </form>
43
+ );
44
+ }
45
+
46
+ test("form's native validation with effect-ts", async () => {
47
+ const handleSubmit = vi.fn();
48
+ render(<TestComponent onSubmit={handleSubmit} />);
49
+
50
+ // username
51
+ let usernameField = screen.getByPlaceholderText(
52
+ /username/i,
53
+ ) as HTMLInputElement;
54
+ expect(usernameField.validity.valid).toBe(true);
55
+ expect(usernameField.validationMessage).toBe('');
56
+
57
+ // password
58
+ let passwordField = screen.getByPlaceholderText(
59
+ /password/i,
60
+ ) as HTMLInputElement;
61
+ expect(passwordField.validity.valid).toBe(true);
62
+ expect(passwordField.validationMessage).toBe('');
63
+
64
+ await user.click(screen.getByText(/submit/i));
65
+
66
+ // username
67
+ usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
68
+ expect(usernameField.validity.valid).toBe(false);
69
+ expect(usernameField.validationMessage).toBe(USERNAME_REQUIRED_MESSAGE);
70
+
71
+ // password
72
+ passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
73
+ expect(passwordField.validity.valid).toBe(false);
74
+ expect(passwordField.validationMessage).toBe(PASSWORD_REQUIRED_MESSAGE);
75
+
76
+ await user.type(screen.getByPlaceholderText(/username/i), 'joe');
77
+ await user.type(screen.getByPlaceholderText(/password/i), 'password');
78
+
79
+ // username
80
+ usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
81
+ expect(usernameField.validity.valid).toBe(true);
82
+ expect(usernameField.validationMessage).toBe('');
83
+
84
+ // password
85
+ passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
86
+ expect(passwordField.validity.valid).toBe(true);
87
+ expect(passwordField.validationMessage).toBe('');
88
+ });
@@ -0,0 +1,59 @@
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 { effectTsResolver } from '..';
6
+ import { Schema } from '@effect/schema';
7
+
8
+ const USERNAME_REQUIRED_MESSAGE = 'username field is required';
9
+ const PASSWORD_REQUIRED_MESSAGE = 'password field is required';
10
+
11
+ const schema = Schema.Struct({
12
+ username: Schema.String.pipe(
13
+ Schema.nonEmpty({ message: () => USERNAME_REQUIRED_MESSAGE }),
14
+ ),
15
+ password: Schema.String.pipe(
16
+ Schema.nonEmpty({ message: () => PASSWORD_REQUIRED_MESSAGE }),
17
+ ),
18
+ });
19
+
20
+ type FormData = Schema.Schema.Type<typeof schema>;
21
+
22
+ interface Props {
23
+ onSubmit: (data: FormData) => void;
24
+ }
25
+
26
+ function TestComponent({ onSubmit }: Props) {
27
+ const {
28
+ register,
29
+ handleSubmit,
30
+ formState: { errors },
31
+ } = useForm({
32
+ resolver: effectTsResolver(schema),
33
+ });
34
+
35
+ return (
36
+ <form onSubmit={handleSubmit(onSubmit)}>
37
+ <input {...register('username')} />
38
+ {errors.username && <span role="alert">{errors.username.message}</span>}
39
+
40
+ <input {...register('password')} />
41
+ {errors.password && <span role="alert">{errors.password.message}</span>}
42
+
43
+ <button type="submit">submit</button>
44
+ </form>
45
+ );
46
+ }
47
+
48
+ test("form's validation with Zod and TypeScript's integration", async () => {
49
+ const handleSubmit = vi.fn();
50
+ render(<TestComponent onSubmit={handleSubmit} />);
51
+
52
+ expect(screen.queryAllByRole('alert')).toHaveLength(0);
53
+
54
+ await user.click(screen.getByText(/submit/i));
55
+
56
+ expect(screen.getByText(/username field is required/i)).toBeInTheDocument();
57
+ expect(screen.getByText(/password field is required/i)).toBeInTheDocument();
58
+ expect(handleSubmit).not.toHaveBeenCalled();
59
+ });
@@ -0,0 +1,124 @@
1
+ import { Schema } from '@effect/schema';
2
+ import { Field, InternalFieldName } from 'react-hook-form';
3
+
4
+ export const schema = Schema.Struct({
5
+ username: Schema.String.pipe(
6
+ Schema.nonEmpty({ message: () => 'A username is required' }),
7
+ ),
8
+ password: Schema.String.pipe(
9
+ Schema.pattern(new RegExp('.*[A-Z].*'), {
10
+ message: () => 'At least 1 uppercase letter.',
11
+ }),
12
+ Schema.pattern(new RegExp('.*[a-z].*'), {
13
+ message: () => 'At least 1 lowercase letter.',
14
+ }),
15
+ Schema.pattern(new RegExp('.*\\d.*'), {
16
+ message: () => 'At least 1 number.',
17
+ }),
18
+ Schema.pattern(
19
+ new RegExp('.*[`~<>?,./!@#$%^&*()\\-_+="\'|{}\\[\\];:\\\\].*'),
20
+ {
21
+ message: () => 'At least 1 special character.',
22
+ },
23
+ ),
24
+ Schema.minLength(8, { message: () => 'Must be at least 8 characters.' }),
25
+ ),
26
+ accessToken: Schema.Union(Schema.String, Schema.Number),
27
+ birthYear: Schema.Number.pipe(
28
+ Schema.greaterThan(1900, {
29
+ message: () => 'Must be greater than the year 1900',
30
+ }),
31
+ Schema.filter((value) => value < new Date().getFullYear(), {
32
+ message: () => 'Must be before the current year.',
33
+ }),
34
+ ),
35
+ email: Schema.String.pipe(
36
+ Schema.pattern(
37
+ new RegExp(
38
+ /^(?!\.)(?!.*\.\.)([A-Z0-9_+-.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i,
39
+ ),
40
+ {
41
+ message: () => 'A valid email address is required.',
42
+ },
43
+ ),
44
+ ),
45
+ tags: Schema.Array(
46
+ Schema.Struct({
47
+ name: Schema.String,
48
+ }),
49
+ ),
50
+ luckyNumbers: Schema.Array(Schema.Number),
51
+ enabled: Schema.Boolean,
52
+ animal: Schema.Union(Schema.String, Schema.Literal('bird', 'snake')),
53
+ vehicles: Schema.Array(
54
+ Schema.Union(
55
+ Schema.Struct({
56
+ type: Schema.Literal('car'),
57
+ brand: Schema.String,
58
+ horsepower: Schema.Number,
59
+ }),
60
+ Schema.Struct({
61
+ type: Schema.Literal('bike'),
62
+ speed: Schema.Number,
63
+ }),
64
+ ),
65
+ ),
66
+ });
67
+
68
+ export const validData: Schema.Schema.Type<typeof schema> = {
69
+ accessToken: 'abcd1234',
70
+ animal: 'dog',
71
+ birthYear: 2000,
72
+ email: 'johnDoe@here.there',
73
+ enabled: true,
74
+ luckyNumbers: [1, 2, 3, 4, 5],
75
+ password: 'Super#Secret123',
76
+ tags: [{ name: 'move' }, { name: 'over' }, { name: 'zod' }, { name: ';)' }],
77
+ username: 'johnDoe',
78
+ vehicles: [
79
+ { type: 'bike', speed: 5 },
80
+ { type: 'car', brand: 'BMW', horsepower: 150 },
81
+ ],
82
+ };
83
+
84
+ export const invalidData = {
85
+ username: 'test',
86
+ password: 'Password123',
87
+ repeatPassword: 'Password123',
88
+ birthYear: 2000,
89
+ accessToken: '1015d809-e99d-41ec-b161-981a3c243df8',
90
+ email: 'john@doe.com',
91
+ tags: [{ name: 'test' }],
92
+ enabled: true,
93
+ animal: ['dog'],
94
+ luckyNumbers: [1, 2, '3'],
95
+ like: [
96
+ {
97
+ id: '1',
98
+ name: 'name',
99
+ },
100
+ ],
101
+ vehicles: [
102
+ { type: 'car', brand: 'BMW', horsepower: 150 },
103
+ { type: 'car', brand: 'Mercedes' },
104
+ ],
105
+ };
106
+
107
+ export const fields: Record<InternalFieldName, Field['_f']> = {
108
+ username: {
109
+ ref: { name: 'username' },
110
+ name: 'username',
111
+ },
112
+ password: {
113
+ ref: { name: 'password' },
114
+ name: 'password',
115
+ },
116
+ email: {
117
+ ref: { name: 'email' },
118
+ name: 'email',
119
+ },
120
+ birthday: {
121
+ ref: { name: 'birthday' },
122
+ name: 'birthday',
123
+ },
124
+ };
@@ -0,0 +1,40 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`effectTsResolver > should return a single error from effectTsResolver when validation fails 1`] = `
4
+ {
5
+ "errors": {
6
+ "animal": {
7
+ "message": "Expected \\"snake\\", actual [\\"dog\\"]",
8
+ "ref": undefined,
9
+ "type": "Type",
10
+ },
11
+ "luckyNumbers": [
12
+ ,
13
+ ,
14
+ {
15
+ "message": "Expected a number, actual \\"3\\"",
16
+ "ref": undefined,
17
+ "type": "Type",
18
+ },
19
+ ],
20
+ "password": {
21
+ "message": "At least 1 special character.",
22
+ "ref": {
23
+ "name": "password",
24
+ },
25
+ "type": "Refinement",
26
+ },
27
+ "vehicles": [
28
+ ,
29
+ {
30
+ "horsepower": {
31
+ "message": "is missing",
32
+ "ref": undefined,
33
+ "type": "Missing",
34
+ },
35
+ },
36
+ ],
37
+ },
38
+ "values": {},
39
+ }
40
+ `;
@@ -0,0 +1,24 @@
1
+ import { effectTsResolver } from '..';
2
+ import { schema, validData, fields, invalidData } from './__fixtures__/data';
3
+
4
+ const shouldUseNativeValidation = false;
5
+
6
+ describe('effectTsResolver', () => {
7
+ it('should return values from effectTsResolver when validation pass', async () => {
8
+ const result = await effectTsResolver(schema)(validData, undefined, {
9
+ fields,
10
+ shouldUseNativeValidation,
11
+ });
12
+
13
+ expect(result).toEqual({ errors: {}, values: validData });
14
+ });
15
+
16
+ it('should return a single error from effectTsResolver when validation fails', async () => {
17
+ const result = await effectTsResolver(schema)(invalidData, undefined, {
18
+ fields,
19
+ shouldUseNativeValidation,
20
+ });
21
+
22
+ expect(result).toMatchSnapshot();
23
+ });
24
+ });
@@ -0,0 +1,38 @@
1
+ import { decodeUnknown } from '@effect/schema/ParseResult';
2
+ import { formatIssue } from '@effect/schema/ArrayFormatter';
3
+ import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';
4
+ import * as Effect from 'effect/Effect';
5
+ import type { FieldErrors } from 'react-hook-form';
6
+ import type { Resolver } from './types';
7
+
8
+ export const effectTsResolver: Resolver =
9
+ (schema, config = { errors: 'all', onExcessProperty: 'ignore' }) =>
10
+ (values, _, options) => {
11
+ return decodeUnknown(
12
+ schema,
13
+ config,
14
+ )(values).pipe(
15
+ Effect.catchAll((parseIssue) => Effect.flip(formatIssue(parseIssue))),
16
+ Effect.mapError((issues) => {
17
+ const errors = issues.reduce((acc, current) => {
18
+ const key = current.path.join('.');
19
+ acc[key] = { message: current.message, type: current._tag };
20
+ return acc;
21
+ }, {} as FieldErrors);
22
+
23
+ return toNestErrors(errors, options);
24
+ }),
25
+ Effect.tap(() =>
26
+ Effect.sync(
27
+ () =>
28
+ options.shouldUseNativeValidation &&
29
+ validateFieldsNatively({}, options),
30
+ ),
31
+ ),
32
+ Effect.match({
33
+ onFailure: (errors) => ({ errors, values: {} }),
34
+ onSuccess: (result) => ({ errors: {}, values: result }),
35
+ }),
36
+ Effect.runPromise,
37
+ );
38
+ };
@@ -0,0 +1,2 @@
1
+ export * from './effect-ts';
2
+ export * from './types';
@@ -0,0 +1,12 @@
1
+ import { Schema } from '@effect/schema';
2
+ import { ParseOptions } from '@effect/schema/AST';
3
+ import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
4
+
5
+ export type Resolver = <A extends FieldValues, I, TContext>(
6
+ schema: Schema.Schema<A, I>,
7
+ config?: ParseOptions,
8
+ ) => (
9
+ values: FieldValues,
10
+ _context: TContext | undefined,
11
+ options: ResolverOptions<A>,
12
+ ) => Promise<ResolverResult<A>>;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@hookform/resolvers",
3
3
  "amdName": "hookformResolvers",
4
- "version": "3.3.4",
5
- "description": "React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype and Typanion",
4
+ "version": "3.4.1",
5
+ "description": "React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype, Typanion and Effect-TS",
6
6
  "main": "dist/resolvers.js",
7
7
  "module": "dist/resolvers.module.js",
8
8
  "umd:main": "dist/resolvers.umd.js",
@@ -99,6 +99,12 @@
99
99
  "import": "./valibot/dist/valibot.mjs",
100
100
  "require": "./valibot/dist/valibot.js"
101
101
  },
102
+ "./effect-ts": {
103
+ "types": "./effect-ts/dist/index.d.ts",
104
+ "umd": "./effect-ts/dist/effect-ts.umd.js",
105
+ "import": "./effect-ts/dist/effect-ts.mjs",
106
+ "require": "./effect-ts/dist/effect-ts.js"
107
+ },
102
108
  "./package.json": "./package.json",
103
109
  "./*": "./*"
104
110
  },
@@ -145,7 +151,10 @@
145
151
  "arktype/dist",
146
152
  "valibot/package.json",
147
153
  "valibot/src",
148
- "valibot/dist"
154
+ "valibot/dist",
155
+ "effect-ts/package.json",
156
+ "effect-ts/src",
157
+ "effect-ts/dist"
149
158
  ],
150
159
  "publishConfig": {
151
160
  "access": "public"
@@ -168,6 +177,7 @@
168
177
  "build:typebox": "microbundle --cwd typebox --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm,@sinclair/typebox/value=value",
169
178
  "build:arktype": "microbundle --cwd arktype --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
170
179
  "build:valibot": "microbundle --cwd valibot --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
180
+ "build:effect-ts": "microbundle --cwd effect-ts --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm,@effect/schema=EffectSchema,@effect/schema/AST=EffectSchemaAST,@effect/schema/ArrayFormatter=EffectSchemaArrayFormatter",
171
181
  "postbuild": "node ./config/node-13-exports.js",
172
182
  "lint": "eslint . --ext .ts,.js --ignore-path .gitignore",
173
183
  "lint:types": "tsc",
@@ -191,6 +201,7 @@
191
201
  "vest",
192
202
  "class-validator",
193
203
  "io-ts",
204
+ "effect-ts",
194
205
  "nope",
195
206
  "computed-types",
196
207
  "typanion",
@@ -209,6 +220,7 @@
209
220
  },
210
221
  "homepage": "https://react-hook-form.com",
211
222
  "devDependencies": {
223
+ "@effect/schema": "^0.66.14",
212
224
  "@sinclair/typebox": "^0.31.1",
213
225
  "@testing-library/dom": "^9.3.1",
214
226
  "@testing-library/jest-dom": "^6.0.1",
@@ -227,6 +239,7 @@
227
239
  "class-validator": "^0.14.0",
228
240
  "computed-types": "^1.11.2",
229
241
  "cross-env": "^7.0.3",
242
+ "effect": "^3.1.2",
230
243
  "eslint": "^8.47.0",
231
244
  "eslint-config-prettier": "^9.0.0",
232
245
  "fp-ts": "^2.16.1",
@@ -267,5 +280,9 @@
267
280
  "*.{md,json,yml}": [
268
281
  "prettier --write"
269
282
  ]
283
+ },
284
+ "dependencies": {
285
+ "@types/lodash.set": "^4.3.9",
286
+ "lodash.set": "^4.3.2"
270
287
  }
271
288
  }