@hookform/resolvers 3.8.0 → 3.9.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.
Files changed (27) hide show
  1. package/README.md +43 -0
  2. package/dist/resolvers.js.map +1 -1
  3. package/dist/resolvers.mjs +2 -2
  4. package/dist/resolvers.mjs.map +1 -1
  5. package/dist/resolvers.module.js.map +1 -1
  6. package/dist/resolvers.umd.js.map +1 -1
  7. package/fluentvalidation-ts/dist/fluentvalidation-ts.d.ts +4 -0
  8. package/fluentvalidation-ts/dist/fluentvalidation-ts.js +2 -0
  9. package/fluentvalidation-ts/dist/fluentvalidation-ts.js.map +1 -0
  10. package/fluentvalidation-ts/dist/fluentvalidation-ts.mjs +2 -0
  11. package/fluentvalidation-ts/dist/fluentvalidation-ts.modern.mjs +2 -0
  12. package/fluentvalidation-ts/dist/fluentvalidation-ts.modern.mjs.map +1 -0
  13. package/fluentvalidation-ts/dist/fluentvalidation-ts.module.js +2 -0
  14. package/fluentvalidation-ts/dist/fluentvalidation-ts.module.js.map +1 -0
  15. package/fluentvalidation-ts/dist/fluentvalidation-ts.umd.js +2 -0
  16. package/fluentvalidation-ts/dist/fluentvalidation-ts.umd.js.map +1 -0
  17. package/fluentvalidation-ts/dist/index.d.ts +1 -0
  18. package/fluentvalidation-ts/package.json +18 -0
  19. package/fluentvalidation-ts/src/__tests__/Form-native-validation.tsx +88 -0
  20. package/fluentvalidation-ts/src/__tests__/Form.tsx +63 -0
  21. package/fluentvalidation-ts/src/__tests__/__fixtures__/data.ts +121 -0
  22. package/fluentvalidation-ts/src/__tests__/__snapshots__/fluentvalidation-ts.ts.snap +129 -0
  23. package/fluentvalidation-ts/src/__tests__/fluentvalidation-ts.ts +113 -0
  24. package/fluentvalidation-ts/src/fluentvalidation-ts.ts +102 -0
  25. package/fluentvalidation-ts/src/index.ts +1 -0
  26. package/package.json +21 -9
  27. package/valibot/package.json +1 -1
package/README.md CHANGED
@@ -50,6 +50,7 @@
50
50
  - [TypeSchema](#typeschema)
51
51
  - [effect-ts](#effect-ts)
52
52
  - [VineJS](#vinejs)
53
+ - [fluentvalidation-ts](#fluentvalidation-ts)
53
54
  - [Backers](#backers)
54
55
  - [Sponsors](#sponsors)
55
56
  - [Contributors](#contributors)
@@ -734,6 +735,48 @@ const App = () => {
734
735
  };
735
736
  ```
736
737
 
738
+
739
+ ### [fluentvalidation-ts](https://github.com/AlexJPotter/fluentvalidation-ts)
740
+
741
+ A TypeScript-first library for building strongly-typed validation rules
742
+
743
+ [![npm](https://img.shields.io/bundlephobia/minzip/@vinejs/vine?style=for-the-badge)](https://bundlephobia.com/result?p=@vinejs/vine)
744
+
745
+ ```typescript jsx
746
+ import { useForm } from 'react-hook-form';
747
+ import { fluentValidationResolver } from '@hookform/resolvers/fluentvalidation-ts';
748
+ import { Validator } from 'fluentvalidation-ts';
749
+
750
+ class FormDataValidator extends Validator<FormData> {
751
+ constructor() {
752
+ super();
753
+
754
+ this.ruleFor('username')
755
+ .notEmpty()
756
+ .withMessage('username is a required field');
757
+ this.ruleFor('password')
758
+ .notEmpty()
759
+ .withMessage('password is a required field');
760
+ }
761
+ }
762
+
763
+ const App = () => {
764
+ const { register, handleSubmit } = useForm({
765
+ resolver: fluentValidationResolver(new FormDataValidator()),
766
+ });
767
+
768
+ return (
769
+ <form onSubmit={handleSubmit((d) => console.log(d))}>
770
+ <input {...register('username')} />
771
+ {errors.username && <span role="alert">{errors.username.message}</span>}
772
+ <input {...register('password')} />
773
+ {errors.password && <span role="alert">{errors.password.message}</span>}
774
+ <button type="submit">submit</button>
775
+ </form>
776
+ );
777
+ };
778
+ ```
779
+
737
780
  ## Backers
738
781
 
739
782
  Thanks go to all our backers! [[Become a backer](https://opencollective.com/react-hook-form#backer)].
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n set,\n get,\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,gBACN,CACF,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,EAG/C,EATA,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,EACzB,MACEC,EAAGA,IAACN,EAAaC,EAAMnB,EAE3B,CAEA,OAAOkB,CACT"}
1
+ {"version":3,"file":"resolvers.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n get,\n set,\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,gBACN,CACF,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,EAG/C,EATA,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,EACzB,MACEC,EAAGA,IAACN,EAAaC,EAAMnB,EAE3B,CAEA,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};
2
- //# sourceMappingURL=resolvers.module.js.map
1
+ import{get as t,set as e}from"react-hook-form";const s=(e,s,o)=>{if(e&&"reportValidity"in e){const r=t(o,s);e.setCustomValidity(r&&r.message||""),e.reportValidity()}},o=(t,e)=>{for(const o in e.fields){const r=e.fields[o];r&&r.ref&&"reportValidity"in r.ref?s(r.ref,o,t):r.refs&&r.refs.forEach(e=>s(e,o,t))}},r=(s,r)=>{r.shouldUseNativeValidation&&o(s,r);const f={};for(const o in s){const n=t(r.fields,o),a=Object.assign(s[o]||{},{ref:n&&n.ref});if(i(r.names||Object.keys(s),o)){const s=Object.assign({},t(f,o));e(s,"root",a),e(f,o,s)}else e(f,o,a)}return f},i=(t,e)=>t.some(t=>t.startsWith(e+"."));export{r as toNestErrors,o as validateFieldsNatively};
2
+ //# sourceMappingURL=resolvers.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.mjs","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n set,\n get,\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,gBACN,GAIWC,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,GAGxC,GCzBWW,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,EACzB,MACEC,EAAIR,EAAaC,EAAMb,EAE3B,CAEA,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 FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n get,\n set,\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,gBACN,GAIWC,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,GAGxC,GCzBWW,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,EACzB,MACEC,EAAIR,EAAaC,EAAMb,EAE3B,CAEA,OAAOY,GAGHI,EAAqBA,CACzBC,EACAI,IACGJ,EAAMK,KAAMC,GAAMA,EAAEC,WAAWH,EAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.module.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n set,\n get,\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,gBACN,CACF,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,EAG/C,EATA,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,EACzB,MACEC,EAAIR,EAAaC,EAAMd,EAE3B,CAEA,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 FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n get,\n set,\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,gBACN,CACF,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,EAG/C,EATA,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,EACzB,MACEC,EAAIR,EAAaC,EAAMd,EAE3B,CAEA,OAAOa,CACT,EAEMI,EAAqB,SACzBC,EACAI,GAAuB,OACpBJ,EAAMK,KAAK,SAACC,GAAM,OAAAA,EAAEC,WAAWH,EAAO,IAAI,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.umd.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n set,\n get,\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,gBACN,CACF,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,EAG/C,EATA,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,EACzB,MACEC,EAAGA,IAACN,EAAaC,EAAMnB,EAE3B,CAEA,OAAOkB,CACT"}
1
+ {"version":3,"file":"resolvers.umd.js","sources":["../src/validateFieldsNatively.ts","../src/toNestErrors.ts"],"sourcesContent":["import {\n FieldError,\n FieldErrors,\n FieldValues,\n Ref,\n ResolverOptions,\n get,\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 Field,\n FieldErrors,\n FieldValues,\n InternalFieldName,\n ResolverOptions,\n get,\n set,\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,gBACN,CACF,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,EAG/C,EATA,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,EACzB,MACEC,EAAGA,IAACN,EAAaC,EAAMnB,EAE3B,CAEA,OAAOkB,CACT"}
@@ -0,0 +1,4 @@
1
+ import { AsyncValidator, Validator } from 'fluentvalidation-ts';
2
+ import { FieldValues, Resolver } from 'react-hook-form';
3
+ export declare function fluentValidationResolver<TFieldValues extends FieldValues>(validator: Validator<TFieldValues>): Resolver<TFieldValues>;
4
+ export declare function fluentAsyncValidationResolver<TFieldValues extends FieldValues, TValidator extends AsyncValidator<TFieldValues>>(validator: TValidator): Resolver<TFieldValues>;
@@ -0,0 +1,2 @@
1
+ var r=require("@hookform/resolvers");function e(r,t,o){void 0===o&&(o=[]);var n=function(){var n=[].concat(o,[a]),i=r[a];Array.isArray(i)?i.forEach(function(r,o){e(r,t,[].concat(n,[o]))}):"object"==typeof i&&null!==i?e(i,t,n):"string"==typeof i&&(t[n.join(".")]={type:"validation",message:i})};for(var a in r)n()}var t=function(r,t){var o={};return e(r,o),o};exports.fluentAsyncValidationResolver=function(e){return function(o,n,a){try{return Promise.resolve(e.validateAsync(o)).then(function(e){var n=0===Object.keys(e).length;return a.shouldUseNativeValidation&&r.validateFieldsNatively({},a),n?{values:o,errors:{}}:{values:{},errors:r.toNestErrors(t(e),a)}})}catch(r){return Promise.reject(r)}}},exports.fluentValidationResolver=function(e){return function(o,n,a){try{var i=e.validate(o),s=0===Object.keys(i).length;return a.shouldUseNativeValidation&&r.validateFieldsNatively({},a),Promise.resolve(s?{values:o,errors:{}}:{values:{},errors:r.toNestErrors(t(i),a)})}catch(r){return Promise.reject(r)}}};
2
+ //# sourceMappingURL=fluentvalidation-ts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fluentvalidation-ts.js","sources":["../src/fluentvalidation-ts.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport {\n AsyncValidator,\n ValidationErrors,\n Validator,\n} from 'fluentvalidation-ts';\nimport { FieldError, FieldValues, Resolver } from 'react-hook-form';\n\nfunction traverseObject<T>(\n object: ValidationErrors<T>,\n errors: Record<string, FieldError>,\n parentIndices: (string | number)[] = [],\n) {\n for (const key in object) {\n const currentIndex = [...parentIndices, key];\n const currentValue = object[key];\n\n if (Array.isArray(currentValue)) {\n currentValue.forEach((item: any, index: number) => {\n traverseObject(item, errors, [...currentIndex, index]);\n });\n } else if (typeof currentValue === 'object' && currentValue !== null) {\n traverseObject(currentValue, errors, currentIndex);\n } else if (typeof currentValue === 'string') {\n errors[currentIndex.join('.')] = {\n type: 'validation',\n message: currentValue,\n };\n }\n }\n}\n\nconst parseErrorSchema = <T>(\n validationErrors: ValidationErrors<T>,\n validateAllFieldCriteria: boolean,\n) => {\n if (validateAllFieldCriteria) {\n // TODO: check this but i think its always one validation error\n }\n\n const errors: Record<string, FieldError> = {};\n traverseObject(validationErrors, errors);\n\n return errors;\n};\n\nexport function fluentValidationResolver<TFieldValues extends FieldValues>(\n validator: Validator<TFieldValues>,\n): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = validator.validate(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n\nexport function fluentAsyncValidationResolver<\n TFieldValues extends FieldValues,\n TValidator extends AsyncValidator<TFieldValues>,\n>(validator: TValidator): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = await validator.validateAsync(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n"],"names":["traverseObject","object","errors","parentIndices","_loop","currentIndex","concat","key","currentValue","Array","isArray","forEach","item","index","join","type","message","parseErrorSchema","validationErrors","validateAllFieldCriteria","validator","values","_context","options","Promise","resolve","validateAsync","then","validationResult","isValid","Object","keys","length","shouldUseNativeValidation","validateFieldsNatively","toNestErrors","e","reject","validate"],"mappings":"qCAQA,SAASA,EACPC,EACAC,EACAC,YAAAA,IAAAA,EAAqC,IAAE,IAAAC,EAAAA,WAGrC,IAAMC,EAAY,GAAAC,OAAOH,EAAa,CAAEI,IAClCC,EAAeP,EAAOM,GAExBE,MAAMC,QAAQF,GAChBA,EAAaG,QAAQ,SAACC,EAAWC,GAC/Bb,EAAeY,EAAMV,EAAM,GAAAI,OAAMD,EAAcQ,CAAAA,IACjD,GACiC,iBAAjBL,GAA8C,OAAjBA,EAC7CR,EAAeQ,EAAcN,EAAQG,GACJ,iBAAjBG,IAChBN,EAAOG,EAAaS,KAAK,MAAQ,CAC/BC,KAAM,aACNC,QAASR,GAGf,EAhBA,IAAK,IAAMD,KAAON,EAAMG,GAiB1B,CAEA,IAAMa,EAAmB,SACvBC,EACAC,GAMA,IAAMjB,EAAqC,GAG3C,OAFAF,EAAekB,EAAkBhB,GAE1BA,CACT,wCA8BgB,SAGdkB,GACA,OAAcC,SAAAA,EAAQC,EAAUC,GAAW,IAAA,OAAAC,QAAAC,QACVL,EAAUM,cAAcL,IAAOM,KAAA,SAAxDC,GACN,IAAMC,EAAmD,IAAzCC,OAAOC,KAAKH,GAAkBI,OAI9C,OAFAT,EAAQU,2BAA6BC,yBAAuB,CAAA,EAAIX,GAEzDM,EACH,CACER,OAAQA,EACRnB,OAAQ,CACT,GACD,CACEmB,OAAQ,CAAA,EACRnB,OAAQiC,EAAYA,aAClBlB,EACEW,GAIFL,GAEF,EACR,CAAC,MAAAa,GAAA,OAAAZ,QAAAa,OAAAD,EACH,CAAA,CAAA,mCAvDgB,SACdhB,GAEA,OAAcC,SAAAA,EAAQC,EAAUC,GAAW,IACzC,IAAMK,EAAmBR,EAAUkB,SAASjB,GACtCQ,EAAmD,IAAzCC,OAAOC,KAAKH,GAAkBI,OAI9C,OAFAT,EAAQU,2BAA6BC,EAAsBA,uBAAC,CAAE,EAAEX,GAEhEC,QAAAC,QAAOI,EACH,CACER,OAAQA,EACRnB,OAAQ,CAAA,GAEV,CACEmB,OAAQ,CAAA,EACRnB,OAAQiC,EAAAA,aACNlB,EACEW,GAIFL,IAGV,CAAC,MAAAa,GAAA,OAAAZ,QAAAa,OAAAD,EACH,CAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ import{validateFieldsNatively as r,toNestErrors as e}from"@hookform/resolvers";function t(r,e,o){void 0===o&&(o=[]);var n=function(){var n=[].concat(o,[a]),i=r[a];Array.isArray(i)?i.forEach(function(r,o){t(r,e,[].concat(n,[o]))}):"object"==typeof i&&null!==i?t(i,e,n):"string"==typeof i&&(e[n.join(".")]={type:"validation",message:i})};for(var a in r)n()}var o=function(r,e){var o={};return t(r,o),o};function n(t){return function(n,a,i){try{var s=t.validate(n),c=0===Object.keys(s).length;return i.shouldUseNativeValidation&&r({},i),Promise.resolve(c?{values:n,errors:{}}:{values:{},errors:e(o(s),i)})}catch(r){return Promise.reject(r)}}}function a(t){return function(n,a,i){try{return Promise.resolve(t.validateAsync(n)).then(function(t){var a=0===Object.keys(t).length;return i.shouldUseNativeValidation&&r({},i),a?{values:n,errors:{}}:{values:{},errors:e(o(t),i)}})}catch(r){return Promise.reject(r)}}}export{a as fluentAsyncValidationResolver,n as fluentValidationResolver};
2
+ //# sourceMappingURL=fluentvalidation-ts.module.js.map
@@ -0,0 +1,2 @@
1
+ import{validateFieldsNatively as r,toNestErrors as e}from"@hookform/resolvers";function t(r,e,o=[]){for(const n in r){const s=[...o,n],a=r[n];Array.isArray(a)?a.forEach((r,o)=>{t(r,e,[...s,o])}):"object"==typeof a&&null!==a?t(a,e,s):"string"==typeof a&&(e[s.join(".")]={type:"validation",message:a})}}const o=(r,e)=>{const o={};return t(r,o),o};function n(t){return async(n,s,a)=>{const i=t.validate(n),c=0===Object.keys(i).length;return a.shouldUseNativeValidation&&r({},a),c?{values:n,errors:{}}:{values:{},errors:e(o(i),a)}}}function s(t){return async(n,s,a)=>{const i=await t.validateAsync(n),c=0===Object.keys(i).length;return a.shouldUseNativeValidation&&r({},a),c?{values:n,errors:{}}:{values:{},errors:e(o(i),a)}}}export{s as fluentAsyncValidationResolver,n as fluentValidationResolver};
2
+ //# sourceMappingURL=fluentvalidation-ts.modern.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fluentvalidation-ts.modern.mjs","sources":["../src/fluentvalidation-ts.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport {\n AsyncValidator,\n ValidationErrors,\n Validator,\n} from 'fluentvalidation-ts';\nimport { FieldError, FieldValues, Resolver } from 'react-hook-form';\n\nfunction traverseObject<T>(\n object: ValidationErrors<T>,\n errors: Record<string, FieldError>,\n parentIndices: (string | number)[] = [],\n) {\n for (const key in object) {\n const currentIndex = [...parentIndices, key];\n const currentValue = object[key];\n\n if (Array.isArray(currentValue)) {\n currentValue.forEach((item: any, index: number) => {\n traverseObject(item, errors, [...currentIndex, index]);\n });\n } else if (typeof currentValue === 'object' && currentValue !== null) {\n traverseObject(currentValue, errors, currentIndex);\n } else if (typeof currentValue === 'string') {\n errors[currentIndex.join('.')] = {\n type: 'validation',\n message: currentValue,\n };\n }\n }\n}\n\nconst parseErrorSchema = <T>(\n validationErrors: ValidationErrors<T>,\n validateAllFieldCriteria: boolean,\n) => {\n if (validateAllFieldCriteria) {\n // TODO: check this but i think its always one validation error\n }\n\n const errors: Record<string, FieldError> = {};\n traverseObject(validationErrors, errors);\n\n return errors;\n};\n\nexport function fluentValidationResolver<TFieldValues extends FieldValues>(\n validator: Validator<TFieldValues>,\n): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = validator.validate(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n\nexport function fluentAsyncValidationResolver<\n TFieldValues extends FieldValues,\n TValidator extends AsyncValidator<TFieldValues>,\n>(validator: TValidator): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = await validator.validateAsync(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n"],"names":["traverseObject","object","errors","parentIndices","key","currentIndex","currentValue","Array","isArray","forEach","item","index","join","type","message","parseErrorSchema","validationErrors","validateAllFieldCriteria","fluentValidationResolver","validator","async","values","_context","options","validationResult","validate","isValid","Object","keys","length","shouldUseNativeValidation","validateFieldsNatively","toNestErrors","fluentAsyncValidationResolver","validateAsync"],"mappings":"+EAQA,SAASA,EACPC,EACAC,EACAC,EAAqC,IAErC,IAAK,MAAMC,KAAOH,EAAQ,CACxB,MAAMI,EAAe,IAAIF,EAAeC,GAClCE,EAAeL,EAAOG,GAExBG,MAAMC,QAAQF,GAChBA,EAAaG,QAAQ,CAACC,EAAWC,KAC/BX,EAAeU,EAAMR,EAAQ,IAAIG,EAAcM,GAAM,GAEtB,iBAAjBL,GAA8C,OAAjBA,EAC7CN,EAAeM,EAAcJ,EAAQG,GACJ,iBAAjBC,IAChBJ,EAAOG,EAAaO,KAAK,MAAQ,CAC/BC,KAAM,aACNC,QAASR,GAGf,CACF,CAEA,MAAMS,EAAmBA,CACvBC,EACAC,KAMA,MAAMf,EAAqC,CAAA,EAG3C,OAFAF,EAAegB,EAAkBd,GAE1BA,YAGOgB,EACdC,GAEA,OAAOC,MAAOC,EAAQC,EAAUC,KAC9B,MAAMC,EAAmBL,EAAUM,SAASJ,GACtCK,EAAmD,IAAzCC,OAAOC,KAAKJ,GAAkBK,OAI9C,OAFAN,EAAQO,2BAA6BC,EAAuB,CAAE,EAAER,GAEzDG,EACH,CACEL,OAAQA,EACRnB,OAAQ,CAAA,GAEV,CACEmB,OAAQ,CAAE,EACVnB,OAAQ8B,EACNjB,EACES,GAIFD,IAIZ,CAEgB,SAAAU,EAGdd,GACA,OAAcE,MAAAA,EAAQC,EAAUC,KAC9B,MAAMC,QAAyBL,EAAUe,cAAcb,GACjDK,EAAmD,IAAzCC,OAAOC,KAAKJ,GAAkBK,OAI9C,OAFAN,EAAQO,2BAA6BC,EAAuB,CAAE,EAAER,GAEzDG,EACH,CACEL,OAAQA,EACRnB,OAAQ,CACT,GACD,CACEmB,OAAQ,CAAA,EACRnB,OAAQ8B,EACNjB,EACES,GAIFD,IAIZ"}
@@ -0,0 +1,2 @@
1
+ import{validateFieldsNatively as r,toNestErrors as e}from"@hookform/resolvers";function t(r,e,o){void 0===o&&(o=[]);var n=function(){var n=[].concat(o,[a]),i=r[a];Array.isArray(i)?i.forEach(function(r,o){t(r,e,[].concat(n,[o]))}):"object"==typeof i&&null!==i?t(i,e,n):"string"==typeof i&&(e[n.join(".")]={type:"validation",message:i})};for(var a in r)n()}var o=function(r,e){var o={};return t(r,o),o};function n(t){return function(n,a,i){try{var s=t.validate(n),c=0===Object.keys(s).length;return i.shouldUseNativeValidation&&r({},i),Promise.resolve(c?{values:n,errors:{}}:{values:{},errors:e(o(s),i)})}catch(r){return Promise.reject(r)}}}function a(t){return function(n,a,i){try{return Promise.resolve(t.validateAsync(n)).then(function(t){var a=0===Object.keys(t).length;return i.shouldUseNativeValidation&&r({},i),a?{values:n,errors:{}}:{values:{},errors:e(o(t),i)}})}catch(r){return Promise.reject(r)}}}export{a as fluentAsyncValidationResolver,n as fluentValidationResolver};
2
+ //# sourceMappingURL=fluentvalidation-ts.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fluentvalidation-ts.module.js","sources":["../src/fluentvalidation-ts.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport {\n AsyncValidator,\n ValidationErrors,\n Validator,\n} from 'fluentvalidation-ts';\nimport { FieldError, FieldValues, Resolver } from 'react-hook-form';\n\nfunction traverseObject<T>(\n object: ValidationErrors<T>,\n errors: Record<string, FieldError>,\n parentIndices: (string | number)[] = [],\n) {\n for (const key in object) {\n const currentIndex = [...parentIndices, key];\n const currentValue = object[key];\n\n if (Array.isArray(currentValue)) {\n currentValue.forEach((item: any, index: number) => {\n traverseObject(item, errors, [...currentIndex, index]);\n });\n } else if (typeof currentValue === 'object' && currentValue !== null) {\n traverseObject(currentValue, errors, currentIndex);\n } else if (typeof currentValue === 'string') {\n errors[currentIndex.join('.')] = {\n type: 'validation',\n message: currentValue,\n };\n }\n }\n}\n\nconst parseErrorSchema = <T>(\n validationErrors: ValidationErrors<T>,\n validateAllFieldCriteria: boolean,\n) => {\n if (validateAllFieldCriteria) {\n // TODO: check this but i think its always one validation error\n }\n\n const errors: Record<string, FieldError> = {};\n traverseObject(validationErrors, errors);\n\n return errors;\n};\n\nexport function fluentValidationResolver<TFieldValues extends FieldValues>(\n validator: Validator<TFieldValues>,\n): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = validator.validate(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n\nexport function fluentAsyncValidationResolver<\n TFieldValues extends FieldValues,\n TValidator extends AsyncValidator<TFieldValues>,\n>(validator: TValidator): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = await validator.validateAsync(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n"],"names":["traverseObject","object","errors","parentIndices","_loop","currentIndex","concat","key","currentValue","Array","isArray","forEach","item","index","join","type","message","parseErrorSchema","validationErrors","validateAllFieldCriteria","fluentValidationResolver","validator","values","_context","options","validationResult","validate","isValid","Object","keys","length","shouldUseNativeValidation","validateFieldsNatively","Promise","resolve","toNestErrors","e","reject","fluentAsyncValidationResolver","validateAsync","then"],"mappings":"+EAQA,SAASA,EACPC,EACAC,EACAC,YAAAA,IAAAA,EAAqC,IAAE,IAAAC,EAAAA,WAGrC,IAAMC,EAAY,GAAAC,OAAOH,EAAa,CAAEI,IAClCC,EAAeP,EAAOM,GAExBE,MAAMC,QAAQF,GAChBA,EAAaG,QAAQ,SAACC,EAAWC,GAC/Bb,EAAeY,EAAMV,EAAM,GAAAI,OAAMD,EAAcQ,CAAAA,IACjD,GACiC,iBAAjBL,GAA8C,OAAjBA,EAC7CR,EAAeQ,EAAcN,EAAQG,GACJ,iBAAjBG,IAChBN,EAAOG,EAAaS,KAAK,MAAQ,CAC/BC,KAAM,aACNC,QAASR,GAGf,EAhBA,IAAK,IAAMD,KAAON,EAAMG,GAiB1B,CAEA,IAAMa,EAAmB,SACvBC,EACAC,GAMA,IAAMjB,EAAqC,GAG3C,OAFAF,EAAekB,EAAkBhB,GAE1BA,CACT,EAEgB,SAAAkB,EACdC,GAEA,OAAcC,SAAAA,EAAQC,EAAUC,GAAW,IACzC,IAAMC,EAAmBJ,EAAUK,SAASJ,GACtCK,EAAmD,IAAzCC,OAAOC,KAAKJ,GAAkBK,OAI9C,OAFAN,EAAQO,2BAA6BC,EAAuB,CAAE,EAAER,GAEhES,QAAAC,QAAOP,EACH,CACEL,OAAQA,EACRpB,OAAQ,CAAA,GAEV,CACEoB,OAAQ,CAAA,EACRpB,OAAQiC,EACNlB,EACEQ,GAIFD,IAGV,CAAC,MAAAY,GAAA,OAAAH,QAAAI,OAAAD,EACH,CAAA,CAAA,CAEgB,SAAAE,EAGdjB,GACA,OAAcC,SAAAA,EAAQC,EAAUC,GAAW,IAAA,OAAAS,QAAAC,QACVb,EAAUkB,cAAcjB,IAAOkB,KAAA,SAAxDf,GACN,IAAME,EAAmD,IAAzCC,OAAOC,KAAKJ,GAAkBK,OAI9C,OAFAN,EAAQO,2BAA6BC,EAAuB,CAAA,EAAIR,GAEzDG,EACH,CACEL,OAAQA,EACRpB,OAAQ,CACT,GACD,CACEoB,OAAQ,CAAA,EACRpB,OAAQiC,EACNlB,EACEQ,GAIFD,GAEF,EACR,CAAC,MAAAY,GAAA,OAAAH,QAAAI,OAAAD,EACH,CAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@hookform/resolvers")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers"],r):r((e||self)["hookformResolversfluentvalidation-ts"]={},e.hookformResolvers)}(this,function(e,r){function o(e,r,t){void 0===t&&(t=[]);var n=function(){var n=[].concat(t,[i]),s=e[i];Array.isArray(s)?s.forEach(function(e,t){o(e,r,[].concat(n,[t]))}):"object"==typeof s&&null!==s?o(s,r,n):"string"==typeof s&&(r[n.join(".")]={type:"validation",message:s})};for(var i in e)n()}var t=function(e,r){var t={};return o(e,t),t};e.fluentAsyncValidationResolver=function(e){return function(o,n,i){try{return Promise.resolve(e.validateAsync(o)).then(function(e){var n=0===Object.keys(e).length;return i.shouldUseNativeValidation&&r.validateFieldsNatively({},i),n?{values:o,errors:{}}:{values:{},errors:r.toNestErrors(t(e),i)}})}catch(e){return Promise.reject(e)}}},e.fluentValidationResolver=function(e){return function(o,n,i){try{var s=e.validate(o),a=0===Object.keys(s).length;return i.shouldUseNativeValidation&&r.validateFieldsNatively({},i),Promise.resolve(a?{values:o,errors:{}}:{values:{},errors:r.toNestErrors(t(s),i)})}catch(e){return Promise.reject(e)}}}});
2
+ //# sourceMappingURL=fluentvalidation-ts.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fluentvalidation-ts.umd.js","sources":["../src/fluentvalidation-ts.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport {\n AsyncValidator,\n ValidationErrors,\n Validator,\n} from 'fluentvalidation-ts';\nimport { FieldError, FieldValues, Resolver } from 'react-hook-form';\n\nfunction traverseObject<T>(\n object: ValidationErrors<T>,\n errors: Record<string, FieldError>,\n parentIndices: (string | number)[] = [],\n) {\n for (const key in object) {\n const currentIndex = [...parentIndices, key];\n const currentValue = object[key];\n\n if (Array.isArray(currentValue)) {\n currentValue.forEach((item: any, index: number) => {\n traverseObject(item, errors, [...currentIndex, index]);\n });\n } else if (typeof currentValue === 'object' && currentValue !== null) {\n traverseObject(currentValue, errors, currentIndex);\n } else if (typeof currentValue === 'string') {\n errors[currentIndex.join('.')] = {\n type: 'validation',\n message: currentValue,\n };\n }\n }\n}\n\nconst parseErrorSchema = <T>(\n validationErrors: ValidationErrors<T>,\n validateAllFieldCriteria: boolean,\n) => {\n if (validateAllFieldCriteria) {\n // TODO: check this but i think its always one validation error\n }\n\n const errors: Record<string, FieldError> = {};\n traverseObject(validationErrors, errors);\n\n return errors;\n};\n\nexport function fluentValidationResolver<TFieldValues extends FieldValues>(\n validator: Validator<TFieldValues>,\n): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = validator.validate(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n\nexport function fluentAsyncValidationResolver<\n TFieldValues extends FieldValues,\n TValidator extends AsyncValidator<TFieldValues>,\n>(validator: TValidator): Resolver<TFieldValues> {\n return async (values, _context, options) => {\n const validationResult = await validator.validateAsync(values);\n const isValid = Object.keys(validationResult).length === 0;\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return isValid\n ? {\n values: values,\n errors: {},\n }\n : {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n validationResult,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n}\n"],"names":["traverseObject","object","errors","parentIndices","_loop","currentIndex","concat","key","currentValue","Array","isArray","forEach","item","index","join","type","message","parseErrorSchema","validationErrors","validateAllFieldCriteria","validator","values","_context","options","Promise","resolve","validateAsync","then","validationResult","isValid","Object","keys","length","shouldUseNativeValidation","validateFieldsNatively","toNestErrors","e","reject","validate"],"mappings":"4UAQA,SAASA,EACPC,EACAC,EACAC,YAAAA,IAAAA,EAAqC,IAAE,IAAAC,EAAAA,WAGrC,IAAMC,EAAY,GAAAC,OAAOH,EAAa,CAAEI,IAClCC,EAAeP,EAAOM,GAExBE,MAAMC,QAAQF,GAChBA,EAAaG,QAAQ,SAACC,EAAWC,GAC/Bb,EAAeY,EAAMV,EAAM,GAAAI,OAAMD,EAAcQ,CAAAA,IACjD,GACiC,iBAAjBL,GAA8C,OAAjBA,EAC7CR,EAAeQ,EAAcN,EAAQG,GACJ,iBAAjBG,IAChBN,EAAOG,EAAaS,KAAK,MAAQ,CAC/BC,KAAM,aACNC,QAASR,GAGf,EAhBA,IAAK,IAAMD,KAAON,EAAMG,GAiB1B,CAEA,IAAMa,EAAmB,SACvBC,EACAC,GAMA,IAAMjB,EAAqC,GAG3C,OAFAF,EAAekB,EAAkBhB,GAE1BA,CACT,kCA8BgB,SAGdkB,GACA,OAAcC,SAAAA,EAAQC,EAAUC,GAAW,IAAA,OAAAC,QAAAC,QACVL,EAAUM,cAAcL,IAAOM,KAAA,SAAxDC,GACN,IAAMC,EAAmD,IAAzCC,OAAOC,KAAKH,GAAkBI,OAI9C,OAFAT,EAAQU,2BAA6BC,yBAAuB,CAAA,EAAIX,GAEzDM,EACH,CACER,OAAQA,EACRnB,OAAQ,CACT,GACD,CACEmB,OAAQ,CAAA,EACRnB,OAAQiC,EAAYA,aAClBlB,EACEW,GAIFL,GAEF,EACR,CAAC,MAAAa,GAAA,OAAAZ,QAAAa,OAAAD,EACH,CAAA,CAAA,6BAvDgB,SACdhB,GAEA,OAAcC,SAAAA,EAAQC,EAAUC,GAAW,IACzC,IAAMK,EAAmBR,EAAUkB,SAASjB,GACtCQ,EAAmD,IAAzCC,OAAOC,KAAKH,GAAkBI,OAI9C,OAFAT,EAAQU,2BAA6BC,EAAsBA,uBAAC,CAAE,EAAEX,GAEhEC,QAAAC,QAAOI,EACH,CACER,OAAQA,EACRnB,OAAQ,CAAA,GAEV,CACEmB,OAAQ,CAAA,EACRnB,OAAQiC,EAAAA,aACNlB,EACEW,GAIFL,IAGV,CAAC,MAAAa,GAAA,OAAAZ,QAAAa,OAAAD,EACH,CAAA,CAAA"}
@@ -0,0 +1 @@
1
+ export * from './fluentvalidation-ts';
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@hookform/resolvers/fluentvalidation-ts",
3
+ "amdName": "hookformResolversfluentvalidation-ts",
4
+ "version": "1.0.0",
5
+ "private": true,
6
+ "description": "React Hook Form validation resolver: fluentvalidation-ts",
7
+ "main": "dist/fluentvalidation-ts.js",
8
+ "module": "dist/fluentvalidation-ts.module.js",
9
+ "umd:main": "dist/fluentvalidation-ts.umd.js",
10
+ "source": "src/index.ts",
11
+ "types": "dist/index.d.ts",
12
+ "license": "MIT",
13
+ "peerDependencies": {
14
+ "react-hook-form": "^7.0.0",
15
+ "@hookform/resolvers": "^2.0.0",
16
+ "fluentvalidation-ts": "^3.0.0"
17
+ }
18
+ }
@@ -0,0 +1,88 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import user from '@testing-library/user-event';
3
+ import { Validator } from 'fluentvalidation-ts';
4
+ import React from 'react';
5
+ import { useForm } from 'react-hook-form';
6
+ import { fluentValidationResolver } from '../fluentvalidation-ts';
7
+
8
+ const USERNAME_REQUIRED_MESSAGE = 'username field is required';
9
+ const PASSWORD_REQUIRED_MESSAGE = 'password field is required';
10
+
11
+ type FormData = {
12
+ username: string;
13
+ password: string;
14
+ };
15
+
16
+ class FormDataValidator extends Validator<FormData> {
17
+ constructor() {
18
+ super();
19
+
20
+ this.ruleFor('username').notEmpty().withMessage(USERNAME_REQUIRED_MESSAGE);
21
+ this.ruleFor('password').notEmpty().withMessage(PASSWORD_REQUIRED_MESSAGE);
22
+ }
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: fluentValidationResolver(new FormDataValidator()),
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 fluentvalidation-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,63 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import user from '@testing-library/user-event';
3
+ import { Validator } from 'fluentvalidation-ts';
4
+ import React from 'react';
5
+ import { SubmitHandler, useForm } from 'react-hook-form';
6
+ import { fluentValidationResolver } from '../fluentvalidation-ts';
7
+
8
+ type FormData = {
9
+ username: string;
10
+ password: string;
11
+ };
12
+
13
+ class FormDataValidator extends Validator<FormData> {
14
+ constructor() {
15
+ super();
16
+
17
+ this.ruleFor('username')
18
+ .notEmpty()
19
+ .withMessage('username is a required field');
20
+ this.ruleFor('password')
21
+ .notEmpty()
22
+ .withMessage('password is a required field');
23
+ }
24
+ }
25
+
26
+ interface Props {
27
+ onSubmit: SubmitHandler<FormData>;
28
+ }
29
+
30
+ function TestComponent({ onSubmit }: Props) {
31
+ const {
32
+ register,
33
+ formState: { errors },
34
+ handleSubmit,
35
+ } = useForm({
36
+ resolver: fluentValidationResolver(new FormDataValidator()), // Useful to check TypeScript regressions
37
+ });
38
+
39
+ return (
40
+ <form onSubmit={handleSubmit(onSubmit)}>
41
+ <input {...register('username')} />
42
+ {errors.username && <span role="alert">{errors.username.message}</span>}
43
+
44
+ <input {...register('password')} />
45
+ {errors.password && <span role="alert">{errors.password.message}</span>}
46
+
47
+ <button type="submit">submit</button>
48
+ </form>
49
+ );
50
+ }
51
+
52
+ test("form's validation with Yup and TypeScript's integration", async () => {
53
+ const handleSubmit = vi.fn();
54
+ render(<TestComponent onSubmit={handleSubmit} />);
55
+
56
+ expect(screen.queryAllByRole('alert')).toHaveLength(0);
57
+
58
+ await user.click(screen.getByText(/submit/i));
59
+
60
+ expect(screen.getByText(/username is a required field/i)).toBeInTheDocument();
61
+ expect(screen.getByText(/password is a required field/i)).toBeInTheDocument();
62
+ expect(handleSubmit).not.toHaveBeenCalled();
63
+ });
@@ -0,0 +1,121 @@
1
+ import { Validator } from 'fluentvalidation-ts';
2
+ import { Field, InternalFieldName } from 'react-hook-form';
3
+
4
+ const beNumeric = (value: string | number | undefined) => !isNaN(Number(value));
5
+
6
+ export type Schema = {
7
+ username: string;
8
+ password: string;
9
+ repeatPassword: string;
10
+ accessToken?: string;
11
+ birthYear?: number;
12
+ email?: string;
13
+ tags?: string[];
14
+ enabled?: boolean;
15
+ like?: {
16
+ id: number;
17
+ name: string;
18
+ }[];
19
+ };
20
+
21
+ export type SchemaWithWhen = {
22
+ name: string;
23
+ value: string;
24
+ };
25
+
26
+ export class SchemaValidator extends Validator<Schema> {
27
+ constructor() {
28
+ super();
29
+
30
+ this.ruleFor('username')
31
+ .notEmpty()
32
+ .matches(/^\w+$/)
33
+ .minLength(3)
34
+ .maxLength(30);
35
+
36
+ this.ruleFor('password')
37
+ .notEmpty()
38
+ .matches(/.*[A-Z].*/)
39
+ .withMessage('One uppercase character')
40
+ .matches(/.*[a-z].*/)
41
+ .withMessage('One lowercase character')
42
+ .matches(/.*\d.*/)
43
+ .withMessage('One number')
44
+ .matches(new RegExp('.*[`~<>?,./!@#$%^&*()\\-_+="\'|{}\\[\\];:\\\\].*'))
45
+ .withMessage('One special character')
46
+ .minLength(8)
47
+ .withMessage('Must be at least 8 characters in length');
48
+
49
+ this.ruleFor('repeatPassword')
50
+ .notEmpty()
51
+ .must((repeatPassword, data) => repeatPassword === data.password);
52
+
53
+ this.ruleFor('accessToken');
54
+ this.ruleFor('birthYear')
55
+ .must(beNumeric)
56
+ .inclusiveBetween(1900, 2013)
57
+ .when((birthYear) => birthYear != undefined);
58
+
59
+ this.ruleFor('email').emailAddress();
60
+ this.ruleFor('tags');
61
+ this.ruleFor('enabled');
62
+
63
+ this.ruleForEach('like').setValidator(() => new LikeValidator());
64
+ }
65
+ }
66
+
67
+ export class LikeValidator extends Validator<{
68
+ id: number;
69
+ name: string;
70
+ }> {
71
+ constructor() {
72
+ super();
73
+
74
+ this.ruleFor('id').notNull();
75
+ this.ruleFor('name').notEmpty().length(4, 4);
76
+ }
77
+ }
78
+
79
+ export const validData = {
80
+ username: 'Doe',
81
+ password: 'Password123_',
82
+ repeatPassword: 'Password123_',
83
+ birthYear: 2000,
84
+ email: 'john@doe.com',
85
+ tags: ['tag1', 'tag2'],
86
+ enabled: true,
87
+ accesstoken: 'accesstoken',
88
+ like: [
89
+ {
90
+ id: 1,
91
+ name: 'name',
92
+ },
93
+ ],
94
+ } as Schema;
95
+
96
+ export const invalidData = {
97
+ password: '___',
98
+ email: '',
99
+ birthYear: 'birthYear',
100
+ like: [{ id: 'z' }],
101
+ // Must be set to "unknown", otherwise typescript knows that it is invalid
102
+ } as unknown as Required<Schema>;
103
+
104
+ export const fields: Record<InternalFieldName, Field['_f']> = {
105
+ username: {
106
+ ref: { name: 'username' },
107
+ name: 'username',
108
+ },
109
+ password: {
110
+ ref: { name: 'password' },
111
+ name: 'password',
112
+ },
113
+ email: {
114
+ ref: { name: 'email' },
115
+ name: 'email',
116
+ },
117
+ birthday: {
118
+ ref: { name: 'birthday' },
119
+ name: 'birthday',
120
+ },
121
+ };
@@ -0,0 +1,129 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`fluentValidationResolver > should return a single error from fluentValidationResolver when validation fails 1`] = `
4
+ {
5
+ "errors": {
6
+ "birthYear": {
7
+ "message": "Value is not valid",
8
+ "ref": undefined,
9
+ "type": "validation",
10
+ },
11
+ "email": {
12
+ "message": "Not a valid email address",
13
+ "ref": {
14
+ "name": "email",
15
+ },
16
+ "type": "validation",
17
+ },
18
+ "password": {
19
+ "message": "One uppercase character",
20
+ "ref": {
21
+ "name": "password",
22
+ },
23
+ "type": "validation",
24
+ },
25
+ "repeatPassword": {
26
+ "message": "Value is not valid",
27
+ "ref": undefined,
28
+ "type": "validation",
29
+ },
30
+ },
31
+ "values": {},
32
+ }
33
+ `;
34
+
35
+ exports[`fluentValidationResolver > should return a single error from fluentValidationResolver with \`mode: sync\` when validation fails 1`] = `
36
+ {
37
+ "errors": {
38
+ "birthYear": {
39
+ "message": "Value is not valid",
40
+ "ref": undefined,
41
+ "type": "validation",
42
+ },
43
+ "email": {
44
+ "message": "Not a valid email address",
45
+ "ref": {
46
+ "name": "email",
47
+ },
48
+ "type": "validation",
49
+ },
50
+ "password": {
51
+ "message": "One uppercase character",
52
+ "ref": {
53
+ "name": "password",
54
+ },
55
+ "type": "validation",
56
+ },
57
+ "repeatPassword": {
58
+ "message": "Value is not valid",
59
+ "ref": undefined,
60
+ "type": "validation",
61
+ },
62
+ },
63
+ "values": {},
64
+ }
65
+ `;
66
+
67
+ exports[`fluentValidationResolver > should return all the errors from fluentValidationResolver when validation fails with \`validateAllFieldCriteria\` set to true 1`] = `
68
+ {
69
+ "errors": {
70
+ "birthYear": {
71
+ "message": "Value is not valid",
72
+ "ref": undefined,
73
+ "type": "validation",
74
+ },
75
+ "email": {
76
+ "message": "Not a valid email address",
77
+ "ref": {
78
+ "name": "email",
79
+ },
80
+ "type": "validation",
81
+ },
82
+ "password": {
83
+ "message": "One uppercase character",
84
+ "ref": {
85
+ "name": "password",
86
+ },
87
+ "type": "validation",
88
+ },
89
+ "repeatPassword": {
90
+ "message": "Value is not valid",
91
+ "ref": undefined,
92
+ "type": "validation",
93
+ },
94
+ },
95
+ "values": {},
96
+ }
97
+ `;
98
+
99
+ exports[`fluentValidationResolver > should return all the errors from fluentValidationResolver when validation fails with \`validateAllFieldCriteria\` set to true and \`mode: sync\` 1`] = `
100
+ {
101
+ "errors": {
102
+ "birthYear": {
103
+ "message": "Value is not valid",
104
+ "ref": undefined,
105
+ "type": "validation",
106
+ },
107
+ "email": {
108
+ "message": "Not a valid email address",
109
+ "ref": {
110
+ "name": "email",
111
+ },
112
+ "type": "validation",
113
+ },
114
+ "password": {
115
+ "message": "One uppercase character",
116
+ "ref": {
117
+ "name": "password",
118
+ },
119
+ "type": "validation",
120
+ },
121
+ "repeatPassword": {
122
+ "message": "Value is not valid",
123
+ "ref": undefined,
124
+ "type": "validation",
125
+ },
126
+ },
127
+ "values": {},
128
+ }
129
+ `;
@@ -0,0 +1,113 @@
1
+ /* eslint-disable no-console, @typescript-eslint/ban-ts-comment */
2
+ import { fluentValidationResolver } from '..';
3
+ import {
4
+ SchemaValidator,
5
+ fields,
6
+ invalidData,
7
+ validData,
8
+ } from './__fixtures__/data';
9
+
10
+ const shouldUseNativeValidation = false;
11
+
12
+ const validator = new SchemaValidator();
13
+
14
+ describe('fluentValidationResolver', () => {
15
+ it('should return values from fluentValidationResolver when validation pass', async () => {
16
+ const validatorSpy = vi.spyOn(validator, 'validate');
17
+
18
+ const result = await fluentValidationResolver(validator)(
19
+ validData,
20
+ undefined,
21
+ {
22
+ fields,
23
+ shouldUseNativeValidation,
24
+ },
25
+ );
26
+
27
+ expect(validatorSpy).toHaveBeenCalledTimes(1);
28
+ expect(result).toEqual({ errors: {}, values: validData });
29
+ });
30
+
31
+ it('should return values from fluentValidationResolver with `mode: sync` when validation pass', async () => {
32
+ const validatorSpy = vi.spyOn(validator, 'validate');
33
+
34
+ const result = await fluentValidationResolver(validator)(
35
+ validData,
36
+ undefined,
37
+ { fields, shouldUseNativeValidation },
38
+ );
39
+
40
+ expect(validatorSpy).toHaveBeenCalledTimes(1);
41
+ expect(result).toEqual({ errors: {}, values: validData });
42
+ });
43
+
44
+ it('should return a single error from fluentValidationResolver when validation fails', async () => {
45
+ const result = await fluentValidationResolver(validator)(
46
+ invalidData,
47
+ undefined,
48
+ {
49
+ fields,
50
+ shouldUseNativeValidation,
51
+ },
52
+ );
53
+
54
+ expect(result).toMatchSnapshot();
55
+ });
56
+
57
+ it('should return a single error from fluentValidationResolver with `mode: sync` when validation fails', async () => {
58
+ const validateSpy = vi.spyOn(validator, 'validate');
59
+
60
+ const result = await fluentValidationResolver(validator)(
61
+ invalidData,
62
+ undefined,
63
+ { fields, shouldUseNativeValidation },
64
+ );
65
+
66
+ expect(validateSpy).toHaveBeenCalledTimes(1);
67
+ expect(result).toMatchSnapshot();
68
+ });
69
+
70
+ it('should return all the errors from fluentValidationResolver when validation fails with `validateAllFieldCriteria` set to true', async () => {
71
+ const result = await fluentValidationResolver(validator)(
72
+ invalidData,
73
+ undefined,
74
+ {
75
+ fields,
76
+ criteriaMode: 'all',
77
+ shouldUseNativeValidation,
78
+ },
79
+ );
80
+
81
+ expect(result).toMatchSnapshot();
82
+ });
83
+
84
+ it('should return all the errors from fluentValidationResolver when validation fails with `validateAllFieldCriteria` set to true and `mode: sync`', async () => {
85
+ const result = await fluentValidationResolver(validator)(
86
+ invalidData,
87
+ undefined,
88
+ {
89
+ fields,
90
+ criteriaMode: 'all',
91
+ shouldUseNativeValidation,
92
+ },
93
+ );
94
+
95
+ expect(result).toMatchSnapshot();
96
+ });
97
+
98
+ it('should return values from fluentValidationResolver when validation pass & raw=true', async () => {
99
+ const schemaSpy = vi.spyOn(validator, 'validate');
100
+
101
+ const result = await fluentValidationResolver(validator)(
102
+ validData,
103
+ undefined,
104
+ {
105
+ fields,
106
+ shouldUseNativeValidation,
107
+ },
108
+ );
109
+
110
+ expect(schemaSpy).toHaveBeenCalledTimes(1);
111
+ expect(result).toEqual({ errors: {}, values: validData });
112
+ });
113
+ });
@@ -0,0 +1,102 @@
1
+ import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';
2
+ import {
3
+ AsyncValidator,
4
+ ValidationErrors,
5
+ Validator,
6
+ } from 'fluentvalidation-ts';
7
+ import { FieldError, FieldValues, Resolver } from 'react-hook-form';
8
+
9
+ function traverseObject<T>(
10
+ object: ValidationErrors<T>,
11
+ errors: Record<string, FieldError>,
12
+ parentIndices: (string | number)[] = [],
13
+ ) {
14
+ for (const key in object) {
15
+ const currentIndex = [...parentIndices, key];
16
+ const currentValue = object[key];
17
+
18
+ if (Array.isArray(currentValue)) {
19
+ currentValue.forEach((item: any, index: number) => {
20
+ traverseObject(item, errors, [...currentIndex, index]);
21
+ });
22
+ } else if (typeof currentValue === 'object' && currentValue !== null) {
23
+ traverseObject(currentValue, errors, currentIndex);
24
+ } else if (typeof currentValue === 'string') {
25
+ errors[currentIndex.join('.')] = {
26
+ type: 'validation',
27
+ message: currentValue,
28
+ };
29
+ }
30
+ }
31
+ }
32
+
33
+ const parseErrorSchema = <T>(
34
+ validationErrors: ValidationErrors<T>,
35
+ validateAllFieldCriteria: boolean,
36
+ ) => {
37
+ if (validateAllFieldCriteria) {
38
+ // TODO: check this but i think its always one validation error
39
+ }
40
+
41
+ const errors: Record<string, FieldError> = {};
42
+ traverseObject(validationErrors, errors);
43
+
44
+ return errors;
45
+ };
46
+
47
+ export function fluentValidationResolver<TFieldValues extends FieldValues>(
48
+ validator: Validator<TFieldValues>,
49
+ ): Resolver<TFieldValues> {
50
+ return async (values, _context, options) => {
51
+ const validationResult = validator.validate(values);
52
+ const isValid = Object.keys(validationResult).length === 0;
53
+
54
+ options.shouldUseNativeValidation && validateFieldsNatively({}, options);
55
+
56
+ return isValid
57
+ ? {
58
+ values: values,
59
+ errors: {},
60
+ }
61
+ : {
62
+ values: {},
63
+ errors: toNestErrors(
64
+ parseErrorSchema(
65
+ validationResult,
66
+ !options.shouldUseNativeValidation &&
67
+ options.criteriaMode === 'all',
68
+ ),
69
+ options,
70
+ ),
71
+ };
72
+ };
73
+ }
74
+
75
+ export function fluentAsyncValidationResolver<
76
+ TFieldValues extends FieldValues,
77
+ TValidator extends AsyncValidator<TFieldValues>,
78
+ >(validator: TValidator): Resolver<TFieldValues> {
79
+ return async (values, _context, options) => {
80
+ const validationResult = await validator.validateAsync(values);
81
+ const isValid = Object.keys(validationResult).length === 0;
82
+
83
+ options.shouldUseNativeValidation && validateFieldsNatively({}, options);
84
+
85
+ return isValid
86
+ ? {
87
+ values: values,
88
+ errors: {},
89
+ }
90
+ : {
91
+ values: {},
92
+ errors: toNestErrors(
93
+ parseErrorSchema(
94
+ validationResult,
95
+ !options.shouldUseNativeValidation &&
96
+ options.criteriaMode === 'all',
97
+ ),
98
+ options,
99
+ ),
100
+ };
101
+ };
102
+ }
@@ -0,0 +1 @@
1
+ export * from './fluentvalidation-ts';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hookform/resolvers",
3
3
  "amdName": "hookformResolvers",
4
- "version": "3.8.0",
4
+ "version": "3.9.1",
5
5
  "description": "React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype, Typanion, Effect-TS and VineJS",
6
6
  "main": "dist/resolvers.js",
7
7
  "module": "dist/resolvers.module.js",
@@ -117,6 +117,12 @@
117
117
  "import": "./vine/dist/vine.mjs",
118
118
  "require": "./vine/dist/vine.js"
119
119
  },
120
+ "./fluentvalidation-ts": {
121
+ "types": "./fluentvalidation-ts/dist/index.d.ts",
122
+ "umd": "./fluentvalidation-ts/dist/fluentvalidation-ts.umd.js",
123
+ "import": "./fluentvalidation-ts/dist/fluentvalidation-ts.mjs",
124
+ "require": "./fluentvalidation-ts/dist/fluentvalidation-ts.js"
125
+ },
120
126
  "./package.json": "./package.json",
121
127
  "./*": "./*"
122
128
  },
@@ -175,13 +181,16 @@
175
181
  "effect-ts/dist",
176
182
  "vine/package.json",
177
183
  "vine/src",
178
- "vine/dist"
184
+ "vine/dist",
185
+ "fluentvalidation-ts/package.json",
186
+ "fluentvalidation-ts/src",
187
+ "fluentvalidation-ts/dist"
179
188
  ],
180
189
  "publishConfig": {
181
190
  "access": "public"
182
191
  },
183
192
  "scripts": {
184
- "prepare": "run-s build:src build && check-export-map",
193
+ "prepare": "run-s build:src",
185
194
  "build": "cross-env npm-run-all --parallel 'build:*'",
186
195
  "build:src": "microbundle build --globals react-hook-form=ReactHookForm",
187
196
  "build:zod": "microbundle --cwd zod --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
@@ -201,7 +210,8 @@
201
210
  "build:typeschema": "microbundle --cwd typeschema --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm,@typeschema/main=main",
202
211
  "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,@effect/schema/ParseResult=EffectSchemaArrayFormatter,effect/Effect=Effect",
203
212
  "build:vine": "microbundle --cwd vine --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm,@vinejs/vine=vine",
204
- "postbuild": "node ./config/node-13-exports.js",
213
+ "build:fluentvalidation-ts": "microbundle --cwd fluentvalidation-ts --globals @hookform/resolvers=hookformResolvers,react-hook-form=ReactHookForm",
214
+ "postbuild": "node ./config/node-13-exports.js && check-export-map",
205
215
  "lint": "bunx @biomejs/biome check --write --vcs-use-ignore-file=true .",
206
216
  "lint:types": "tsc",
207
217
  "test": "vitest run",
@@ -232,7 +242,8 @@
232
242
  "TypeBox",
233
243
  "arktype",
234
244
  "typeschema",
235
- "vine"
245
+ "vine",
246
+ "fluentvalidation-ts"
236
247
  ],
237
248
  "repository": {
238
249
  "type": "git",
@@ -245,9 +256,9 @@
245
256
  },
246
257
  "homepage": "https://react-hook-form.com",
247
258
  "devDependencies": {
248
- "@effect/schema": "^0.68.15",
259
+ "@effect/schema": "^0.68.17",
249
260
  "@sinclair/typebox": "^0.32.34",
250
- "@testing-library/dom": "^10.3.0",
261
+ "@testing-library/dom": "^10.3.1",
251
262
  "@testing-library/jest-dom": "^6.4.6",
252
263
  "@testing-library/react": "^16.0.0",
253
264
  "@testing-library/user-event": "^14.5.2",
@@ -266,7 +277,8 @@
266
277
  "class-validator": "^0.14.1",
267
278
  "computed-types": "^1.11.2",
268
279
  "cross-env": "^7.0.3",
269
- "effect": "^3.4.6",
280
+ "effect": "^3.4.7",
281
+ "fluentvalidation-ts": "^3.2.0",
270
282
  "fp-ts": "^2.16.7",
271
283
  "io-ts": "^2.2.21",
272
284
  "io-ts-types": "^0.5.19",
@@ -285,7 +297,7 @@
285
297
  "superstruct": "^1.0.4",
286
298
  "typanion": "^3.14.0",
287
299
  "typescript": "^5.5.3",
288
- "valibot": "0.35.0",
300
+ "valibot": "^1.0.0-beta.0",
289
301
  "vest": "^5.3.0",
290
302
  "vite": "^5.3.3",
291
303
  "vite-tsconfig-paths": "^4.3.2",
@@ -13,6 +13,6 @@
13
13
  "peerDependencies": {
14
14
  "@hookform/resolvers": "^2.0.0",
15
15
  "react-hook-form": "^7.0.0",
16
- "valibot": ">=0.33.0 <1"
16
+ "valibot": "^1.0.0 || ^1.0.0-beta || ^1.0.0-rc"
17
17
  }
18
18
  }