@hookform/resolvers 3.6.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -25
- package/ajv/dist/ajv.js.map +1 -1
- package/ajv/dist/ajv.modern.mjs.map +1 -1
- package/ajv/dist/ajv.module.js.map +1 -1
- package/ajv/dist/ajv.umd.js.map +1 -1
- package/ajv/dist/types.d.ts +1 -1
- package/ajv/src/__tests__/ajv.ts +7 -1
- package/ajv/src/ajv.ts +1 -1
- package/ajv/src/types.ts +1 -5
- package/arktype/dist/arktype.js +1 -1
- package/arktype/dist/arktype.js.map +1 -1
- package/arktype/dist/arktype.mjs +1 -1
- package/arktype/dist/arktype.modern.mjs +1 -1
- package/arktype/dist/arktype.modern.mjs.map +1 -1
- package/arktype/dist/arktype.module.js +1 -1
- package/arktype/dist/arktype.module.js.map +1 -1
- package/arktype/dist/arktype.umd.js +1 -1
- package/arktype/dist/arktype.umd.js.map +1 -1
- package/arktype/dist/types.d.ts +1 -1
- package/arktype/package.json +2 -1
- package/arktype/src/__tests__/Form-native-validation.tsx +5 -5
- package/arktype/src/__tests__/Form.tsx +2 -2
- package/arktype/src/__tests__/__fixtures__/data.ts +1 -1
- package/arktype/src/__tests__/__snapshots__/arktype.ts.snap +29 -29
- package/arktype/src/__tests__/arktype.ts +1 -1
- package/arktype/src/arktype.ts +2 -2
- package/arktype/src/types.ts +1 -1
- package/class-validator/dist/class-validator.js.map +1 -1
- package/class-validator/dist/class-validator.modern.mjs.map +1 -1
- package/class-validator/dist/class-validator.module.js.map +1 -1
- package/class-validator/dist/class-validator.umd.js.map +1 -1
- package/class-validator/dist/types.d.ts +2 -2
- package/class-validator/src/__tests__/Form-native-validation.tsx +2 -2
- package/class-validator/src/__tests__/Form.tsx +2 -2
- package/class-validator/src/__tests__/__snapshots__/class-validator.ts.snap +2 -2
- package/class-validator/src/__tests__/class-validator.ts +4 -4
- package/class-validator/src/class-validator.ts +2 -2
- package/class-validator/src/types.ts +2 -2
- package/computed-types/dist/computed-types.js.map +1 -1
- package/computed-types/dist/computed-types.modern.mjs.map +1 -1
- package/computed-types/dist/computed-types.module.js.map +1 -1
- package/computed-types/dist/computed-types.umd.js.map +1 -1
- package/computed-types/dist/types.d.ts +1 -1
- package/computed-types/src/__tests__/Form-native-validation.tsx +2 -2
- package/computed-types/src/__tests__/Form.tsx +2 -2
- package/computed-types/src/__tests__/__fixtures__/data.ts +1 -1
- package/computed-types/src/__tests__/__snapshots__/computed-types.ts.snap +6 -6
- package/computed-types/src/__tests__/computed-types.ts +1 -1
- package/computed-types/src/computed-types.ts +2 -2
- package/computed-types/src/types.ts +1 -1
- package/dist/resolvers.js +1 -1
- package/dist/resolvers.js.map +1 -1
- package/dist/resolvers.mjs +1 -1
- package/dist/resolvers.mjs.map +1 -1
- package/dist/resolvers.module.js +1 -1
- package/dist/resolvers.module.js.map +1 -1
- package/dist/resolvers.umd.js +1 -1
- package/dist/resolvers.umd.js.map +1 -1
- package/dist/toNestErrors.d.ts +1 -6
- package/dist/validateFieldsNatively.d.ts +1 -1
- package/effect-ts/dist/effect-ts.js +1 -1
- package/effect-ts/dist/effect-ts.js.map +1 -1
- package/effect-ts/dist/effect-ts.mjs +1 -1
- package/effect-ts/dist/effect-ts.modern.mjs +1 -1
- package/effect-ts/dist/effect-ts.modern.mjs.map +1 -1
- package/effect-ts/dist/effect-ts.module.js +1 -1
- package/effect-ts/dist/effect-ts.module.js.map +1 -1
- package/effect-ts/dist/effect-ts.umd.js +1 -1
- package/effect-ts/dist/effect-ts.umd.js.map +1 -1
- package/effect-ts/src/__tests__/Form-native-validation.tsx +2 -2
- package/effect-ts/src/__tests__/Form.tsx +2 -2
- package/effect-ts/src/__tests__/__snapshots__/effect-ts.ts.snap +2 -2
- package/effect-ts/src/__tests__/effect-ts.ts +1 -1
- package/effect-ts/src/effect-ts.ts +1 -1
- package/io-ts/dist/errorsToRecord.d.ts +0 -1
- package/io-ts/dist/io-ts.js +1 -1
- package/io-ts/dist/io-ts.js.map +1 -1
- package/io-ts/dist/io-ts.mjs +1 -1
- package/io-ts/dist/io-ts.modern.mjs +1 -1
- package/io-ts/dist/io-ts.modern.mjs.map +1 -1
- package/io-ts/dist/io-ts.module.js +1 -1
- package/io-ts/dist/io-ts.module.js.map +1 -1
- package/io-ts/dist/io-ts.umd.js +1 -1
- package/io-ts/dist/io-ts.umd.js.map +1 -1
- package/io-ts/src/__tests__/Form-native-validation.tsx +2 -2
- package/io-ts/src/__tests__/Form.tsx +2 -2
- package/io-ts/src/__tests__/__snapshots__/io-ts.ts.snap +9 -9
- package/io-ts/src/__tests__/errorsToRecord.ts +29 -19
- package/io-ts/src/__tests__/io-ts.ts +1 -1
- package/io-ts/src/errorsToRecord.ts +19 -10
- package/io-ts/src/io-ts.ts +1 -1
- package/joi/dist/joi.js +1 -1
- package/joi/dist/joi.js.map +1 -1
- package/joi/dist/joi.mjs +1 -1
- package/joi/dist/joi.modern.mjs +1 -1
- package/joi/dist/joi.modern.mjs.map +1 -1
- package/joi/dist/joi.module.js +1 -1
- package/joi/dist/joi.module.js.map +1 -1
- package/joi/dist/joi.umd.js +1 -1
- package/joi/dist/joi.umd.js.map +1 -1
- package/joi/dist/types.d.ts +1 -1
- package/joi/src/__tests__/Form-native-validation.tsx +2 -2
- package/joi/src/__tests__/Form.tsx +2 -2
- package/joi/src/__tests__/__snapshots__/joi.ts.snap +56 -56
- package/joi/src/__tests__/joi.ts +1 -1
- package/joi/src/joi.ts +1 -1
- package/joi/src/types.ts +1 -5
- package/nope/dist/nope.js.map +1 -1
- package/nope/dist/nope.modern.mjs.map +1 -1
- package/nope/dist/nope.module.js.map +1 -1
- package/nope/dist/nope.umd.js.map +1 -1
- package/nope/dist/types.d.ts +1 -1
- package/nope/src/__tests__/Form-native-validation.tsx +2 -2
- package/nope/src/__tests__/Form.tsx +2 -2
- package/nope/src/__tests__/__fixtures__/data.ts +1 -1
- package/nope/src/__tests__/nope.ts +1 -1
- package/nope/src/nope.ts +1 -1
- package/nope/src/types.ts +2 -2
- package/package.json +69 -54
- package/superstruct/dist/superstruct.js.map +1 -1
- package/superstruct/dist/superstruct.modern.mjs.map +1 -1
- package/superstruct/dist/superstruct.module.js.map +1 -1
- package/superstruct/dist/superstruct.umd.js.map +1 -1
- package/superstruct/dist/types.d.ts +1 -1
- package/superstruct/src/__tests__/Form-native-validation.tsx +2 -2
- package/superstruct/src/__tests__/Form.tsx +2 -2
- package/superstruct/src/__tests__/__fixtures__/data.ts +8 -8
- package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +4 -4
- package/superstruct/src/__tests__/superstruct.ts +1 -1
- package/superstruct/src/superstruct.ts +1 -1
- package/superstruct/src/types.ts +1 -1
- package/typanion/dist/typanion.js.map +1 -1
- package/typanion/dist/typanion.modern.mjs.map +1 -1
- package/typanion/dist/typanion.module.js.map +1 -1
- package/typanion/dist/typanion.umd.js.map +1 -1
- package/typanion/dist/types.d.ts +1 -1
- package/typanion/src/__tests__/Form-native-validation.tsx +1 -1
- package/typanion/src/__tests__/Form.tsx +1 -1
- package/typanion/src/__tests__/__fixtures__/data.ts +12 -7
- package/typanion/src/__tests__/__snapshots__/typanion.ts.snap +4 -4
- package/typanion/src/__tests__/typanion.ts +1 -1
- package/typanion/src/typanion.ts +1 -1
- package/typanion/src/types.ts +4 -4
- package/typebox/dist/typebox.js +1 -1
- package/typebox/dist/typebox.js.map +1 -1
- package/typebox/dist/typebox.mjs +1 -1
- package/typebox/dist/typebox.modern.mjs +1 -1
- package/typebox/dist/typebox.modern.mjs.map +1 -1
- package/typebox/dist/typebox.module.js +1 -1
- package/typebox/dist/typebox.module.js.map +1 -1
- package/typebox/dist/typebox.umd.js +1 -1
- package/typebox/dist/typebox.umd.js.map +1 -1
- package/typebox/dist/types.d.ts +3 -2
- package/typebox/src/__tests__/Form-compiler.tsx +57 -0
- package/typebox/src/__tests__/Form-native-validation-compiler.tsx +86 -0
- package/typebox/src/__tests__/Form-native-validation.tsx +4 -4
- package/typebox/src/__tests__/Form.tsx +3 -3
- package/typebox/src/__tests__/__fixtures__/data.ts +6 -2
- package/typebox/src/__tests__/__snapshots__/typebox-compiler.ts.snap +188 -0
- package/typebox/src/__tests__/__snapshots__/typebox.ts.snap +13 -13
- package/typebox/src/__tests__/typebox-compiler.ts +37 -0
- package/typebox/src/__tests__/typebox.ts +1 -1
- package/typebox/src/typebox.ts +8 -3
- package/typebox/src/types.ts +3 -2
- package/typeschema/dist/index.d.ts +2 -0
- package/typeschema/dist/types.d.ts +9 -0
- package/typeschema/dist/typeschema.d.ts +2 -0
- package/typeschema/dist/typeschema.js +2 -0
- package/typeschema/dist/typeschema.js.map +1 -0
- package/typeschema/dist/typeschema.mjs +2 -0
- package/typeschema/dist/typeschema.modern.mjs +2 -0
- package/typeschema/dist/typeschema.modern.mjs.map +1 -0
- package/typeschema/dist/typeschema.module.js +2 -0
- package/typeschema/dist/typeschema.module.js.map +1 -0
- package/typeschema/dist/typeschema.umd.js +2 -0
- package/typeschema/dist/typeschema.umd.js.map +1 -0
- package/typeschema/package.json +18 -0
- package/typeschema/src/__tests__/Form-native-validation.tsx +82 -0
- package/typeschema/src/__tests__/Form.tsx +53 -0
- package/typeschema/src/__tests__/__fixtures__/data.ts +88 -0
- package/typeschema/src/__tests__/__snapshots__/typeschema.ts.snap +225 -0
- package/typeschema/src/__tests__/typeschema.ts +70 -0
- package/typeschema/src/index.ts +2 -0
- package/typeschema/src/types.ts +18 -0
- package/typeschema/src/typeschema.ts +70 -0
- package/valibot/dist/types.d.ts +1 -1
- package/valibot/dist/valibot.js +1 -1
- package/valibot/dist/valibot.js.map +1 -1
- package/valibot/dist/valibot.mjs +1 -1
- package/valibot/dist/valibot.modern.mjs +1 -1
- package/valibot/dist/valibot.modern.mjs.map +1 -1
- package/valibot/dist/valibot.module.js +1 -1
- package/valibot/dist/valibot.module.js.map +1 -1
- package/valibot/dist/valibot.umd.js +1 -1
- package/valibot/dist/valibot.umd.js.map +1 -1
- package/valibot/package.json +1 -1
- package/valibot/src/__tests__/Form-native-validation.tsx +2 -2
- package/valibot/src/__tests__/Form.tsx +1 -1
- package/valibot/src/__tests__/valibot.ts +4 -4
- package/valibot/src/types.ts +1 -1
- package/valibot/src/valibot.ts +12 -6
- package/vest/dist/types.d.ts +2 -2
- package/vest/dist/vest.js.map +1 -1
- package/vest/dist/vest.modern.mjs.map +1 -1
- package/vest/dist/vest.module.js.map +1 -1
- package/vest/dist/vest.umd.js.map +1 -1
- package/vest/src/__tests__/Form-native-validation.tsx +1 -1
- package/vest/src/__tests__/Form.tsx +1 -1
- package/vest/src/__tests__/__snapshots__/vest.ts.snap +0 -6
- package/vest/src/__tests__/vest.ts +14 -8
- package/vest/src/types.ts +11 -4
- package/vest/src/vest.ts +1 -1
- package/vine/dist/index.d.ts +2 -0
- package/vine/dist/types.d.ts +6 -0
- package/vine/dist/vine.d.ts +2 -0
- package/vine/dist/vine.js +2 -0
- package/vine/dist/vine.js.map +1 -0
- package/vine/dist/vine.mjs +2 -0
- package/vine/dist/vine.modern.mjs +2 -0
- package/vine/dist/vine.modern.mjs.map +1 -0
- package/vine/dist/vine.module.js +2 -0
- package/vine/dist/vine.module.js.map +1 -0
- package/vine/dist/vine.umd.js +2 -0
- package/vine/dist/vine.umd.js.map +1 -0
- package/vine/package.json +18 -0
- package/vine/src/__tests__/Form-native-validation.tsx +85 -0
- package/vine/src/__tests__/Form.tsx +59 -0
- package/vine/src/__tests__/__fixtures__/data.ts +76 -0
- package/vine/src/__tests__/__snapshots__/vine.ts.snap +180 -0
- package/vine/src/__tests__/vine.ts +53 -0
- package/vine/src/index.ts +2 -0
- package/vine/src/types.ts +13 -0
- package/vine/src/vine.ts +68 -0
- package/yup/dist/yup.d.ts +1 -1
- package/yup/dist/yup.js.map +1 -1
- package/yup/dist/yup.modern.mjs.map +1 -1
- package/yup/dist/yup.module.js.map +1 -1
- package/yup/dist/yup.umd.js.map +1 -1
- package/yup/src/__tests__/Form-native-validation.tsx +1 -1
- package/yup/src/__tests__/Form.tsx +1 -1
- package/yup/src/__tests__/__snapshots__/yup.ts.snap +13 -13
- package/yup/src/__tests__/yup.ts +9 -7
- package/yup/src/yup.ts +2 -2
- package/zod/dist/types.d.ts +1 -1
- package/zod/dist/zod.js +1 -1
- package/zod/dist/zod.js.map +1 -1
- package/zod/dist/zod.mjs +1 -1
- package/zod/dist/zod.modern.mjs +1 -1
- package/zod/dist/zod.modern.mjs.map +1 -1
- package/zod/dist/zod.module.js +1 -1
- package/zod/dist/zod.module.js.map +1 -1
- package/zod/dist/zod.umd.js +1 -1
- package/zod/dist/zod.umd.js.map +1 -1
- package/zod/src/__tests__/Form-native-validation.tsx +2 -2
- package/zod/src/__tests__/Form.tsx +1 -1
- package/zod/src/__tests__/zod.ts +1 -1
- package/zod/src/types.ts +1 -1
- package/zod/src/zod.ts +4 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vine.js","sources":["../src/vine.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { SimpleErrorReporter, errors } from '@vinejs/vine';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n vineErrors: SimpleErrorReporter['errors'],\n validateAllFieldCriteria: boolean,\n) => {\n const schemaErrors: Record<string, FieldError> = {};\n\n for (; vineErrors.length; ) {\n const error = vineErrors[0];\n const path = error.field;\n\n if (!(path in schemaErrors)) {\n schemaErrors[path] = { message: error.message, type: error.rule };\n }\n\n if (validateAllFieldCriteria) {\n const { types } = schemaErrors[path];\n const messages = types && types[error.rule];\n\n schemaErrors[path] = appendErrors(\n path,\n validateAllFieldCriteria,\n schemaErrors,\n error.rule,\n messages ? [...(messages as string[]), error.message] : error.message,\n ) as FieldError;\n }\n\n vineErrors.shift();\n }\n\n return schemaErrors;\n};\n\nexport const vineResolver: Resolver =\n (schema, schemaOptions, resolverOptions = {}) =>\n async (values, _, options) => {\n try {\n const data = await schema.validate(values, schemaOptions);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : data,\n };\n } catch (error: any) {\n if (error instanceof errors.E_VALIDATION_ERROR) {\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n error.messages,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n\n throw error;\n }\n };\n"],"names":["parseErrorSchema","vineErrors","validateAllFieldCriteria","schemaErrors","length","error","path","field","message","type","rule","types","messages","appendErrors","concat","shift","schema","schemaOptions","resolverOptions","values","_","options","Promise","resolve","validate","then","data","shouldUseNativeValidation","validateFieldsNatively","errors","raw","_catch","E_VALIDATION_ERROR","toNestErrors","criteriaMode","e","reject"],"mappings":"4FAKMA,EAAmB,SACvBC,EACAC,GAIA,IAFA,IAAMC,EAA2C,CAAA,EAE1CF,EAAWG,QAAU,CAC1B,IAAMC,EAAQJ,EAAW,GACnBK,EAAOD,EAAME,MAMnB,GAJMD,KAAQH,IACZA,EAAaG,GAAQ,CAAEE,QAASH,EAAMG,QAASC,KAAMJ,EAAMK,OAGzDR,EAA0B,CAC5B,IAAQS,EAAUR,EAAaG,GAAvBK,MACFC,EAAWD,GAASA,EAAMN,EAAMK,MAEtCP,EAAaG,GAAQO,eACnBP,EACAJ,EACAC,EACAE,EAAMK,KACNE,EAAQ,GAAAE,OAAQF,EAAuBP,CAAAA,EAAMG,UAAWH,EAAMG,QAElE,CAEAP,EAAWc,OACb,CAEA,OAAOZ,CACT,uBAGE,SAACa,EAAQC,EAAeC,GACjBC,YADiBD,IAAAA,IAAAA,EAAkB,CAAE,GACrCC,SAAAA,EAAQC,EAAGC,GAAW,IAAA,OAAAC,QAAAC,gCACvBD,QAAAC,QACiBP,EAAOQ,SAASL,EAAQF,IAAcQ,KAAnDC,SAAAA,GAIN,OAFAL,EAAQM,2BAA6BC,EAAAA,uBAAuB,CAAE,EAAEP,GAEzD,CACLQ,OAAQ,GACRV,OAAQD,EAAgBY,IAAMX,EAASO,EACvC,4DATuBK,GAU1B,SAAQ1B,GACP,GAAIA,aAAiBwB,EAAMA,OAACG,mBAC1B,MAAO,CACLb,OAAQ,CAAA,EACRU,OAAQI,EAAYA,aAClBjC,EACEK,EAAMO,UACLS,EAAQM,2BACkB,QAAzBN,EAAQa,cAEZb,IAKN,MAAMhB,CACR,GACF,CAAC,MAAA8B,GAAA,OAAAb,QAAAc,OAAAD,EAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{validateFieldsNatively as e,toNestErrors as r}from"@hookform/resolvers";import{errors as t}from"@vinejs/vine";import{appendErrors as o}from"react-hook-form";var n=function(e,r){for(var t={};e.length;){var n=e[0],i=n.field;if(i in t||(t[i]={message:n.message,type:n.rule}),r){var s=t[i].types,a=s&&s[n.rule];t[i]=o(i,r,t,n.rule,a?[].concat(a,[n.message]):n.message)}e.shift()}return t},i=function(o,i,s){return void 0===s&&(s={}),function(a,u,f){try{return Promise.resolve(function(r,t){try{var n=Promise.resolve(o.validate(a,i)).then(function(r){return f.shouldUseNativeValidation&&e({},f),{errors:{},values:s.raw?a:r}})}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}(0,function(e){if(e instanceof t.E_VALIDATION_ERROR)return{values:{},errors:r(n(e.messages,!f.shouldUseNativeValidation&&"all"===f.criteriaMode),f)};throw e}))}catch(e){return Promise.reject(e)}}};export{i as vineResolver};
|
|
2
|
+
//# sourceMappingURL=vine.module.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{validateFieldsNatively as e,toNestErrors as r}from"@hookform/resolvers";import{errors as s}from"@vinejs/vine";import{appendErrors as o}from"react-hook-form";const t=(e,r)=>{const s={};for(;e.length;){const t=e[0],a=t.field;if(a in s||(s[a]={message:t.message,type:t.rule}),r){const{types:e}=s[a],i=e&&e[t.rule];s[a]=o(a,r,s,t.rule,i?[...i,t.message]:t.message)}e.shift()}return s},a=(o,a,i={})=>async(n,l,m)=>{try{const r=await o.validate(n,a);return m.shouldUseNativeValidation&&e({},m),{errors:{},values:i.raw?n:r}}catch(e){if(e instanceof s.E_VALIDATION_ERROR)return{values:{},errors:r(t(e.messages,!m.shouldUseNativeValidation&&"all"===m.criteriaMode),m)};throw e}};export{a as vineResolver};
|
|
2
|
+
//# sourceMappingURL=vine.modern.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vine.modern.mjs","sources":["../src/vine.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { SimpleErrorReporter, errors } from '@vinejs/vine';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n vineErrors: SimpleErrorReporter['errors'],\n validateAllFieldCriteria: boolean,\n) => {\n const schemaErrors: Record<string, FieldError> = {};\n\n for (; vineErrors.length; ) {\n const error = vineErrors[0];\n const path = error.field;\n\n if (!(path in schemaErrors)) {\n schemaErrors[path] = { message: error.message, type: error.rule };\n }\n\n if (validateAllFieldCriteria) {\n const { types } = schemaErrors[path];\n const messages = types && types[error.rule];\n\n schemaErrors[path] = appendErrors(\n path,\n validateAllFieldCriteria,\n schemaErrors,\n error.rule,\n messages ? [...(messages as string[]), error.message] : error.message,\n ) as FieldError;\n }\n\n vineErrors.shift();\n }\n\n return schemaErrors;\n};\n\nexport const vineResolver: Resolver =\n (schema, schemaOptions, resolverOptions = {}) =>\n async (values, _, options) => {\n try {\n const data = await schema.validate(values, schemaOptions);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : data,\n };\n } catch (error: any) {\n if (error instanceof errors.E_VALIDATION_ERROR) {\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n error.messages,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n\n throw error;\n }\n };\n"],"names":["parseErrorSchema","vineErrors","validateAllFieldCriteria","schemaErrors","length","error","path","field","message","type","rule","types","messages","appendErrors","shift","vineResolver","schema","schemaOptions","resolverOptions","async","values","_","options","data","validate","shouldUseNativeValidation","validateFieldsNatively","errors","raw","E_VALIDATION_ERROR","toNestErrors","criteriaMode"],"mappings":"oKAKA,MAAMA,EAAmBA,CACvBC,EACAC,KAEA,MAAMC,EAA2C,CAAE,EAEnD,KAAOF,EAAWG,QAAU,CAC1B,MAAMC,EAAQJ,EAAW,GACnBK,EAAOD,EAAME,MAMnB,GAJMD,KAAQH,IACZA,EAAaG,GAAQ,CAAEE,QAASH,EAAMG,QAASC,KAAMJ,EAAMK,OAGzDR,EAA0B,CAC5B,MAAMS,MAAEA,GAAUR,EAAaG,GACzBM,EAAWD,GAASA,EAAMN,EAAMK,MAEtCP,EAAaG,GAAQO,EACnBP,EACAJ,EACAC,EACAE,EAAMK,KACNE,EAAW,IAAKA,EAAuBP,EAAMG,SAAWH,EAAMG,QAElE,CAEAP,EAAWa,OACb,CAEA,OAAOX,GAGIY,EACXA,CAACC,EAAQC,EAAeC,EAAkB,CAAE,IAC5CC,MAAOC,EAAQC,EAAGC,KAChB,IACE,MAAMC,QAAaP,EAAOQ,SAASJ,EAAQH,GAI3C,OAFAK,EAAQG,2BAA6BC,EAAuB,CAAA,EAAIJ,GAEzD,CACLK,OAAQ,GACRP,OAAQF,EAAgBU,IAAMR,EAASG,EAE3C,CAAE,MAAOlB,GACP,GAAIA,aAAiBsB,EAAOE,mBAC1B,MAAO,CACLT,OAAQ,CAAA,EACRO,OAAQG,EACN9B,EACEK,EAAMO,UACLU,EAAQG,2BACkB,QAAzBH,EAAQS,cAEZT,IAKN,MAAMjB,CACR"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{validateFieldsNatively as e,toNestErrors as r}from"@hookform/resolvers";import{errors as t}from"@vinejs/vine";import{appendErrors as o}from"react-hook-form";var n=function(e,r){for(var t={};e.length;){var n=e[0],i=n.field;if(i in t||(t[i]={message:n.message,type:n.rule}),r){var s=t[i].types,a=s&&s[n.rule];t[i]=o(i,r,t,n.rule,a?[].concat(a,[n.message]):n.message)}e.shift()}return t},i=function(o,i,s){return void 0===s&&(s={}),function(a,u,f){try{return Promise.resolve(function(r,t){try{var n=Promise.resolve(o.validate(a,i)).then(function(r){return f.shouldUseNativeValidation&&e({},f),{errors:{},values:s.raw?a:r}})}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}(0,function(e){if(e instanceof t.E_VALIDATION_ERROR)return{values:{},errors:r(n(e.messages,!f.shouldUseNativeValidation&&"all"===f.criteriaMode),f)};throw e}))}catch(e){return Promise.reject(e)}}};export{i as vineResolver};
|
|
2
|
+
//# sourceMappingURL=vine.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vine.module.js","sources":["../src/vine.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { SimpleErrorReporter, errors } from '@vinejs/vine';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n vineErrors: SimpleErrorReporter['errors'],\n validateAllFieldCriteria: boolean,\n) => {\n const schemaErrors: Record<string, FieldError> = {};\n\n for (; vineErrors.length; ) {\n const error = vineErrors[0];\n const path = error.field;\n\n if (!(path in schemaErrors)) {\n schemaErrors[path] = { message: error.message, type: error.rule };\n }\n\n if (validateAllFieldCriteria) {\n const { types } = schemaErrors[path];\n const messages = types && types[error.rule];\n\n schemaErrors[path] = appendErrors(\n path,\n validateAllFieldCriteria,\n schemaErrors,\n error.rule,\n messages ? [...(messages as string[]), error.message] : error.message,\n ) as FieldError;\n }\n\n vineErrors.shift();\n }\n\n return schemaErrors;\n};\n\nexport const vineResolver: Resolver =\n (schema, schemaOptions, resolverOptions = {}) =>\n async (values, _, options) => {\n try {\n const data = await schema.validate(values, schemaOptions);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : data,\n };\n } catch (error: any) {\n if (error instanceof errors.E_VALIDATION_ERROR) {\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n error.messages,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n\n throw error;\n }\n };\n"],"names":["parseErrorSchema","vineErrors","validateAllFieldCriteria","schemaErrors","length","error","path","field","message","type","rule","types","messages","appendErrors","concat","shift","vineResolver","schema","schemaOptions","resolverOptions","values","_","options","Promise","resolve","validate","then","data","shouldUseNativeValidation","validateFieldsNatively","errors","raw","_catch","E_VALIDATION_ERROR","toNestErrors","criteriaMode","e","reject"],"mappings":"oKAKA,IAAMA,EAAmB,SACvBC,EACAC,GAIA,IAFA,IAAMC,EAA2C,CAAA,EAE1CF,EAAWG,QAAU,CAC1B,IAAMC,EAAQJ,EAAW,GACnBK,EAAOD,EAAME,MAMnB,GAJMD,KAAQH,IACZA,EAAaG,GAAQ,CAAEE,QAASH,EAAMG,QAASC,KAAMJ,EAAMK,OAGzDR,EAA0B,CAC5B,IAAQS,EAAUR,EAAaG,GAAvBK,MACFC,EAAWD,GAASA,EAAMN,EAAMK,MAEtCP,EAAaG,GAAQO,EACnBP,EACAJ,EACAC,EACAE,EAAMK,KACNE,EAAQ,GAAAE,OAAQF,EAAuBP,CAAAA,EAAMG,UAAWH,EAAMG,QAElE,CAEAP,EAAWc,OACb,CAEA,OAAOZ,CACT,EAEaa,EACX,SAACC,EAAQC,EAAeC,GACjBC,YADiBD,IAAAA,IAAAA,EAAkB,CAAE,GACrCC,SAAAA,EAAQC,EAAGC,GAAW,IAAA,OAAAC,QAAAC,gCACvBD,QAAAC,QACiBP,EAAOQ,SAASL,EAAQF,IAAcQ,KAAnDC,SAAAA,GAIN,OAFAL,EAAQM,2BAA6BC,EAAuB,CAAE,EAAEP,GAEzD,CACLQ,OAAQ,GACRV,OAAQD,EAAgBY,IAAMX,EAASO,EACvC,4DATuBK,GAU1B,SAAQ3B,GACP,GAAIA,aAAiByB,EAAOG,mBAC1B,MAAO,CACLb,OAAQ,CAAA,EACRU,OAAQI,EACNlC,EACEK,EAAMO,UACLU,EAAQM,2BACkB,QAAzBN,EAAQa,cAEZb,IAKN,MAAMjB,CACR,GACF,CAAC,MAAA+B,GAAA,OAAAb,QAAAc,OAAAD,EAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@hookform/resolvers"),require("@vinejs/vine"),require("react-hook-form")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers","@vinejs/vine","react-hook-form"],r):r((e||self).hookformResolversVine={},e.hookformResolvers,e.vine,e.ReactHookForm)}(this,function(e,r,o,t){var n=function(e,r){for(var o={};e.length;){var n=e[0],i=n.field;if(i in o||(o[i]={message:n.message,type:n.rule}),r){var s=o[i].types,a=s&&s[n.rule];o[i]=t.appendErrors(i,r,o,n.rule,a?[].concat(a,[n.message]):n.message)}e.shift()}return o};e.vineResolver=function(e,t,i){return void 0===i&&(i={}),function(s,a,f){try{return Promise.resolve(function(o,n){try{var a=Promise.resolve(e.validate(s,t)).then(function(e){return f.shouldUseNativeValidation&&r.validateFieldsNatively({},f),{errors:{},values:i.raw?s:e}})}catch(e){return n(e)}return a&&a.then?a.then(void 0,n):a}(0,function(e){if(e instanceof o.errors.E_VALIDATION_ERROR)return{values:{},errors:r.toNestErrors(n(e.messages,!f.shouldUseNativeValidation&&"all"===f.criteriaMode),f)};throw e}))}catch(e){return Promise.reject(e)}}}});
|
|
2
|
+
//# sourceMappingURL=vine.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vine.umd.js","sources":["../src/vine.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport { SimpleErrorReporter, errors } from '@vinejs/vine';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n vineErrors: SimpleErrorReporter['errors'],\n validateAllFieldCriteria: boolean,\n) => {\n const schemaErrors: Record<string, FieldError> = {};\n\n for (; vineErrors.length; ) {\n const error = vineErrors[0];\n const path = error.field;\n\n if (!(path in schemaErrors)) {\n schemaErrors[path] = { message: error.message, type: error.rule };\n }\n\n if (validateAllFieldCriteria) {\n const { types } = schemaErrors[path];\n const messages = types && types[error.rule];\n\n schemaErrors[path] = appendErrors(\n path,\n validateAllFieldCriteria,\n schemaErrors,\n error.rule,\n messages ? [...(messages as string[]), error.message] : error.message,\n ) as FieldError;\n }\n\n vineErrors.shift();\n }\n\n return schemaErrors;\n};\n\nexport const vineResolver: Resolver =\n (schema, schemaOptions, resolverOptions = {}) =>\n async (values, _, options) => {\n try {\n const data = await schema.validate(values, schemaOptions);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : data,\n };\n } catch (error: any) {\n if (error instanceof errors.E_VALIDATION_ERROR) {\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n error.messages,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n\n throw error;\n }\n };\n"],"names":["parseErrorSchema","vineErrors","validateAllFieldCriteria","schemaErrors","length","error","path","field","message","type","rule","types","messages","appendErrors","concat","shift","schema","schemaOptions","resolverOptions","values","_","options","Promise","resolve","validate","then","data","shouldUseNativeValidation","validateFieldsNatively","errors","raw","_catch","E_VALIDATION_ERROR","toNestErrors","criteriaMode","e","reject"],"mappings":"yaAKA,IAAMA,EAAmB,SACvBC,EACAC,GAIA,IAFA,IAAMC,EAA2C,CAAA,EAE1CF,EAAWG,QAAU,CAC1B,IAAMC,EAAQJ,EAAW,GACnBK,EAAOD,EAAME,MAMnB,GAJMD,KAAQH,IACZA,EAAaG,GAAQ,CAAEE,QAASH,EAAMG,QAASC,KAAMJ,EAAMK,OAGzDR,EAA0B,CAC5B,IAAQS,EAAUR,EAAaG,GAAvBK,MACFC,EAAWD,GAASA,EAAMN,EAAMK,MAEtCP,EAAaG,GAAQO,eACnBP,EACAJ,EACAC,EACAE,EAAMK,KACNE,EAAQ,GAAAE,OAAQF,EAAuBP,CAAAA,EAAMG,UAAWH,EAAMG,QAElE,CAEAP,EAAWc,OACb,CAEA,OAAOZ,CACT,iBAGE,SAACa,EAAQC,EAAeC,GACjBC,YADiBD,IAAAA,IAAAA,EAAkB,CAAE,GACrCC,SAAAA,EAAQC,EAAGC,GAAW,IAAA,OAAAC,QAAAC,gCACvBD,QAAAC,QACiBP,EAAOQ,SAASL,EAAQF,IAAcQ,KAAnDC,SAAAA,GAIN,OAFAL,EAAQM,2BAA6BC,EAAAA,uBAAuB,CAAE,EAAEP,GAEzD,CACLQ,OAAQ,GACRV,OAAQD,EAAgBY,IAAMX,EAASO,EACvC,4DATuBK,GAU1B,SAAQ1B,GACP,GAAIA,aAAiBwB,EAAMA,OAACG,mBAC1B,MAAO,CACLb,OAAQ,CAAA,EACRU,OAAQI,EAAYA,aAClBjC,EACEK,EAAMO,UACLS,EAAQM,2BACkB,QAAzBN,EAAQa,cAEZb,IAKN,MAAMhB,CACR,GACF,CAAC,MAAA8B,GAAA,OAAAb,QAAAc,OAAAD,EAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hookform/resolvers/vine",
|
|
3
|
+
"amdName": "hookformResolversVine",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"description": "React Hook Form validation resolver: vine",
|
|
7
|
+
"main": "dist/vine.js",
|
|
8
|
+
"module": "dist/vine.module.js",
|
|
9
|
+
"umd:main": "dist/vine.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
|
+
"@vinejs/vine": "^2.0.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import user from '@testing-library/user-event';
|
|
3
|
+
import vine from '@vinejs/vine';
|
|
4
|
+
import { Infer } from '@vinejs/vine/build/src/types';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { useForm } from 'react-hook-form';
|
|
7
|
+
import { vineResolver } from '..';
|
|
8
|
+
|
|
9
|
+
const schema = vine.compile(
|
|
10
|
+
vine.object({
|
|
11
|
+
username: vine.string().minLength(1),
|
|
12
|
+
password: vine.string().minLength(1),
|
|
13
|
+
}),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
type FormData = Infer<typeof schema> & { unusedProperty: string };
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
onSubmit: (data: FormData) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function TestComponent({ onSubmit }: Props) {
|
|
23
|
+
const { register, handleSubmit } = useForm<FormData>({
|
|
24
|
+
resolver: vineResolver(schema),
|
|
25
|
+
shouldUseNativeValidation: true,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
30
|
+
<input {...register('username')} placeholder="username" />
|
|
31
|
+
|
|
32
|
+
<input {...register('password')} placeholder="password" />
|
|
33
|
+
|
|
34
|
+
<button type="submit">submit</button>
|
|
35
|
+
</form>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
test("form's native validation with Zod", async () => {
|
|
40
|
+
const handleSubmit = vi.fn();
|
|
41
|
+
render(<TestComponent onSubmit={handleSubmit} />);
|
|
42
|
+
|
|
43
|
+
// username
|
|
44
|
+
let usernameField = screen.getByPlaceholderText(
|
|
45
|
+
/username/i,
|
|
46
|
+
) as HTMLInputElement;
|
|
47
|
+
expect(usernameField.validity.valid).toBe(true);
|
|
48
|
+
expect(usernameField.validationMessage).toBe('');
|
|
49
|
+
|
|
50
|
+
// password
|
|
51
|
+
let passwordField = screen.getByPlaceholderText(
|
|
52
|
+
/password/i,
|
|
53
|
+
) as HTMLInputElement;
|
|
54
|
+
expect(passwordField.validity.valid).toBe(true);
|
|
55
|
+
expect(passwordField.validationMessage).toBe('');
|
|
56
|
+
|
|
57
|
+
await user.click(screen.getByText(/submit/i));
|
|
58
|
+
|
|
59
|
+
// username
|
|
60
|
+
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
61
|
+
expect(usernameField.validity.valid).toBe(false);
|
|
62
|
+
expect(usernameField.validationMessage).toBe(
|
|
63
|
+
'The username field must have at least 1 characters',
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// password
|
|
67
|
+
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
68
|
+
expect(passwordField.validity.valid).toBe(false);
|
|
69
|
+
expect(passwordField.validationMessage).toBe(
|
|
70
|
+
'The password field must have at least 1 characters',
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
await user.type(screen.getByPlaceholderText(/username/i), 'joe');
|
|
74
|
+
await user.type(screen.getByPlaceholderText(/password/i), 'password');
|
|
75
|
+
|
|
76
|
+
// username
|
|
77
|
+
usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
|
|
78
|
+
expect(usernameField.validity.valid).toBe(true);
|
|
79
|
+
expect(usernameField.validationMessage).toBe('');
|
|
80
|
+
|
|
81
|
+
// password
|
|
82
|
+
passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
|
|
83
|
+
expect(passwordField.validity.valid).toBe(true);
|
|
84
|
+
expect(passwordField.validationMessage).toBe('');
|
|
85
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import user from '@testing-library/user-event';
|
|
3
|
+
import vine from '@vinejs/vine';
|
|
4
|
+
import { Infer } from '@vinejs/vine/build/src/types';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { useForm } from 'react-hook-form';
|
|
7
|
+
import { vineResolver } from '..';
|
|
8
|
+
|
|
9
|
+
const schema = vine.compile(
|
|
10
|
+
vine.object({
|
|
11
|
+
username: vine.string().minLength(1),
|
|
12
|
+
password: vine.string().minLength(1),
|
|
13
|
+
}),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
type FormData = Infer<typeof schema> & { unusedProperty: string };
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
onSubmit: (data: FormData) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function TestComponent({ onSubmit }: Props) {
|
|
23
|
+
const {
|
|
24
|
+
register,
|
|
25
|
+
handleSubmit,
|
|
26
|
+
formState: { errors },
|
|
27
|
+
} = useForm<FormData>({
|
|
28
|
+
resolver: vineResolver(schema), // Useful to check TypeScript regressions
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
33
|
+
<input {...register('username')} />
|
|
34
|
+
{errors.username && <span role="alert">{errors.username.message}</span>}
|
|
35
|
+
|
|
36
|
+
<input {...register('password')} />
|
|
37
|
+
{errors.password && <span role="alert">{errors.password.message}</span>}
|
|
38
|
+
|
|
39
|
+
<button type="submit">submit</button>
|
|
40
|
+
</form>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
test("form's validation with Vine and TypeScript's integration", async () => {
|
|
45
|
+
const handleSubmit = vi.fn();
|
|
46
|
+
render(<TestComponent onSubmit={handleSubmit} />);
|
|
47
|
+
|
|
48
|
+
expect(screen.queryAllByRole('alert')).toHaveLength(0);
|
|
49
|
+
|
|
50
|
+
await user.click(screen.getByText(/submit/i));
|
|
51
|
+
|
|
52
|
+
expect(
|
|
53
|
+
screen.getByText(/The username field must have at least 1 characters/i),
|
|
54
|
+
).toBeInTheDocument();
|
|
55
|
+
expect(
|
|
56
|
+
screen.getByText(/The password field must have at least 1 characters/i),
|
|
57
|
+
).toBeInTheDocument();
|
|
58
|
+
expect(handleSubmit).not.toHaveBeenCalled();
|
|
59
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import vine from '@vinejs/vine';
|
|
2
|
+
import { Infer } from '@vinejs/vine/build/src/types';
|
|
3
|
+
import { Field, InternalFieldName } from 'react-hook-form';
|
|
4
|
+
|
|
5
|
+
export const schema = vine.compile(
|
|
6
|
+
vine.object({
|
|
7
|
+
username: vine.string().regex(/^\w+$/).minLength(3).maxLength(30),
|
|
8
|
+
password: vine
|
|
9
|
+
.string()
|
|
10
|
+
.regex(new RegExp('.*[A-Z].*'))
|
|
11
|
+
.regex(new RegExp('.*[a-z].*'))
|
|
12
|
+
.regex(new RegExp('.*\\d.*'))
|
|
13
|
+
.regex(new RegExp('.*[`~<>?,./!@#$%^&*()\\-_+="\'|{}\\[\\];:\\\\].*'))
|
|
14
|
+
.minLength(8)
|
|
15
|
+
.confirmed({ confirmationField: 'repeatPassword' }),
|
|
16
|
+
repeatPassword: vine.string().sameAs('password'),
|
|
17
|
+
accessToken: vine.unionOfTypes([vine.string(), vine.number()]),
|
|
18
|
+
birthYear: vine.number().min(1900).max(2013),
|
|
19
|
+
email: vine.string().email().optional(),
|
|
20
|
+
tags: vine.array(vine.string()),
|
|
21
|
+
enabled: vine.boolean(),
|
|
22
|
+
like: vine.array(
|
|
23
|
+
vine.object({
|
|
24
|
+
id: vine.number(),
|
|
25
|
+
name: vine.string().fixedLength(4),
|
|
26
|
+
}),
|
|
27
|
+
),
|
|
28
|
+
dateStr: vine
|
|
29
|
+
.string()
|
|
30
|
+
.transform((value: string) => new Date(value).toISOString()),
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const validData: Infer<typeof schema> = {
|
|
35
|
+
username: 'Doe',
|
|
36
|
+
password: 'Password123_',
|
|
37
|
+
repeatPassword: 'Password123_',
|
|
38
|
+
birthYear: 2000,
|
|
39
|
+
email: 'john@doe.com',
|
|
40
|
+
tags: ['tag1', 'tag2'],
|
|
41
|
+
enabled: true,
|
|
42
|
+
accessToken: 'accessToken',
|
|
43
|
+
like: [
|
|
44
|
+
{
|
|
45
|
+
id: 1,
|
|
46
|
+
name: 'name',
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
dateStr: '2020-01-01T00:00:00.000Z',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const invalidData = {
|
|
53
|
+
password: '___',
|
|
54
|
+
email: '',
|
|
55
|
+
birthYear: 'birthYear',
|
|
56
|
+
like: [{ id: 'z' }],
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const fields: Record<InternalFieldName, Field['_f']> = {
|
|
60
|
+
username: {
|
|
61
|
+
ref: { name: 'username' },
|
|
62
|
+
name: 'username',
|
|
63
|
+
},
|
|
64
|
+
password: {
|
|
65
|
+
ref: { name: 'password' },
|
|
66
|
+
name: 'password',
|
|
67
|
+
},
|
|
68
|
+
email: {
|
|
69
|
+
ref: { name: 'email' },
|
|
70
|
+
name: 'email',
|
|
71
|
+
},
|
|
72
|
+
birthday: {
|
|
73
|
+
ref: { name: 'birthday' },
|
|
74
|
+
name: 'birthday',
|
|
75
|
+
},
|
|
76
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`vineResolver > should return a single error from vineResolver when validation fails 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"errors": {
|
|
6
|
+
"accessToken": {
|
|
7
|
+
"message": "Invalid value provided for accessToken field",
|
|
8
|
+
"ref": undefined,
|
|
9
|
+
"type": "unionOfTypes",
|
|
10
|
+
},
|
|
11
|
+
"birthYear": {
|
|
12
|
+
"message": "The birthYear field must be a number",
|
|
13
|
+
"ref": undefined,
|
|
14
|
+
"type": "number",
|
|
15
|
+
},
|
|
16
|
+
"dateStr": {
|
|
17
|
+
"message": "The dateStr field must be defined",
|
|
18
|
+
"ref": undefined,
|
|
19
|
+
"type": "required",
|
|
20
|
+
},
|
|
21
|
+
"email": {
|
|
22
|
+
"message": "The email field must be a valid email address",
|
|
23
|
+
"ref": {
|
|
24
|
+
"name": "email",
|
|
25
|
+
},
|
|
26
|
+
"type": "email",
|
|
27
|
+
},
|
|
28
|
+
"enabled": {
|
|
29
|
+
"message": "The enabled field must be defined",
|
|
30
|
+
"ref": undefined,
|
|
31
|
+
"type": "required",
|
|
32
|
+
},
|
|
33
|
+
"like": [
|
|
34
|
+
{
|
|
35
|
+
"id": {
|
|
36
|
+
"message": "The id field must be a number",
|
|
37
|
+
"ref": undefined,
|
|
38
|
+
"type": "number",
|
|
39
|
+
},
|
|
40
|
+
"name": {
|
|
41
|
+
"message": "The name field must be defined",
|
|
42
|
+
"ref": undefined,
|
|
43
|
+
"type": "required",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
"password": {
|
|
48
|
+
"message": "The password field format is invalid",
|
|
49
|
+
"ref": {
|
|
50
|
+
"name": "password",
|
|
51
|
+
},
|
|
52
|
+
"type": "regex",
|
|
53
|
+
},
|
|
54
|
+
"repeatPassword": {
|
|
55
|
+
"message": "The repeatPassword field must be defined",
|
|
56
|
+
"ref": undefined,
|
|
57
|
+
"type": "required",
|
|
58
|
+
},
|
|
59
|
+
"tags": {
|
|
60
|
+
"message": "The tags field must be defined",
|
|
61
|
+
"ref": undefined,
|
|
62
|
+
"type": "required",
|
|
63
|
+
},
|
|
64
|
+
"username": {
|
|
65
|
+
"message": "The username field must be defined",
|
|
66
|
+
"ref": {
|
|
67
|
+
"name": "username",
|
|
68
|
+
},
|
|
69
|
+
"type": "required",
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
"values": {},
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
exports[`vineResolver > should return all the errors from vineResolver when validation fails with \`validateAllFieldCriteria\` set to true 1`] = `
|
|
77
|
+
{
|
|
78
|
+
"errors": {
|
|
79
|
+
"accessToken": {
|
|
80
|
+
"message": "Invalid value provided for accessToken field",
|
|
81
|
+
"ref": undefined,
|
|
82
|
+
"type": "unionOfTypes",
|
|
83
|
+
"types": {
|
|
84
|
+
"unionOfTypes": "Invalid value provided for accessToken field",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
"birthYear": {
|
|
88
|
+
"message": "The birthYear field must be a number",
|
|
89
|
+
"ref": undefined,
|
|
90
|
+
"type": "number",
|
|
91
|
+
"types": {
|
|
92
|
+
"number": "The birthYear field must be a number",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
"dateStr": {
|
|
96
|
+
"message": "The dateStr field must be defined",
|
|
97
|
+
"ref": undefined,
|
|
98
|
+
"type": "required",
|
|
99
|
+
"types": {
|
|
100
|
+
"required": "The dateStr field must be defined",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
"email": {
|
|
104
|
+
"message": "The email field must be a valid email address",
|
|
105
|
+
"ref": {
|
|
106
|
+
"name": "email",
|
|
107
|
+
},
|
|
108
|
+
"type": "email",
|
|
109
|
+
"types": {
|
|
110
|
+
"email": "The email field must be a valid email address",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
"enabled": {
|
|
114
|
+
"message": "The enabled field must be defined",
|
|
115
|
+
"ref": undefined,
|
|
116
|
+
"type": "required",
|
|
117
|
+
"types": {
|
|
118
|
+
"required": "The enabled field must be defined",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
"like": [
|
|
122
|
+
{
|
|
123
|
+
"id": {
|
|
124
|
+
"message": "The id field must be a number",
|
|
125
|
+
"ref": undefined,
|
|
126
|
+
"type": "number",
|
|
127
|
+
"types": {
|
|
128
|
+
"number": "The id field must be a number",
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
"name": {
|
|
132
|
+
"message": "The name field must be defined",
|
|
133
|
+
"ref": undefined,
|
|
134
|
+
"type": "required",
|
|
135
|
+
"types": {
|
|
136
|
+
"required": "The name field must be defined",
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
"password": {
|
|
142
|
+
"message": "The password field format is invalid",
|
|
143
|
+
"ref": {
|
|
144
|
+
"name": "password",
|
|
145
|
+
},
|
|
146
|
+
"type": "regex",
|
|
147
|
+
"types": {
|
|
148
|
+
"regex": "The password field format is invalid",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
"repeatPassword": {
|
|
152
|
+
"message": "The repeatPassword field must be defined",
|
|
153
|
+
"ref": undefined,
|
|
154
|
+
"type": "required",
|
|
155
|
+
"types": {
|
|
156
|
+
"required": "The repeatPassword field must be defined",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
"tags": {
|
|
160
|
+
"message": "The tags field must be defined",
|
|
161
|
+
"ref": undefined,
|
|
162
|
+
"type": "required",
|
|
163
|
+
"types": {
|
|
164
|
+
"required": "The tags field must be defined",
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
"username": {
|
|
168
|
+
"message": "The username field must be defined",
|
|
169
|
+
"ref": {
|
|
170
|
+
"name": "username",
|
|
171
|
+
},
|
|
172
|
+
"type": "required",
|
|
173
|
+
"types": {
|
|
174
|
+
"required": "The username field must be defined",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
"values": {},
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { vineResolver } from '..';
|
|
2
|
+
import { fields, invalidData, schema, validData } from './__fixtures__/data';
|
|
3
|
+
|
|
4
|
+
const shouldUseNativeValidation = false;
|
|
5
|
+
|
|
6
|
+
describe('vineResolver', () => {
|
|
7
|
+
it('should return values from vineResolver when validation pass', async () => {
|
|
8
|
+
const schemaSpy = vi.spyOn(schema, 'validate');
|
|
9
|
+
|
|
10
|
+
const result = await vineResolver(schema)(validData, undefined, {
|
|
11
|
+
fields,
|
|
12
|
+
shouldUseNativeValidation,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
expect(schemaSpy).toHaveBeenCalledTimes(1);
|
|
16
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return a single error from vineResolver when validation fails', async () => {
|
|
20
|
+
const result = await vineResolver(schema)(invalidData, undefined, {
|
|
21
|
+
fields,
|
|
22
|
+
shouldUseNativeValidation,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(result).toMatchSnapshot();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should return all the errors from vineResolver when validation fails with `validateAllFieldCriteria` set to true', async () => {
|
|
29
|
+
const result = await vineResolver(schema)(invalidData, undefined, {
|
|
30
|
+
fields,
|
|
31
|
+
criteriaMode: 'all',
|
|
32
|
+
shouldUseNativeValidation,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(result).toMatchSnapshot();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return values from vineResolver when validation pass & raw=true', async () => {
|
|
39
|
+
const schemaSpy = vi.spyOn(schema, 'validate');
|
|
40
|
+
|
|
41
|
+
const result = await vineResolver(schema, undefined, { raw: true })(
|
|
42
|
+
validData,
|
|
43
|
+
undefined,
|
|
44
|
+
{
|
|
45
|
+
fields,
|
|
46
|
+
shouldUseNativeValidation,
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
expect(schemaSpy).toHaveBeenCalledTimes(1);
|
|
51
|
+
expect(result).toEqual({ errors: {}, values: validData });
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { VineValidator } from '@vinejs/vine';
|
|
2
|
+
import { ValidationOptions } from '@vinejs/vine/build/src/types';
|
|
3
|
+
import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
|
|
4
|
+
|
|
5
|
+
export type Resolver = <T extends VineValidator<any, any>>(
|
|
6
|
+
schema: T,
|
|
7
|
+
schemaOptions?: ValidationOptions<any>,
|
|
8
|
+
resolverOptions?: { raw?: boolean },
|
|
9
|
+
) => <TFieldValues extends FieldValues, TContext>(
|
|
10
|
+
values: TFieldValues,
|
|
11
|
+
context: TContext | undefined,
|
|
12
|
+
options: ResolverOptions<TFieldValues>,
|
|
13
|
+
) => Promise<ResolverResult<TFieldValues>>;
|
package/vine/src/vine.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';
|
|
2
|
+
import { SimpleErrorReporter, errors } from '@vinejs/vine';
|
|
3
|
+
import { FieldError, FieldErrors, appendErrors } from 'react-hook-form';
|
|
4
|
+
import type { Resolver } from './types';
|
|
5
|
+
|
|
6
|
+
const parseErrorSchema = (
|
|
7
|
+
vineErrors: SimpleErrorReporter['errors'],
|
|
8
|
+
validateAllFieldCriteria: boolean,
|
|
9
|
+
) => {
|
|
10
|
+
const schemaErrors: Record<string, FieldError> = {};
|
|
11
|
+
|
|
12
|
+
for (; vineErrors.length; ) {
|
|
13
|
+
const error = vineErrors[0];
|
|
14
|
+
const path = error.field;
|
|
15
|
+
|
|
16
|
+
if (!(path in schemaErrors)) {
|
|
17
|
+
schemaErrors[path] = { message: error.message, type: error.rule };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (validateAllFieldCriteria) {
|
|
21
|
+
const { types } = schemaErrors[path];
|
|
22
|
+
const messages = types && types[error.rule];
|
|
23
|
+
|
|
24
|
+
schemaErrors[path] = appendErrors(
|
|
25
|
+
path,
|
|
26
|
+
validateAllFieldCriteria,
|
|
27
|
+
schemaErrors,
|
|
28
|
+
error.rule,
|
|
29
|
+
messages ? [...(messages as string[]), error.message] : error.message,
|
|
30
|
+
) as FieldError;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
vineErrors.shift();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return schemaErrors;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const vineResolver: Resolver =
|
|
40
|
+
(schema, schemaOptions, resolverOptions = {}) =>
|
|
41
|
+
async (values, _, options) => {
|
|
42
|
+
try {
|
|
43
|
+
const data = await schema.validate(values, schemaOptions);
|
|
44
|
+
|
|
45
|
+
options.shouldUseNativeValidation && validateFieldsNatively({}, options);
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
errors: {} as FieldErrors,
|
|
49
|
+
values: resolverOptions.raw ? values : data,
|
|
50
|
+
};
|
|
51
|
+
} catch (error: any) {
|
|
52
|
+
if (error instanceof errors.E_VALIDATION_ERROR) {
|
|
53
|
+
return {
|
|
54
|
+
values: {},
|
|
55
|
+
errors: toNestErrors(
|
|
56
|
+
parseErrorSchema(
|
|
57
|
+
error.messages,
|
|
58
|
+
!options.shouldUseNativeValidation &&
|
|
59
|
+
options.criteriaMode === 'all',
|
|
60
|
+
),
|
|
61
|
+
options,
|
|
62
|
+
),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
};
|
package/yup/dist/yup.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as Yup from 'yup';
|
|
2
1
|
import { FieldValues, Resolver } from 'react-hook-form';
|
|
2
|
+
import * as Yup from 'yup';
|
|
3
3
|
export declare function yupResolver<TFieldValues extends FieldValues>(schema: Yup.ObjectSchema<TFieldValues> | ReturnType<typeof Yup.lazy<Yup.ObjectSchema<TFieldValues>>>, schemaOptions?: Parameters<(typeof schema)['validate']>[1], resolverOptions?: {
|
|
4
4
|
/**
|
|
5
5
|
* @default async
|
package/yup/dist/yup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yup.js","sources":["../src/yup.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"yup.js","sources":["../src/yup.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport {\n FieldError,\n FieldValues,\n Resolver,\n appendErrors,\n} from 'react-hook-form';\nimport * as Yup from 'yup';\n\n/**\n * Why `path!` ? because it could be `undefined` in some case\n * https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\n */\nconst parseErrorSchema = (\n error: Yup.ValidationError,\n validateAllFieldCriteria: boolean,\n) => {\n return (error.inner || []).reduce<Record<string, FieldError>>(\n (previous, error) => {\n if (!previous[error.path!]) {\n previous[error.path!] = { message: error.message, type: error.type! };\n }\n\n if (validateAllFieldCriteria) {\n const types = previous[error.path!].types;\n const messages = types && types[error.type!];\n\n previous[error.path!] = appendErrors(\n error.path!,\n validateAllFieldCriteria,\n previous,\n error.type!,\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n return previous;\n },\n {},\n );\n};\n\nexport function yupResolver<TFieldValues extends FieldValues>(\n schema:\n | Yup.ObjectSchema<TFieldValues>\n | ReturnType<typeof Yup.lazy<Yup.ObjectSchema<TFieldValues>>>,\n schemaOptions: Parameters<(typeof schema)['validate']>[1] = {},\n resolverOptions: {\n /**\n * @default async\n */\n mode?: 'async' | 'sync';\n /**\n * Return the raw input values rather than the parsed values.\n * @default false\n */\n raw?: boolean;\n } = {},\n): Resolver<Yup.InferType<typeof schema>> {\n return async (values, context, options) => {\n try {\n if (schemaOptions.context && process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn(\n \"You should not used the yup options context. Please, use the 'useForm' context object instead\",\n );\n }\n\n const result = await schema[\n resolverOptions.mode === 'sync' ? 'validateSync' : 'validate'\n ](\n values,\n Object.assign({ abortEarly: false }, schemaOptions, { context }),\n );\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n return {\n values: resolverOptions.raw ? values : result,\n errors: {},\n };\n } catch (e: any) {\n if (!e.inner) {\n throw e;\n }\n\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n e,\n !options.shouldUseNativeValidation &&\n options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n }\n };\n}\n"],"names":["schema","schemaOptions","resolverOptions","values","context","options","Promise","resolve","process","env","NODE_ENV","console","warn","mode","Object","assign","abortEarly","then","result","shouldUseNativeValidation","validateFieldsNatively","raw","errors","_catch","e","inner","toNestErrors","error","validateAllFieldCriteria","criteriaMode","reduce","previous","path","message","type","types","messages","appendErrors","concat","reject"],"mappings":"sFA4CgB,SACdA,EAGAC,EACAC,GAYA,YAbAD,IAAAA,IAAAA,EAA4D,CAAE,QAC9DC,IAAAA,IAAAA,EAUI,IAEUC,SAAAA,EAAQC,EAASC,GAAW,IAAA,OAAAC,QAAAC,iCAElCN,EAAcG,SAAoC,gBAAzBI,QAAQC,IAAIC,UAEvCC,QAAQC,KACN,iGAEHN,QAAAC,QAEoBP,EACM,SAAzBE,EAAgBW,KAAkB,eAAiB,YAEnDV,EACAW,OAAOC,OAAO,CAAEC,YAAY,GAASf,EAAe,CAAEG,QAAAA,MACvDa,cALKC,GASN,OAFAb,EAAQc,2BAA6BC,EAAAA,uBAAuB,CAAE,EAAEf,GAEzD,CACLF,OAAQD,EAAgBmB,IAAMlB,EAASe,EACvCI,OAAQ,CAAA,EACR,6DArBoCC,CAAA,WAsB/BC,GACP,IAAKA,EAAEC,MACL,MAAMD,EAGR,MAAO,CACLrB,OAAQ,CAAE,EACVmB,OAAQI,EAAAA,cA5EdC,EA8EUH,EA7EVI,GA8EWvB,EAAQc,2BACkB,QAAzBd,EAAQwB,cA7EZF,EAAMF,OAAS,IAAIK,OACzB,SAACC,EAAUJ,GAKT,GAJKI,EAASJ,EAAMK,QAClBD,EAASJ,EAAMK,MAAS,CAAEC,QAASN,EAAMM,QAASC,KAAMP,EAAMO,OAG5DN,EAA0B,CAC5B,IAAMO,EAAQJ,EAASJ,EAAMK,MAAOG,MAC9BC,EAAWD,GAASA,EAAMR,EAAMO,MAEtCH,EAASJ,EAAMK,MAASK,EAAAA,aACtBV,EAAMK,KACNJ,EACAG,EACAJ,EAAMO,KACNE,EACK,GAAgBE,OAAOF,EAAsBT,EAAMM,SACpDN,EAAMM,QAEd,CAEA,OAAOF,CACT,EACA,KAwDM1B,IAnFe,IACvBsB,EACAC,CAoFE,GACF,CAAC,MAAAJ,GAAA,OAAAlB,QAAAiC,OAAAf,EACH,CAAA,CAAA"}
|