@hookform/resolvers 2.0.0-beta.7 → 2.0.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.
Files changed (91) hide show
  1. package/README.md +19 -10
  2. package/dist/index.d.ts +1 -1
  3. package/dist/resolvers.js +1 -1
  4. package/dist/resolvers.js.map +1 -1
  5. package/dist/resolvers.mjs +1 -1
  6. package/dist/resolvers.modern.js +1 -1
  7. package/dist/resolvers.modern.js.map +1 -1
  8. package/dist/resolvers.module.js +1 -1
  9. package/dist/resolvers.module.js.map +1 -1
  10. package/dist/resolvers.umd.js +1 -1
  11. package/dist/resolvers.umd.js.map +1 -1
  12. package/dist/toNestError.d.ts +2 -0
  13. package/joi/dist/joi.js +1 -1
  14. package/joi/dist/joi.js.map +1 -1
  15. package/joi/dist/joi.mjs +1 -1
  16. package/joi/dist/joi.modern.js +1 -1
  17. package/joi/dist/joi.modern.js.map +1 -1
  18. package/joi/dist/joi.module.js +1 -1
  19. package/joi/dist/joi.module.js.map +1 -1
  20. package/joi/dist/joi.umd.js +1 -1
  21. package/joi/dist/joi.umd.js.map +1 -1
  22. package/joi/dist/types.d.ts +1 -1
  23. package/joi/src/__tests__/__fixtures__/data.ts +76 -0
  24. package/joi/src/__tests__/__snapshots__/joi.ts.snap +118 -0
  25. package/joi/src/__tests__/joi.ts +35 -88
  26. package/joi/src/joi.ts +47 -64
  27. package/joi/src/types.ts +1 -1
  28. package/package.json +14 -15
  29. package/superstruct/dist/superstruct.js +1 -1
  30. package/superstruct/dist/superstruct.js.map +1 -1
  31. package/superstruct/dist/superstruct.mjs +1 -1
  32. package/superstruct/dist/superstruct.modern.js +1 -1
  33. package/superstruct/dist/superstruct.modern.js.map +1 -1
  34. package/superstruct/dist/superstruct.module.js +1 -1
  35. package/superstruct/dist/superstruct.module.js.map +1 -1
  36. package/superstruct/dist/superstruct.umd.js +1 -1
  37. package/superstruct/dist/superstruct.umd.js.map +1 -1
  38. package/superstruct/dist/types.d.ts +1 -1
  39. package/superstruct/package.json +2 -1
  40. package/superstruct/src/__tests__/__fixtures__/data.ts +73 -0
  41. package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +26 -56
  42. package/superstruct/src/__tests__/superstruct.ts +6 -65
  43. package/superstruct/src/superstruct.ts +20 -53
  44. package/superstruct/src/types.ts +1 -1
  45. package/vest/dist/vest.js +1 -1
  46. package/vest/dist/vest.js.map +1 -1
  47. package/vest/dist/vest.mjs +1 -1
  48. package/vest/dist/vest.modern.js +1 -1
  49. package/vest/dist/vest.modern.js.map +1 -1
  50. package/vest/dist/vest.module.js +1 -1
  51. package/vest/dist/vest.module.js.map +1 -1
  52. package/vest/dist/vest.umd.js +1 -1
  53. package/vest/dist/vest.umd.js.map +1 -1
  54. package/vest/package.json +3 -1
  55. package/vest/src/__tests__/__fixtures__/data.ts +67 -0
  56. package/vest/src/__tests__/__snapshots__/vest.ts.snap +28 -0
  57. package/vest/src/__tests__/vest.ts +22 -95
  58. package/vest/src/types.ts +1 -1
  59. package/vest/src/vest.ts +31 -42
  60. package/yup/dist/types.d.ts +4 -3
  61. package/yup/dist/yup.js +1 -1
  62. package/yup/dist/yup.js.map +1 -1
  63. package/yup/dist/yup.mjs +1 -1
  64. package/yup/dist/yup.modern.js +1 -1
  65. package/yup/dist/yup.modern.js.map +1 -1
  66. package/yup/dist/yup.module.js +1 -1
  67. package/yup/dist/yup.module.js.map +1 -1
  68. package/yup/dist/yup.umd.js +1 -1
  69. package/yup/dist/yup.umd.js.map +1 -1
  70. package/yup/package.json +2 -1
  71. package/yup/src/__tests__/__fixtures__/data.ts +65 -0
  72. package/yup/src/__tests__/__snapshots__/yup.ts.snap +99 -13
  73. package/yup/src/__tests__/yup.ts +23 -97
  74. package/yup/src/types.ts +6 -3
  75. package/yup/src/yup.ts +30 -60
  76. package/zod/dist/types.d.ts +1 -1
  77. package/zod/dist/zod.js +1 -1
  78. package/zod/dist/zod.js.map +1 -1
  79. package/zod/dist/zod.mjs +1 -1
  80. package/zod/dist/zod.modern.js +1 -1
  81. package/zod/dist/zod.modern.js.map +1 -1
  82. package/zod/dist/zod.module.js +1 -1
  83. package/zod/dist/zod.module.js.map +1 -1
  84. package/zod/dist/zod.umd.js +1 -1
  85. package/zod/dist/zod.umd.js.map +1 -1
  86. package/zod/src/__tests__/__fixtures__/data.ts +68 -0
  87. package/zod/src/__tests__/__snapshots__/zod.ts.snap +146 -0
  88. package/zod/src/__tests__/zod.ts +19 -79
  89. package/zod/src/types.ts +1 -1
  90. package/zod/src/zod.ts +45 -50
  91. package/dist/convertArrayToPathName.d.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"zod.module.js","sources":["../src/zod.ts"],"sourcesContent":["import { appendErrors, transformToNestObject } from 'react-hook-form';\nimport * as z from 'zod';\n// @ts-expect-error maybe fixed after the first publish ?\nimport { convertArrayToPathName } from '@hookform/resolvers';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n zodError: z.ZodError,\n validateAllFieldCriteria: boolean,\n) => {\n if (zodError.isEmpty) {\n return {};\n }\n\n return zodError.errors.reduce<Record<string, any>>(\n (previous, { path, message, code: type }) => {\n const currentPath = convertArrayToPathName(path);\n\n return {\n ...previous,\n ...(path\n ? previous[currentPath] && validateAllFieldCriteria\n ? {\n [currentPath]: appendErrors(\n currentPath,\n validateAllFieldCriteria,\n previous,\n type,\n message,\n ),\n }\n : {\n [currentPath]: previous[currentPath] || {\n message,\n type,\n ...(validateAllFieldCriteria\n ? {\n types: { [type]: message || true },\n }\n : {}),\n },\n }\n : {}),\n };\n },\n {},\n );\n};\n\nexport const zodResolver: Resolver = (\n schema,\n schemaOptions,\n { mode } = { mode: 'async' },\n) => async (values, _, { criteriaMode }) => {\n try {\n const result =\n mode === 'async'\n ? await schema.parseAsync(values, schemaOptions)\n : schema.parse(values, schemaOptions);\n\n return { values: result, errors: {} };\n } catch (error) {\n return {\n values: {},\n errors: transformToNestObject(\n parseErrorSchema(error, criteriaMode === 'all'),\n ),\n };\n }\n};\n"],"names":["zodResolver","schema","schemaOptions","mode","values","_","criteriaMode","result","errors","parseAsync","parse","error","transformToNestObject","zodError","validateAllFieldCriteria","isEmpty","reduce","previous","path","message","type","code","currentPath","convertArrayToPathName","appendErrors","types"],"mappings":"sVAMA,IA2CaA,EAAwB,SACnCC,EACAC,SACEC,cAAS,CAAEA,KAAM,YAAjBA,qBACQC,EAAQC,SAAKC,IAAAA,sFAEfC,GAKN,MAAO,CAAEH,OAAQG,EAAQC,OAAQ,UAJtB,UAATL,kBAAS,UAATA,EACUF,EAAOQ,WAAWL,EAAQF,GAChCD,EAAOS,MAAMN,EAAQF,cAFhB,UAATC,EACUF,EAAOQ,WAAWL,EAAQF,GAChCD,EAAOS,MAAMN,EAAQF,4EAGpBS,GACP,MAAO,CACLP,OAAQ,GACRI,OAAQI,GAzDZC,EA0DuBF,EAzDvBG,EAyD+C,QAAjBR,EAvD1BO,EAASE,QACJ,GAGFF,EAASL,OAAOQ,OACrB,SAACC,eAAYC,IAAAA,KAAMC,IAAAA,QAAeC,IAANC,KACpBC,EAAcC,EAAuBL,GAE3C,YACKD,EACCC,EACAD,EAASK,IAAgBR,UAEpBQ,GAAcE,EACbF,EACAR,EACAG,EACAG,EACAD,cAIDG,GAAcL,EAASK,OACtBH,QAAAA,EACAC,KAAAA,GACIN,EACA,CACEW,cAAUL,GAAOD,IAAW,MAE9B,OAGV,KAGR,OAvCqB,IACvBN,EACAC,KAyCmC"}
1
+ {"version":3,"file":"zod.module.js","sources":["../src/zod.ts"],"sourcesContent":["import { appendErrors, FieldError } from 'react-hook-form';\nimport * as z from 'zod';\nimport { toNestError } from '@hookform/resolvers';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n zodErrors: z.ZodSuberror[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; zodErrors.length; ) {\n const error = zodErrors[0];\n const { code, message, path } = error;\n const _path = path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: code };\n }\n\n if ('unionErrors' in error) {\n error.unionErrors.forEach((unionError) =>\n unionError.errors.forEach((e) => zodErrors.push(e)),\n );\n }\n\n if (validateAllFieldCriteria) {\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n code,\n message,\n ) as FieldError;\n }\n\n zodErrors.shift();\n }\n\n return errors;\n};\n\nexport const zodResolver: Resolver = (\n schema,\n schemaOptions,\n resolverOptions = {},\n) => async (values, _, options) => {\n try {\n return {\n errors: {},\n values: await schema[\n resolverOptions.mode === 'sync' ? 'parse' : 'parseAsync'\n ](values, schemaOptions),\n };\n } catch (error) {\n return {\n values: {},\n errors: error.isEmpty\n ? {}\n : toNestError(\n parseErrorSchema(error.errors, options.criteriaMode === 'all'),\n options.fields,\n ),\n };\n }\n};\n"],"names":["parseErrorSchema","zodErrors","validateAllFieldCriteria","errors","length","error","code","message","_path","path","join","type","unionErrors","forEach","unionError","e","push","appendErrors","shift","zodResolver","schema","schemaOptions","resolverOptions","values","_","options","mode","isEmpty","toNestError","criteriaMode","fields"],"mappings":"iGAKA,IAAMA,EAAmB,SACvBC,EACAC,GAGA,IADA,IAAMC,EAAqC,GACpCF,EAAUG,QAAU,CACzB,IAAMC,EAAQJ,EAAU,GAChBK,EAAwBD,EAAxBC,KAAMC,EAAkBF,EAAlBE,QACRC,EAD0BH,EAATI,KACJC,KAAK,KAEnBP,EAAOK,KACVL,EAAOK,GAAS,CAAED,QAAAA,EAASI,KAAML,IAG/B,gBAAiBD,GACnBA,EAAMO,YAAYC,QAAQ,SAACC,UACzBA,EAAWX,OAAOU,QAAQ,SAACE,UAAMd,EAAUe,KAAKD,OAIhDb,IACFC,EAAOK,GAASS,EACdT,EACAN,EACAC,EACAG,EACAC,IAIJN,EAAUiB,QAGZ,OAAOf,GAGIgB,EAAwB,SACnCC,EACAC,EACAC,mBAAAA,IAAAA,EAAkB,aACRC,EAAQC,EAAGC,sEAIHL,EACa,SAAzBE,EAAgBI,KAAkB,QAAU,cAC5CH,EAAQF,qBAJZ,MAAO,CACLlB,OAAQ,GACRoB,iFAIKlB,GACP,MAAO,CACLkB,OAAQ,GACRpB,OAAQE,EAAMsB,QACV,GACAC,EACE5B,EAAiBK,EAAMF,OAAiC,QAAzBsB,EAAQI,cACvCJ,EAAQK,YAnBiB"}
@@ -1,2 +1,2 @@
1
- !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("react-hook-form"),require("@hookform/resolvers")):"function"==typeof define&&define.amd?define(["exports","react-hook-form","@hookform/resolvers"],r):r((e||self).hookformResolversZod={},e.reactHookForm,e.hookformResolvers)}(this,function(e,r,o){function t(){return(t=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var o=arguments[r];for(var t in o)Object.prototype.hasOwnProperty.call(o,t)&&(e[t]=o[t])}return e}).apply(this,arguments)}e.zodResolver=function(e,n,s){var a=(void 0===s?{mode:"async"}:s).mode;return function(s,c,i){var f=i.criteriaMode;try{return Promise.resolve(function(r,o){try{var t=function(){function r(e){return{values:e,errors:{}}}return"async"===a?Promise.resolve("async"===a?e.parseAsync(s,n):e.parse(s,n)).then(r):r("async"===a?e.parseAsync(s,n):e.parse(s,n))}()}catch(e){return o(e)}return t&&t.then?t.then(void 0,o):t}(0,function(e){return{values:{},errors:r.transformToNestObject((n=e,s="all"===f,n.isEmpty?{}:n.errors.reduce(function(e,n){var a,c,i,f=n.path,u=n.message,p=n.code,l=o.convertArrayToPathName(f);return t({},e,f?e[l]&&s?((a={})[l]=r.appendErrors(l,s,e,p,u),a):((i={})[l]=e[l]||t({message:u,type:p},s?{types:(c={},c[p]=u||!0,c)}:{}),i):{})},{})))};var n,s}))}catch(e){return Promise.reject(e)}}}});
1
+ !function(r,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react-hook-form"),require("@hookform/resolvers")):"function"==typeof define&&define.amd?define(["exports","react-hook-form","@hookform/resolvers"],e):e((r||self).hookformResolversZod={},r.reactHookForm,r.hookformResolvers)}(this,function(r,e,o){var n=function(r,o){for(var n={};r.length;){var t=r[0],s=t.code,i=t.message,f=t.path.join(".");n[f]||(n[f]={message:i,type:s}),"unionErrors"in t&&t.unionErrors.forEach(function(e){return e.errors.forEach(function(e){return r.push(e)})}),o&&(n[f]=e.appendErrors(f,o,n,s,i)),r.shift()}return n};r.zodResolver=function(r,e,t){return void 0===t&&(t={}),function(s,i,f){try{return Promise.resolve(function(o,n){try{var i=Promise.resolve(r["sync"===t.mode?"parse":"parseAsync"](s,e)).then(function(r){return{errors:{},values:r}})}catch(r){return n(r)}return i&&i.then?i.then(void 0,n):i}(0,function(r){return{values:{},errors:r.isEmpty?{}:o.toNestError(n(r.errors,"all"===f.criteriaMode),f.fields)}}))}catch(r){return Promise.reject(r)}}}});
2
2
  //# sourceMappingURL=zod.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zod.umd.js","sources":["../src/zod.ts"],"sourcesContent":["import { appendErrors, transformToNestObject } from 'react-hook-form';\nimport * as z from 'zod';\n// @ts-expect-error maybe fixed after the first publish ?\nimport { convertArrayToPathName } from '@hookform/resolvers';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n zodError: z.ZodError,\n validateAllFieldCriteria: boolean,\n) => {\n if (zodError.isEmpty) {\n return {};\n }\n\n return zodError.errors.reduce<Record<string, any>>(\n (previous, { path, message, code: type }) => {\n const currentPath = convertArrayToPathName(path);\n\n return {\n ...previous,\n ...(path\n ? previous[currentPath] && validateAllFieldCriteria\n ? {\n [currentPath]: appendErrors(\n currentPath,\n validateAllFieldCriteria,\n previous,\n type,\n message,\n ),\n }\n : {\n [currentPath]: previous[currentPath] || {\n message,\n type,\n ...(validateAllFieldCriteria\n ? {\n types: { [type]: message || true },\n }\n : {}),\n },\n }\n : {}),\n };\n },\n {},\n );\n};\n\nexport const zodResolver: Resolver = (\n schema,\n schemaOptions,\n { mode } = { mode: 'async' },\n) => async (values, _, { criteriaMode }) => {\n try {\n const result =\n mode === 'async'\n ? await schema.parseAsync(values, schemaOptions)\n : schema.parse(values, schemaOptions);\n\n return { values: result, errors: {} };\n } catch (error) {\n return {\n values: {},\n errors: transformToNestObject(\n parseErrorSchema(error, criteriaMode === 'all'),\n ),\n };\n }\n};\n"],"names":["schema","schemaOptions","mode","values","_","criteriaMode","result","errors","parseAsync","parse","error","transformToNestObject","zodError","validateAllFieldCriteria","isEmpty","reduce","previous","path","message","type","code","currentPath","convertArrayToPathName","appendErrors","types"],"mappings":"qlBAiDqC,SACnCA,EACAC,SACEC,cAAS,CAAEA,KAAM,YAAjBA,qBACQC,EAAQC,SAAKC,IAAAA,sFAEfC,GAKN,MAAO,CAAEH,OAAQG,EAAQC,OAAQ,UAJtB,UAATL,kBAAS,UAATA,EACUF,EAAOQ,WAAWL,EAAQF,GAChCD,EAAOS,MAAMN,EAAQF,cAFhB,UAATC,EACUF,EAAOQ,WAAWL,EAAQF,GAChCD,EAAOS,MAAMN,EAAQF,4EAGpBS,GACP,MAAO,CACLP,OAAQ,GACRI,OAAQI,yBAzDZC,EA0DuBF,EAzDvBG,EAyD+C,QAAjBR,EAvD1BO,EAASE,QACJ,GAGFF,EAASL,OAAOQ,OACrB,SAACC,eAAYC,IAAAA,KAAMC,IAAAA,QAAeC,IAANC,KACpBC,EAAcC,yBAAuBL,GAE3C,YACKD,EACCC,EACAD,EAASK,IAAgBR,UAEpBQ,GAAcE,eACbF,EACAR,EACAG,EACAG,EACAD,cAIDG,GAAcL,EAASK,OACtBH,QAAAA,EACAC,KAAAA,GACIN,EACA,CACEW,cAAUL,GAAOD,IAAW,MAE9B,OAGV,KAGR,OAvCqB,IACvBN,EACAC,KAyCmC"}
1
+ {"version":3,"file":"zod.umd.js","sources":["../src/zod.ts"],"sourcesContent":["import { appendErrors, FieldError } from 'react-hook-form';\nimport * as z from 'zod';\nimport { toNestError } from '@hookform/resolvers';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n zodErrors: z.ZodSuberror[],\n validateAllFieldCriteria: boolean,\n) => {\n const errors: Record<string, FieldError> = {};\n for (; zodErrors.length; ) {\n const error = zodErrors[0];\n const { code, message, path } = error;\n const _path = path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message, type: code };\n }\n\n if ('unionErrors' in error) {\n error.unionErrors.forEach((unionError) =>\n unionError.errors.forEach((e) => zodErrors.push(e)),\n );\n }\n\n if (validateAllFieldCriteria) {\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n code,\n message,\n ) as FieldError;\n }\n\n zodErrors.shift();\n }\n\n return errors;\n};\n\nexport const zodResolver: Resolver = (\n schema,\n schemaOptions,\n resolverOptions = {},\n) => async (values, _, options) => {\n try {\n return {\n errors: {},\n values: await schema[\n resolverOptions.mode === 'sync' ? 'parse' : 'parseAsync'\n ](values, schemaOptions),\n };\n } catch (error) {\n return {\n values: {},\n errors: error.isEmpty\n ? {}\n : toNestError(\n parseErrorSchema(error.errors, options.criteriaMode === 'all'),\n options.fields,\n ),\n };\n }\n};\n"],"names":["parseErrorSchema","zodErrors","validateAllFieldCriteria","errors","length","error","code","message","_path","path","join","type","unionErrors","forEach","unionError","e","push","appendErrors","shift","schema","schemaOptions","resolverOptions","values","_","options","mode","isEmpty","toNestError","criteriaMode","fields"],"mappings":"wXAKA,IAAMA,EAAmB,SACvBC,EACAC,GAGA,IADA,IAAMC,EAAqC,GACpCF,EAAUG,QAAU,CACzB,IAAMC,EAAQJ,EAAU,GAChBK,EAAwBD,EAAxBC,KAAMC,EAAkBF,EAAlBE,QACRC,EAD0BH,EAATI,KACJC,KAAK,KAEnBP,EAAOK,KACVL,EAAOK,GAAS,CAAED,QAAAA,EAASI,KAAML,IAG/B,gBAAiBD,GACnBA,EAAMO,YAAYC,QAAQ,SAACC,UACzBA,EAAWX,OAAOU,QAAQ,SAACE,UAAMd,EAAUe,KAAKD,OAIhDb,IACFC,EAAOK,GAASS,eACdT,EACAN,EACAC,EACAG,EACAC,IAIJN,EAAUiB,QAGZ,OAAOf,iBAG4B,SACnCgB,EACAC,EACAC,mBAAAA,IAAAA,EAAkB,aACRC,EAAQC,EAAGC,sEAIHL,EACa,SAAzBE,EAAgBI,KAAkB,QAAU,cAC5CH,EAAQF,qBAJZ,MAAO,CACLjB,OAAQ,GACRmB,iFAIKjB,GACP,MAAO,CACLiB,OAAQ,GACRnB,OAAQE,EAAMqB,QACV,GACAC,cACE3B,EAAiBK,EAAMF,OAAiC,QAAzBqB,EAAQI,cACvCJ,EAAQK,YAnBiB"}
@@ -0,0 +1,68 @@
1
+ import { Field, InternalFieldName } from 'react-hook-form';
2
+ import * as z from 'zod';
3
+
4
+ export const schema = z
5
+ .object({
6
+ username: z.string().regex(/^\w+$/).min(3).max(30),
7
+ password: z.string().regex(/^[a-zA-Z0-9]{3,30}/),
8
+ repeatPassword: z.string(),
9
+ accessToken: z.union([z.string(), z.number()]).optional(),
10
+ birthYear: z.number().min(1900).max(2013).optional(),
11
+ email: z.string().email().optional(),
12
+ tags: z.array(z.string()),
13
+ enabled: z.boolean(),
14
+ like: z
15
+ .array(
16
+ z.object({
17
+ id: z.number(),
18
+ name: z.string().length(4),
19
+ }),
20
+ )
21
+ .optional(),
22
+ })
23
+ .refine((data) => data.password === data.repeatPassword, {
24
+ message: "Passwords don't match",
25
+ path: ['confirm'], // set path of error
26
+ });
27
+
28
+ export const validData: z.infer<typeof schema> = {
29
+ username: 'Doe',
30
+ password: 'Password123',
31
+ repeatPassword: 'Password123',
32
+ birthYear: 2000,
33
+ email: 'john@doe.com',
34
+ tags: ['tag1', 'tag2'],
35
+ enabled: true,
36
+ like: [
37
+ {
38
+ id: 1,
39
+ name: 'name',
40
+ },
41
+ ],
42
+ };
43
+
44
+ export const invalidData = {
45
+ password: '___',
46
+ email: '',
47
+ birthYear: 'birthYear',
48
+ like: [{ id: 'z' }],
49
+ };
50
+
51
+ export const fields: Record<InternalFieldName, Field['_f']> = {
52
+ username: {
53
+ ref: { name: 'username' },
54
+ name: 'username',
55
+ },
56
+ password: {
57
+ ref: { name: 'password' },
58
+ name: 'password',
59
+ },
60
+ email: {
61
+ ref: { name: 'email' },
62
+ name: 'email',
63
+ },
64
+ birthday: {
65
+ ref: { name: 'birthday' },
66
+ name: 'birthday',
67
+ },
68
+ };
@@ -5,34 +5,65 @@ Object {
5
5
  "errors": Object {
6
6
  "birthYear": Object {
7
7
  "message": "Invalid input",
8
+ "ref": undefined,
8
9
  "type": "invalid_union",
9
10
  },
10
11
  "confirm": Object {
11
12
  "message": "Passwords don't match",
13
+ "ref": undefined,
12
14
  "type": "custom_error",
13
15
  },
14
16
  "email": Object {
15
17
  "message": "Invalid email",
18
+ "ref": Object {
19
+ "name": "email",
20
+ },
16
21
  "type": "invalid_string",
17
22
  },
18
23
  "enabled": Object {
19
24
  "message": "Required",
25
+ "ref": undefined,
20
26
  "type": "invalid_type",
21
27
  },
28
+ "like": Object {
29
+ "0": Object {
30
+ "id": Object {
31
+ "message": "Expected number, received string",
32
+ "ref": undefined,
33
+ "type": "invalid_type",
34
+ },
35
+ "name": Object {
36
+ "message": "Required",
37
+ "ref": undefined,
38
+ "type": "invalid_type",
39
+ },
40
+ },
41
+ "message": "Invalid input",
42
+ "ref": undefined,
43
+ "type": "invalid_union",
44
+ },
22
45
  "password": Object {
23
46
  "message": "Invalid",
47
+ "ref": Object {
48
+ "name": "password",
49
+ },
24
50
  "type": "invalid_string",
25
51
  },
26
52
  "repeatPassword": Object {
27
53
  "message": "Required",
54
+ "ref": undefined,
28
55
  "type": "invalid_type",
29
56
  },
30
57
  "tags": Object {
31
58
  "message": "Required",
59
+ "ref": undefined,
32
60
  "type": "invalid_type",
33
61
  },
34
62
  "username": Object {
35
63
  "message": "Required",
64
+ "ref": Object {
65
+ "name": "username",
66
+ },
36
67
  "type": "invalid_type",
37
68
  },
38
69
  },
@@ -45,34 +76,65 @@ Object {
45
76
  "errors": Object {
46
77
  "birthYear": Object {
47
78
  "message": "Invalid input",
79
+ "ref": undefined,
48
80
  "type": "invalid_union",
49
81
  },
50
82
  "confirm": Object {
51
83
  "message": "Passwords don't match",
84
+ "ref": undefined,
52
85
  "type": "custom_error",
53
86
  },
54
87
  "email": Object {
55
88
  "message": "Invalid email",
89
+ "ref": Object {
90
+ "name": "email",
91
+ },
56
92
  "type": "invalid_string",
57
93
  },
58
94
  "enabled": Object {
59
95
  "message": "Required",
96
+ "ref": undefined,
60
97
  "type": "invalid_type",
61
98
  },
99
+ "like": Object {
100
+ "0": Object {
101
+ "id": Object {
102
+ "message": "Expected number, received string",
103
+ "ref": undefined,
104
+ "type": "invalid_type",
105
+ },
106
+ "name": Object {
107
+ "message": "Required",
108
+ "ref": undefined,
109
+ "type": "invalid_type",
110
+ },
111
+ },
112
+ "message": "Invalid input",
113
+ "ref": undefined,
114
+ "type": "invalid_union",
115
+ },
62
116
  "password": Object {
63
117
  "message": "Invalid",
118
+ "ref": Object {
119
+ "name": "password",
120
+ },
64
121
  "type": "invalid_string",
65
122
  },
66
123
  "repeatPassword": Object {
67
124
  "message": "Required",
125
+ "ref": undefined,
68
126
  "type": "invalid_type",
69
127
  },
70
128
  "tags": Object {
71
129
  "message": "Required",
130
+ "ref": undefined,
72
131
  "type": "invalid_type",
73
132
  },
74
133
  "username": Object {
75
134
  "message": "Required",
135
+ "ref": Object {
136
+ "name": "username",
137
+ },
76
138
  "type": "invalid_type",
77
139
  },
78
140
  },
@@ -85,13 +147,16 @@ Object {
85
147
  "errors": Object {
86
148
  "birthYear": Object {
87
149
  "message": "Invalid input",
150
+ "ref": undefined,
88
151
  "type": "invalid_union",
89
152
  "types": Object {
153
+ "invalid_type": "Expected undefined, received string",
90
154
  "invalid_union": "Invalid input",
91
155
  },
92
156
  },
93
157
  "confirm": Object {
94
158
  "message": "Passwords don't match",
159
+ "ref": undefined,
95
160
  "type": "custom_error",
96
161
  "types": Object {
97
162
  "custom_error": "Passwords don't match",
@@ -99,6 +164,9 @@ Object {
99
164
  },
100
165
  "email": Object {
101
166
  "message": "Invalid email",
167
+ "ref": Object {
168
+ "name": "email",
169
+ },
102
170
  "type": "invalid_string",
103
171
  "types": Object {
104
172
  "invalid_string": "Invalid email",
@@ -106,13 +174,44 @@ Object {
106
174
  },
107
175
  "enabled": Object {
108
176
  "message": "Required",
177
+ "ref": undefined,
109
178
  "type": "invalid_type",
110
179
  "types": Object {
111
180
  "invalid_type": "Required",
112
181
  },
113
182
  },
183
+ "like": Object {
184
+ "0": Object {
185
+ "id": Object {
186
+ "message": "Expected number, received string",
187
+ "ref": undefined,
188
+ "type": "invalid_type",
189
+ "types": Object {
190
+ "invalid_type": "Expected number, received string",
191
+ },
192
+ },
193
+ "name": Object {
194
+ "message": "Required",
195
+ "ref": undefined,
196
+ "type": "invalid_type",
197
+ "types": Object {
198
+ "invalid_type": "Required",
199
+ },
200
+ },
201
+ },
202
+ "message": "Invalid input",
203
+ "ref": undefined,
204
+ "type": "invalid_union",
205
+ "types": Object {
206
+ "invalid_type": "Expected undefined, received array",
207
+ "invalid_union": "Invalid input",
208
+ },
209
+ },
114
210
  "password": Object {
115
211
  "message": "Invalid",
212
+ "ref": Object {
213
+ "name": "password",
214
+ },
116
215
  "type": "invalid_string",
117
216
  "types": Object {
118
217
  "invalid_string": "Invalid",
@@ -120,6 +219,7 @@ Object {
120
219
  },
121
220
  "repeatPassword": Object {
122
221
  "message": "Required",
222
+ "ref": undefined,
123
223
  "type": "invalid_type",
124
224
  "types": Object {
125
225
  "invalid_type": "Required",
@@ -127,6 +227,7 @@ Object {
127
227
  },
128
228
  "tags": Object {
129
229
  "message": "Required",
230
+ "ref": undefined,
130
231
  "type": "invalid_type",
131
232
  "types": Object {
132
233
  "invalid_type": "Required",
@@ -134,6 +235,9 @@ Object {
134
235
  },
135
236
  "username": Object {
136
237
  "message": "Required",
238
+ "ref": Object {
239
+ "name": "username",
240
+ },
137
241
  "type": "invalid_type",
138
242
  "types": Object {
139
243
  "invalid_type": "Required",
@@ -149,13 +253,16 @@ Object {
149
253
  "errors": Object {
150
254
  "birthYear": Object {
151
255
  "message": "Invalid input",
256
+ "ref": undefined,
152
257
  "type": "invalid_union",
153
258
  "types": Object {
259
+ "invalid_type": "Expected undefined, received string",
154
260
  "invalid_union": "Invalid input",
155
261
  },
156
262
  },
157
263
  "confirm": Object {
158
264
  "message": "Passwords don't match",
265
+ "ref": undefined,
159
266
  "type": "custom_error",
160
267
  "types": Object {
161
268
  "custom_error": "Passwords don't match",
@@ -163,6 +270,9 @@ Object {
163
270
  },
164
271
  "email": Object {
165
272
  "message": "Invalid email",
273
+ "ref": Object {
274
+ "name": "email",
275
+ },
166
276
  "type": "invalid_string",
167
277
  "types": Object {
168
278
  "invalid_string": "Invalid email",
@@ -170,13 +280,44 @@ Object {
170
280
  },
171
281
  "enabled": Object {
172
282
  "message": "Required",
283
+ "ref": undefined,
173
284
  "type": "invalid_type",
174
285
  "types": Object {
175
286
  "invalid_type": "Required",
176
287
  },
177
288
  },
289
+ "like": Object {
290
+ "0": Object {
291
+ "id": Object {
292
+ "message": "Expected number, received string",
293
+ "ref": undefined,
294
+ "type": "invalid_type",
295
+ "types": Object {
296
+ "invalid_type": "Expected number, received string",
297
+ },
298
+ },
299
+ "name": Object {
300
+ "message": "Required",
301
+ "ref": undefined,
302
+ "type": "invalid_type",
303
+ "types": Object {
304
+ "invalid_type": "Required",
305
+ },
306
+ },
307
+ },
308
+ "message": "Invalid input",
309
+ "ref": undefined,
310
+ "type": "invalid_union",
311
+ "types": Object {
312
+ "invalid_type": "Expected undefined, received array",
313
+ "invalid_union": "Invalid input",
314
+ },
315
+ },
178
316
  "password": Object {
179
317
  "message": "Invalid",
318
+ "ref": Object {
319
+ "name": "password",
320
+ },
180
321
  "type": "invalid_string",
181
322
  "types": Object {
182
323
  "invalid_string": "Invalid",
@@ -184,6 +325,7 @@ Object {
184
325
  },
185
326
  "repeatPassword": Object {
186
327
  "message": "Required",
328
+ "ref": undefined,
187
329
  "type": "invalid_type",
188
330
  "types": Object {
189
331
  "invalid_type": "Required",
@@ -191,6 +333,7 @@ Object {
191
333
  },
192
334
  "tags": Object {
193
335
  "message": "Required",
336
+ "ref": undefined,
194
337
  "type": "invalid_type",
195
338
  "types": Object {
196
339
  "invalid_type": "Required",
@@ -198,6 +341,9 @@ Object {
198
341
  },
199
342
  "username": Object {
200
343
  "message": "Required",
344
+ "ref": Object {
345
+ "name": "username",
346
+ },
201
347
  "type": "invalid_type",
202
348
  "types": Object {
203
349
  "invalid_type": "Required",
@@ -1,94 +1,46 @@
1
- import * as z from 'zod';
2
1
  import { zodResolver } from '..';
3
-
4
- const schema = z
5
- .object({
6
- username: z.string().regex(/^\w+$/).min(3).max(30),
7
- password: z.string().regex(/^[a-zA-Z0-9]{3,30}/),
8
- repeatPassword: z.string(),
9
- accessToken: z.union([z.string(), z.number()]).optional(),
10
- birthYear: z.number().min(1900).max(2013).optional(),
11
- email: z.string().email().optional(),
12
- tags: z.array(z.string()),
13
- enabled: z.boolean(),
14
- })
15
- .refine((data) => data.password === data.repeatPassword, {
16
- message: "Passwords don't match",
17
- path: ['confirm'], // set path of error
18
- });
2
+ import { schema, validData, invalidData, fields } from './__fixtures__/data';
19
3
 
20
4
  describe('zodResolver', () => {
21
5
  it('should return values from zodResolver when validation pass', async () => {
22
- const data: z.infer<typeof schema> = {
23
- username: 'Doe',
24
- password: 'Password123',
25
- repeatPassword: 'Password123',
26
- birthYear: 2000,
27
- email: 'john@doe.com',
28
- tags: ['tag1', 'tag2'],
29
- enabled: true,
30
- };
31
-
32
6
  const parseAsyncSpy = jest.spyOn(schema, 'parseAsync');
33
7
 
34
- const result = await zodResolver(schema)(data, undefined, { fields: {} });
8
+ const result = await zodResolver(schema)(validData, undefined, {
9
+ fields,
10
+ });
35
11
 
36
12
  expect(parseAsyncSpy).toHaveBeenCalledTimes(1);
37
- expect(result).toEqual({ errors: {}, values: data });
13
+ expect(result).toEqual({ errors: {}, values: validData });
38
14
  });
39
15
 
40
16
  it('should return values from zodResolver with `mode: sync` when validation pass', async () => {
41
- const data: z.infer<typeof schema> = {
42
- username: 'Doe',
43
- password: 'Password123',
44
- repeatPassword: 'Password123',
45
- birthYear: 2000,
46
- email: 'john@doe.com',
47
- tags: ['tag1', 'tag2'],
48
- enabled: true,
49
- };
50
-
51
17
  const parseSpy = jest.spyOn(schema, 'parse');
52
18
  const parseAsyncSpy = jest.spyOn(schema, 'parseAsync');
53
19
 
54
- const result = await zodResolver(schema, undefined, { mode: 'sync' })(
55
- data,
56
- undefined,
57
- { fields: {} },
58
- );
20
+ const result = await zodResolver(schema, undefined, {
21
+ mode: 'sync',
22
+ })(validData, undefined, { fields });
59
23
 
60
24
  expect(parseSpy).toHaveBeenCalledTimes(1);
61
25
  expect(parseAsyncSpy).not.toHaveBeenCalled();
62
- expect(result).toEqual({ errors: {}, values: data });
26
+ expect(result).toEqual({ errors: {}, values: validData });
63
27
  });
64
28
 
65
29
  it('should return a single error from zodResolver when validation fails', async () => {
66
- const data = {
67
- password: '___',
68
- email: '',
69
- birthYear: 'birthYear',
70
- };
71
-
72
- const result = await zodResolver(schema)(data, undefined, { fields: {} });
30
+ const result = await zodResolver(schema)(invalidData, undefined, {
31
+ fields,
32
+ });
73
33
 
74
34
  expect(result).toMatchSnapshot();
75
35
  });
76
36
 
77
37
  it('should return a single error from zodResolver with `mode: sync` when validation fails', async () => {
78
- const data = {
79
- password: '___',
80
- email: '',
81
- birthYear: 'birthYear',
82
- };
83
-
84
38
  const parseSpy = jest.spyOn(schema, 'parse');
85
39
  const parseAsyncSpy = jest.spyOn(schema, 'parseAsync');
86
40
 
87
- const result = await zodResolver(schema, undefined, { mode: 'sync' })(
88
- data,
89
- undefined,
90
- { fields: {} },
91
- );
41
+ const result = await zodResolver(schema, undefined, {
42
+ mode: 'sync',
43
+ })(invalidData, undefined, { fields });
92
44
 
93
45
  expect(parseSpy).toHaveBeenCalledTimes(1);
94
46
  expect(parseAsyncSpy).not.toHaveBeenCalled();
@@ -96,14 +48,8 @@ describe('zodResolver', () => {
96
48
  });
97
49
 
98
50
  it('should return all the errors from zodResolver when validation fails with `validateAllFieldCriteria` set to true', async () => {
99
- const data = {
100
- password: '___',
101
- email: '',
102
- birthYear: 'birthYear',
103
- };
104
-
105
- const result = await zodResolver(schema)(data, undefined, {
106
- fields: {},
51
+ const result = await zodResolver(schema)(invalidData, undefined, {
52
+ fields,
107
53
  criteriaMode: 'all',
108
54
  });
109
55
 
@@ -111,17 +57,11 @@ describe('zodResolver', () => {
111
57
  });
112
58
 
113
59
  it('should return all the errors from zodResolver when validation fails with `validateAllFieldCriteria` set to true and `mode: sync`', async () => {
114
- const data = {
115
- password: '___',
116
- email: '',
117
- birthYear: 'birthYear',
118
- };
119
-
120
60
  const result = await zodResolver(schema, undefined, { mode: 'sync' })(
121
- data,
61
+ invalidData,
122
62
  undefined,
123
63
  {
124
- fields: {},
64
+ fields,
125
65
  criteriaMode: 'all',
126
66
  },
127
67
  );
package/zod/src/types.ts CHANGED
@@ -10,7 +10,7 @@ import type { ParseParams } from 'zod/lib/src/parser';
10
10
  export type Resolver = <T extends z.ZodSchema<any, any>>(
11
11
  schema: T,
12
12
  schemaOptions?: ParseParams,
13
- factoryOptions?: { mode: 'async' | 'sync' },
13
+ factoryOptions?: { mode?: 'async' | 'sync' },
14
14
  ) => <TFieldValues extends FieldValues, TContext>(
15
15
  values: UnpackNestedValue<TFieldValues>,
16
16
  context: TContext | undefined,