@hookform/resolvers 3.7.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.
Files changed (252) hide show
  1. package/README.md +69 -0
  2. package/ajv/dist/ajv.js.map +1 -1
  3. package/ajv/dist/ajv.modern.mjs.map +1 -1
  4. package/ajv/dist/ajv.module.js.map +1 -1
  5. package/ajv/dist/ajv.umd.js.map +1 -1
  6. package/ajv/dist/types.d.ts +1 -1
  7. package/ajv/src/__tests__/ajv.ts +7 -1
  8. package/ajv/src/ajv.ts +1 -1
  9. package/ajv/src/types.ts +1 -5
  10. package/arktype/dist/arktype.js +1 -1
  11. package/arktype/dist/arktype.js.map +1 -1
  12. package/arktype/dist/arktype.mjs +1 -1
  13. package/arktype/dist/arktype.modern.mjs +1 -1
  14. package/arktype/dist/arktype.modern.mjs.map +1 -1
  15. package/arktype/dist/arktype.module.js +1 -1
  16. package/arktype/dist/arktype.module.js.map +1 -1
  17. package/arktype/dist/arktype.umd.js +1 -1
  18. package/arktype/dist/arktype.umd.js.map +1 -1
  19. package/arktype/dist/types.d.ts +1 -1
  20. package/arktype/package.json +2 -1
  21. package/arktype/src/__tests__/Form-native-validation.tsx +5 -5
  22. package/arktype/src/__tests__/Form.tsx +2 -2
  23. package/arktype/src/__tests__/__fixtures__/data.ts +1 -1
  24. package/arktype/src/__tests__/__snapshots__/arktype.ts.snap +29 -29
  25. package/arktype/src/__tests__/arktype.ts +1 -1
  26. package/arktype/src/arktype.ts +2 -2
  27. package/arktype/src/types.ts +1 -1
  28. package/class-validator/dist/class-validator.js.map +1 -1
  29. package/class-validator/dist/class-validator.modern.mjs.map +1 -1
  30. package/class-validator/dist/class-validator.module.js.map +1 -1
  31. package/class-validator/dist/class-validator.umd.js.map +1 -1
  32. package/class-validator/dist/types.d.ts +2 -2
  33. package/class-validator/src/__tests__/Form-native-validation.tsx +2 -2
  34. package/class-validator/src/__tests__/Form.tsx +2 -2
  35. package/class-validator/src/__tests__/__snapshots__/class-validator.ts.snap +2 -2
  36. package/class-validator/src/__tests__/class-validator.ts +4 -4
  37. package/class-validator/src/class-validator.ts +2 -2
  38. package/class-validator/src/types.ts +2 -2
  39. package/computed-types/dist/computed-types.js.map +1 -1
  40. package/computed-types/dist/computed-types.modern.mjs.map +1 -1
  41. package/computed-types/dist/computed-types.module.js.map +1 -1
  42. package/computed-types/dist/computed-types.umd.js.map +1 -1
  43. package/computed-types/dist/types.d.ts +1 -1
  44. package/computed-types/src/__tests__/Form-native-validation.tsx +2 -2
  45. package/computed-types/src/__tests__/Form.tsx +2 -2
  46. package/computed-types/src/__tests__/__fixtures__/data.ts +1 -1
  47. package/computed-types/src/__tests__/__snapshots__/computed-types.ts.snap +6 -6
  48. package/computed-types/src/__tests__/computed-types.ts +1 -1
  49. package/computed-types/src/computed-types.ts +2 -2
  50. package/computed-types/src/types.ts +1 -1
  51. package/dist/resolvers.js +1 -1
  52. package/dist/resolvers.js.map +1 -1
  53. package/dist/resolvers.mjs +1 -1
  54. package/dist/resolvers.mjs.map +1 -1
  55. package/dist/resolvers.module.js +1 -1
  56. package/dist/resolvers.module.js.map +1 -1
  57. package/dist/resolvers.umd.js +1 -1
  58. package/dist/resolvers.umd.js.map +1 -1
  59. package/dist/toNestErrors.d.ts +1 -6
  60. package/dist/validateFieldsNatively.d.ts +1 -1
  61. package/effect-ts/dist/effect-ts.js +1 -1
  62. package/effect-ts/dist/effect-ts.js.map +1 -1
  63. package/effect-ts/dist/effect-ts.mjs +1 -1
  64. package/effect-ts/dist/effect-ts.modern.mjs +1 -1
  65. package/effect-ts/dist/effect-ts.modern.mjs.map +1 -1
  66. package/effect-ts/dist/effect-ts.module.js +1 -1
  67. package/effect-ts/dist/effect-ts.module.js.map +1 -1
  68. package/effect-ts/dist/effect-ts.umd.js +1 -1
  69. package/effect-ts/dist/effect-ts.umd.js.map +1 -1
  70. package/effect-ts/src/__tests__/Form-native-validation.tsx +2 -2
  71. package/effect-ts/src/__tests__/Form.tsx +2 -2
  72. package/effect-ts/src/__tests__/__snapshots__/effect-ts.ts.snap +2 -2
  73. package/effect-ts/src/__tests__/effect-ts.ts +1 -1
  74. package/effect-ts/src/effect-ts.ts +1 -1
  75. package/io-ts/dist/errorsToRecord.d.ts +0 -1
  76. package/io-ts/dist/io-ts.js +1 -1
  77. package/io-ts/dist/io-ts.js.map +1 -1
  78. package/io-ts/dist/io-ts.mjs +1 -1
  79. package/io-ts/dist/io-ts.modern.mjs +1 -1
  80. package/io-ts/dist/io-ts.modern.mjs.map +1 -1
  81. package/io-ts/dist/io-ts.module.js +1 -1
  82. package/io-ts/dist/io-ts.module.js.map +1 -1
  83. package/io-ts/dist/io-ts.umd.js +1 -1
  84. package/io-ts/dist/io-ts.umd.js.map +1 -1
  85. package/io-ts/src/__tests__/Form-native-validation.tsx +2 -2
  86. package/io-ts/src/__tests__/Form.tsx +2 -2
  87. package/io-ts/src/__tests__/__snapshots__/io-ts.ts.snap +9 -9
  88. package/io-ts/src/__tests__/errorsToRecord.ts +29 -19
  89. package/io-ts/src/__tests__/io-ts.ts +1 -1
  90. package/io-ts/src/errorsToRecord.ts +19 -10
  91. package/io-ts/src/io-ts.ts +1 -1
  92. package/joi/dist/joi.js +1 -1
  93. package/joi/dist/joi.js.map +1 -1
  94. package/joi/dist/joi.mjs +1 -1
  95. package/joi/dist/joi.modern.mjs +1 -1
  96. package/joi/dist/joi.modern.mjs.map +1 -1
  97. package/joi/dist/joi.module.js +1 -1
  98. package/joi/dist/joi.module.js.map +1 -1
  99. package/joi/dist/joi.umd.js +1 -1
  100. package/joi/dist/joi.umd.js.map +1 -1
  101. package/joi/dist/types.d.ts +1 -1
  102. package/joi/src/__tests__/Form-native-validation.tsx +2 -2
  103. package/joi/src/__tests__/Form.tsx +2 -2
  104. package/joi/src/__tests__/__snapshots__/joi.ts.snap +56 -56
  105. package/joi/src/__tests__/joi.ts +1 -1
  106. package/joi/src/joi.ts +1 -1
  107. package/joi/src/types.ts +1 -5
  108. package/nope/dist/nope.js.map +1 -1
  109. package/nope/dist/nope.modern.mjs.map +1 -1
  110. package/nope/dist/nope.module.js.map +1 -1
  111. package/nope/dist/nope.umd.js.map +1 -1
  112. package/nope/dist/types.d.ts +1 -1
  113. package/nope/src/__tests__/Form-native-validation.tsx +2 -2
  114. package/nope/src/__tests__/Form.tsx +2 -2
  115. package/nope/src/__tests__/__fixtures__/data.ts +1 -1
  116. package/nope/src/__tests__/nope.ts +1 -1
  117. package/nope/src/nope.ts +1 -1
  118. package/nope/src/types.ts +2 -2
  119. package/package.json +54 -51
  120. package/superstruct/dist/superstruct.js.map +1 -1
  121. package/superstruct/dist/superstruct.modern.mjs.map +1 -1
  122. package/superstruct/dist/superstruct.module.js.map +1 -1
  123. package/superstruct/dist/superstruct.umd.js.map +1 -1
  124. package/superstruct/dist/types.d.ts +1 -1
  125. package/superstruct/src/__tests__/Form-native-validation.tsx +2 -2
  126. package/superstruct/src/__tests__/Form.tsx +2 -2
  127. package/superstruct/src/__tests__/__fixtures__/data.ts +8 -8
  128. package/superstruct/src/__tests__/__snapshots__/superstruct.ts.snap +4 -4
  129. package/superstruct/src/__tests__/superstruct.ts +1 -1
  130. package/superstruct/src/superstruct.ts +1 -1
  131. package/superstruct/src/types.ts +1 -1
  132. package/typanion/dist/typanion.js.map +1 -1
  133. package/typanion/dist/typanion.modern.mjs.map +1 -1
  134. package/typanion/dist/typanion.module.js.map +1 -1
  135. package/typanion/dist/typanion.umd.js.map +1 -1
  136. package/typanion/dist/types.d.ts +1 -1
  137. package/typanion/src/__tests__/Form-native-validation.tsx +1 -1
  138. package/typanion/src/__tests__/Form.tsx +1 -1
  139. package/typanion/src/__tests__/__fixtures__/data.ts +12 -7
  140. package/typanion/src/__tests__/__snapshots__/typanion.ts.snap +4 -4
  141. package/typanion/src/__tests__/typanion.ts +1 -1
  142. package/typanion/src/typanion.ts +1 -1
  143. package/typanion/src/types.ts +4 -4
  144. package/typebox/dist/typebox.js +1 -1
  145. package/typebox/dist/typebox.js.map +1 -1
  146. package/typebox/dist/typebox.mjs +1 -1
  147. package/typebox/dist/typebox.modern.mjs +1 -1
  148. package/typebox/dist/typebox.modern.mjs.map +1 -1
  149. package/typebox/dist/typebox.module.js +1 -1
  150. package/typebox/dist/typebox.module.js.map +1 -1
  151. package/typebox/dist/typebox.umd.js +1 -1
  152. package/typebox/dist/typebox.umd.js.map +1 -1
  153. package/typebox/dist/types.d.ts +3 -2
  154. package/typebox/src/__tests__/Form-compiler.tsx +57 -0
  155. package/typebox/src/__tests__/Form-native-validation-compiler.tsx +86 -0
  156. package/typebox/src/__tests__/Form-native-validation.tsx +4 -4
  157. package/typebox/src/__tests__/Form.tsx +3 -3
  158. package/typebox/src/__tests__/__fixtures__/data.ts +6 -2
  159. package/typebox/src/__tests__/__snapshots__/typebox-compiler.ts.snap +188 -0
  160. package/typebox/src/__tests__/__snapshots__/typebox.ts.snap +13 -13
  161. package/typebox/src/__tests__/typebox-compiler.ts +37 -0
  162. package/typebox/src/__tests__/typebox.ts +1 -1
  163. package/typebox/src/typebox.ts +8 -3
  164. package/typebox/src/types.ts +3 -2
  165. package/typeschema/dist/index.d.ts +2 -0
  166. package/typeschema/dist/types.d.ts +9 -0
  167. package/typeschema/dist/typeschema.d.ts +2 -0
  168. package/typeschema/dist/typeschema.js +2 -0
  169. package/typeschema/dist/typeschema.js.map +1 -0
  170. package/typeschema/dist/typeschema.mjs +2 -0
  171. package/typeschema/dist/typeschema.modern.mjs +2 -0
  172. package/typeschema/dist/typeschema.modern.mjs.map +1 -0
  173. package/typeschema/dist/typeschema.module.js +2 -0
  174. package/typeschema/dist/typeschema.module.js.map +1 -0
  175. package/typeschema/dist/typeschema.umd.js +2 -0
  176. package/typeschema/dist/typeschema.umd.js.map +1 -0
  177. package/typeschema/package.json +18 -0
  178. package/typeschema/src/__tests__/Form-native-validation.tsx +82 -0
  179. package/typeschema/src/__tests__/Form.tsx +53 -0
  180. package/typeschema/src/__tests__/__fixtures__/data.ts +88 -0
  181. package/typeschema/src/__tests__/__snapshots__/typeschema.ts.snap +225 -0
  182. package/typeschema/src/__tests__/typeschema.ts +70 -0
  183. package/typeschema/src/index.ts +2 -0
  184. package/typeschema/src/types.ts +18 -0
  185. package/typeschema/src/typeschema.ts +70 -0
  186. package/valibot/dist/types.d.ts +1 -1
  187. package/valibot/dist/valibot.js +1 -1
  188. package/valibot/dist/valibot.js.map +1 -1
  189. package/valibot/dist/valibot.mjs +1 -1
  190. package/valibot/dist/valibot.modern.mjs +1 -1
  191. package/valibot/dist/valibot.modern.mjs.map +1 -1
  192. package/valibot/dist/valibot.module.js +1 -1
  193. package/valibot/dist/valibot.module.js.map +1 -1
  194. package/valibot/dist/valibot.umd.js +1 -1
  195. package/valibot/dist/valibot.umd.js.map +1 -1
  196. package/valibot/src/__tests__/Form-native-validation.tsx +2 -2
  197. package/valibot/src/__tests__/Form.tsx +1 -1
  198. package/valibot/src/__tests__/valibot.ts +4 -4
  199. package/valibot/src/types.ts +1 -1
  200. package/valibot/src/valibot.ts +12 -6
  201. package/vest/dist/types.d.ts +2 -2
  202. package/vest/dist/vest.js.map +1 -1
  203. package/vest/dist/vest.modern.mjs.map +1 -1
  204. package/vest/dist/vest.module.js.map +1 -1
  205. package/vest/dist/vest.umd.js.map +1 -1
  206. package/vest/src/__tests__/Form-native-validation.tsx +1 -1
  207. package/vest/src/__tests__/Form.tsx +1 -1
  208. package/vest/src/__tests__/__snapshots__/vest.ts.snap +0 -6
  209. package/vest/src/__tests__/vest.ts +14 -8
  210. package/vest/src/types.ts +11 -4
  211. package/vest/src/vest.ts +1 -1
  212. package/vine/dist/types.d.ts +1 -1
  213. package/vine/dist/vine.js +1 -1
  214. package/vine/dist/vine.js.map +1 -1
  215. package/vine/dist/vine.mjs +1 -1
  216. package/vine/dist/vine.modern.mjs +1 -1
  217. package/vine/dist/vine.modern.mjs.map +1 -1
  218. package/vine/dist/vine.module.js +1 -1
  219. package/vine/dist/vine.module.js.map +1 -1
  220. package/vine/dist/vine.umd.js +1 -1
  221. package/vine/dist/vine.umd.js.map +1 -1
  222. package/vine/src/__tests__/Form-native-validation.tsx +9 -5
  223. package/vine/src/__tests__/Form.tsx +9 -5
  224. package/vine/src/__tests__/__fixtures__/data.ts +4 -2
  225. package/vine/src/__tests__/vine.ts +1 -1
  226. package/vine/src/types.ts +1 -1
  227. package/vine/src/vine.ts +10 -8
  228. package/yup/dist/yup.d.ts +1 -1
  229. package/yup/dist/yup.js.map +1 -1
  230. package/yup/dist/yup.modern.mjs.map +1 -1
  231. package/yup/dist/yup.module.js.map +1 -1
  232. package/yup/dist/yup.umd.js.map +1 -1
  233. package/yup/src/__tests__/Form-native-validation.tsx +1 -1
  234. package/yup/src/__tests__/Form.tsx +1 -1
  235. package/yup/src/__tests__/__snapshots__/yup.ts.snap +13 -13
  236. package/yup/src/__tests__/yup.ts +9 -7
  237. package/yup/src/yup.ts +2 -2
  238. package/zod/dist/types.d.ts +1 -1
  239. package/zod/dist/zod.js +1 -1
  240. package/zod/dist/zod.js.map +1 -1
  241. package/zod/dist/zod.mjs +1 -1
  242. package/zod/dist/zod.modern.mjs +1 -1
  243. package/zod/dist/zod.modern.mjs.map +1 -1
  244. package/zod/dist/zod.module.js +1 -1
  245. package/zod/dist/zod.module.js.map +1 -1
  246. package/zod/dist/zod.umd.js +1 -1
  247. package/zod/dist/zod.umd.js.map +1 -1
  248. package/zod/src/__tests__/Form-native-validation.tsx +2 -2
  249. package/zod/src/__tests__/Form.tsx +1 -1
  250. package/zod/src/__tests__/zod.ts +1 -1
  251. package/zod/src/types.ts +1 -1
  252. package/zod/src/zod.ts +4 -3
@@ -1,8 +1,9 @@
1
1
  import { Type } from '@sinclair/typebox';
2
- import { FieldValues, ResolverResult, ResolverOptions } from 'react-hook-form';
2
+ import type { TypeCheck } from '@sinclair/typebox/compiler';
3
+ import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
3
4
 
4
5
  export type Resolver = <T extends ReturnType<typeof Type.Object>>(
5
- schema: T,
6
+ schema: T | TypeCheck<T>,
6
7
  ) => <TFieldValues extends FieldValues, TContext>(
7
8
  values: TFieldValues,
8
9
  context: TContext | undefined,
@@ -0,0 +1,2 @@
1
+ export * from './typeschema';
2
+ export * from './types';
@@ -0,0 +1,9 @@
1
+ import type { Schema } from '@typeschema/main';
2
+ import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
3
+ export type Resolver = <T extends Schema>(schema: T, schemaOptions?: never, factoryOptions?: {
4
+ /**
5
+ * Return the raw input values rather than the parsed values.
6
+ * @default false
7
+ */
8
+ raw?: boolean;
9
+ }) => <TFieldValues extends FieldValues, TContext>(values: TFieldValues, context: TContext | undefined, options: ResolverOptions<TFieldValues>) => Promise<ResolverResult<TFieldValues>>;
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from './types';
2
+ export declare const typeschemaResolver: Resolver;
@@ -0,0 +1,2 @@
1
+ var e=require("@hookform/resolvers"),r=require("@typeschema/main"),s=require("react-hook-form"),a=function(e,r){for(var a={};e.length;){var t=e[0];if(t.path){var o=t.path.join(".");if(a[o]||(a[o]={message:t.message,type:""}),r){var i=a[o].types,n=i&&i[""];a[o]=s.appendErrors(o,r,a,"",n?[].concat(n,t.message):t.message)}e.shift()}}return a};exports.typeschemaResolver=function(s,t,o){return void 0===o&&(o={}),function(t,i,n){try{return Promise.resolve(r.validate(s,t)).then(function(r){return n.shouldUseNativeValidation&&e.validateFieldsNatively({},n),r.success?{errors:{},values:o.raw?t:r.data}:{values:{},errors:e.toNestErrors(a(r.issues,!n.shouldUseNativeValidation&&"all"===n.criteriaMode),n)}})}catch(e){return Promise.reject(e)}}};
2
+ //# sourceMappingURL=typeschema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeschema.js","sources":["../src/typeschema.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport type { ValidationIssue } from '@typeschema/core';\nimport { validate } from '@typeschema/main';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n typeschemaErrors: ValidationIssue[],\n validateAllFieldCriteria: boolean,\n): FieldErrors => {\n const errors: Record<string, FieldError> = {};\n\n for (; typeschemaErrors.length; ) {\n const error = typeschemaErrors[0];\n\n if (!error.path) {\n continue;\n }\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: '' };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types[''];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '',\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n typeschemaErrors.shift();\n }\n\n return errors;\n};\n\nexport const typeschemaResolver: Resolver =\n (schema, _, resolverOptions = {}) =>\n async (values, _, options) => {\n const result = await validate(schema, values);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (result.success) {\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : (result.data as any),\n };\n }\n\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n result.issues,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","typeschemaErrors","validateAllFieldCriteria","errors","length","error","path","_path","join","message","type","types","messages","appendErrors","concat","shift","schema","_","resolverOptions","values","options","Promise","resolve","validate","then","result","shouldUseNativeValidation","validateFieldsNatively","success","raw","data","toNestErrors","issues","criteriaMode","e","reject"],"mappings":"gGAMMA,EAAmB,SACvBC,EACAC,GAIA,IAFA,IAAMC,EAAqC,CAAE,EAEtCF,EAAiBG,QAAU,CAChC,IAAMC,EAAQJ,EAAiB,GAE/B,GAAKI,EAAMC,KAAX,CAGA,IAAMC,EAAQF,EAAMC,KAAKE,KAAK,KAM9B,GAJKL,EAAOI,KACVJ,EAAOI,GAAS,CAAEE,QAASJ,EAAMI,QAASC,KAAM,KAG9CR,EAA0B,CAC5B,IAAMS,EAAQR,EAAOI,GAAOI,MACtBC,EAAWD,GAASA,EAAM,IAEhCR,EAAOI,GAASM,EAAYA,aAC1BN,EACAL,EACAC,EACA,GACAS,EACK,GAAgBE,OAAOF,EAAsBP,EAAMI,SACpDJ,EAAMI,QAEd,CAEAR,EAAiBc,OAtBjB,CAuBF,CAEA,OAAOZ,CACT,6BAGE,SAACa,EAAQC,EAAGC,GACLC,YADKD,IAAAA,IAAAA,EAAkB,CAAA,GACvBC,SAAAA,EAAQF,EAAGG,OAAWC,OAAAA,QAAAC,QACNC,EAAQA,SAACP,EAAQG,IAAOK,cAAvCC,GAEmE,OAAzEL,EAAQM,2BAA6BC,EAAsBA,uBAAC,CAAE,EAAEP,GAE5DK,EAAOG,QACF,CACLzB,OAAQ,CAAiB,EACzBgB,OAAQD,EAAgBW,IAAMV,EAAUM,EAAOK,MAI5C,CACLX,OAAQ,CAAE,EACVhB,OAAQ4B,EAAYA,aAClB/B,EACEyB,EAAOO,QACNZ,EAAQM,2BAAsD,QAAzBN,EAAQa,cAEhDb,GAEH,EACH,CAAC,MAAAc,GAAAb,OAAAA,QAAAc,OAAAD,EAAA,CAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ import{validateFieldsNatively as r,toNestErrors as e}from"@hookform/resolvers";import{validate as o}from"@typeschema/main";import{appendErrors as t}from"react-hook-form";var s=function(r,e){for(var o={};r.length;){var s=r[0];if(s.path){var a=s.path.join(".");if(o[a]||(o[a]={message:s.message,type:""}),e){var i=o[a].types,n=i&&i[""];o[a]=t(a,e,o,"",n?[].concat(n,s.message):s.message)}r.shift()}}return o},a=function(t,a,i){return void 0===i&&(i={}),function(a,n,m){try{return Promise.resolve(o(t,a)).then(function(o){return m.shouldUseNativeValidation&&r({},m),o.success?{errors:{},values:i.raw?a:o.data}:{values:{},errors:e(s(o.issues,!m.shouldUseNativeValidation&&"all"===m.criteriaMode),m)}})}catch(r){return Promise.reject(r)}}};export{a as typeschemaResolver};
2
+ //# sourceMappingURL=typeschema.module.js.map
@@ -0,0 +1,2 @@
1
+ import{validateFieldsNatively as s,toNestErrors as e}from"@hookform/resolvers";import{validate as o}from"@typeschema/main";import{appendErrors as t}from"react-hook-form";const a=(s,e)=>{const o={};for(;s.length;){const a=s[0];if(!a.path)continue;const r=a.path.join(".");if(o[r]||(o[r]={message:a.message,type:""}),e){const s=o[r].types,i=s&&s[""];o[r]=t(r,e,o,"",i?[].concat(i,a.message):a.message)}s.shift()}return o},r=(t,r,i={})=>async(r,n,c)=>{const m=await o(t,r);return c.shouldUseNativeValidation&&s({},c),m.success?{errors:{},values:i.raw?r:m.data}:{values:{},errors:e(a(m.issues,!c.shouldUseNativeValidation&&"all"===c.criteriaMode),c)}};export{r as typeschemaResolver};
2
+ //# sourceMappingURL=typeschema.modern.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeschema.modern.mjs","sources":["../src/typeschema.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport type { ValidationIssue } from '@typeschema/core';\nimport { validate } from '@typeschema/main';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n typeschemaErrors: ValidationIssue[],\n validateAllFieldCriteria: boolean,\n): FieldErrors => {\n const errors: Record<string, FieldError> = {};\n\n for (; typeschemaErrors.length; ) {\n const error = typeschemaErrors[0];\n\n if (!error.path) {\n continue;\n }\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: '' };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types[''];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '',\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n typeschemaErrors.shift();\n }\n\n return errors;\n};\n\nexport const typeschemaResolver: Resolver =\n (schema, _, resolverOptions = {}) =>\n async (values, _, options) => {\n const result = await validate(schema, values);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (result.success) {\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : (result.data as any),\n };\n }\n\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n result.issues,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","typeschemaErrors","validateAllFieldCriteria","errors","length","error","path","_path","join","message","type","types","messages","appendErrors","concat","shift","typeschemaResolver","schema","_","resolverOptions","async","values","options","result","validate","shouldUseNativeValidation","validateFieldsNatively","success","raw","data","toNestErrors","issues","criteriaMode"],"mappings":"0KAMA,MAAMA,EAAmBA,CACvBC,EACAC,KAEA,MAAMC,EAAqC,CAAE,EAE7C,KAAOF,EAAiBG,QAAU,CAChC,MAAMC,EAAQJ,EAAiB,GAE/B,IAAKI,EAAMC,KACT,SAEF,MAAMC,EAAQF,EAAMC,KAAKE,KAAK,KAM9B,GAJKL,EAAOI,KACVJ,EAAOI,GAAS,CAAEE,QAASJ,EAAMI,QAASC,KAAM,KAG9CR,EAA0B,CAC5B,MAAMS,EAAQR,EAAOI,GAAOI,MACtBC,EAAWD,GAASA,EAAM,IAEhCR,EAAOI,GAASM,EACdN,EACAL,EACAC,EACA,GACAS,EACK,GAAgBE,OAAOF,EAAsBP,EAAMI,SACpDJ,EAAMI,QAEd,CAEAR,EAAiBc,OACnB,CAEA,OAAOZ,GAGIa,EACXA,CAACC,EAAQC,EAAGC,EAAkB,CAAE,IAChCC,MAAOC,EAAQH,EAAGI,KAChB,MAAMC,QAAeC,EAASP,EAAQI,GAItC,OAFAC,EAAQG,2BAA6BC,EAAuB,CAAE,EAAEJ,GAE5DC,EAAOI,QACF,CACLxB,OAAQ,CAAiB,EACzBkB,OAAQF,EAAgBS,IAAMP,EAAUE,EAAOM,MAI5C,CACLR,OAAQ,CAAA,EACRlB,OAAQ2B,EACN9B,EACEuB,EAAOQ,QACNT,EAAQG,2BAAsD,QAAzBH,EAAQU,cAEhDV"}
@@ -0,0 +1,2 @@
1
+ import{validateFieldsNatively as r,toNestErrors as e}from"@hookform/resolvers";import{validate as o}from"@typeschema/main";import{appendErrors as t}from"react-hook-form";var s=function(r,e){for(var o={};r.length;){var s=r[0];if(s.path){var a=s.path.join(".");if(o[a]||(o[a]={message:s.message,type:""}),e){var i=o[a].types,n=i&&i[""];o[a]=t(a,e,o,"",n?[].concat(n,s.message):s.message)}r.shift()}}return o},a=function(t,a,i){return void 0===i&&(i={}),function(a,n,m){try{return Promise.resolve(o(t,a)).then(function(o){return m.shouldUseNativeValidation&&r({},m),o.success?{errors:{},values:i.raw?a:o.data}:{values:{},errors:e(s(o.issues,!m.shouldUseNativeValidation&&"all"===m.criteriaMode),m)}})}catch(r){return Promise.reject(r)}}};export{a as typeschemaResolver};
2
+ //# sourceMappingURL=typeschema.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeschema.module.js","sources":["../src/typeschema.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport type { ValidationIssue } from '@typeschema/core';\nimport { validate } from '@typeschema/main';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n typeschemaErrors: ValidationIssue[],\n validateAllFieldCriteria: boolean,\n): FieldErrors => {\n const errors: Record<string, FieldError> = {};\n\n for (; typeschemaErrors.length; ) {\n const error = typeschemaErrors[0];\n\n if (!error.path) {\n continue;\n }\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: '' };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types[''];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '',\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n typeschemaErrors.shift();\n }\n\n return errors;\n};\n\nexport const typeschemaResolver: Resolver =\n (schema, _, resolverOptions = {}) =>\n async (values, _, options) => {\n const result = await validate(schema, values);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (result.success) {\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : (result.data as any),\n };\n }\n\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n result.issues,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","typeschemaErrors","validateAllFieldCriteria","errors","length","error","path","_path","join","message","type","types","messages","appendErrors","concat","shift","typeschemaResolver","schema","_","resolverOptions","values","options","Promise","resolve","validate","then","result","shouldUseNativeValidation","validateFieldsNatively","success","raw","data","toNestErrors","issues","criteriaMode","e","reject"],"mappings":"0KAMA,IAAMA,EAAmB,SACvBC,EACAC,GAIA,IAFA,IAAMC,EAAqC,CAAE,EAEtCF,EAAiBG,QAAU,CAChC,IAAMC,EAAQJ,EAAiB,GAE/B,GAAKI,EAAMC,KAAX,CAGA,IAAMC,EAAQF,EAAMC,KAAKE,KAAK,KAM9B,GAJKL,EAAOI,KACVJ,EAAOI,GAAS,CAAEE,QAASJ,EAAMI,QAASC,KAAM,KAG9CR,EAA0B,CAC5B,IAAMS,EAAQR,EAAOI,GAAOI,MACtBC,EAAWD,GAASA,EAAM,IAEhCR,EAAOI,GAASM,EACdN,EACAL,EACAC,EACA,GACAS,EACK,GAAgBE,OAAOF,EAAsBP,EAAMI,SACpDJ,EAAMI,QAEd,CAEAR,EAAiBc,OAtBjB,CAuBF,CAEA,OAAOZ,CACT,EAEaa,EACX,SAACC,EAAQC,EAAGC,GACLC,YADKD,IAAAA,IAAAA,EAAkB,CAAA,GACvBC,SAAAA,EAAQF,EAAGG,OAAWC,OAAAA,QAAAC,QACNC,EAASP,EAAQG,IAAOK,cAAvCC,GAEmE,OAAzEL,EAAQM,2BAA6BC,EAAuB,CAAE,EAAEP,GAE5DK,EAAOG,QACF,CACL1B,OAAQ,CAAiB,EACzBiB,OAAQD,EAAgBW,IAAMV,EAAUM,EAAOK,MAI5C,CACLX,OAAQ,CAAE,EACVjB,OAAQ6B,EACNhC,EACE0B,EAAOO,QACNZ,EAAQM,2BAAsD,QAAzBN,EAAQa,cAEhDb,GAEH,EACH,CAAC,MAAAc,GAAAb,OAAAA,QAAAc,OAAAD,EAAA,CAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("@hookform/resolvers"),require("@typeschema/main"),require("react-hook-form")):"function"==typeof define&&define.amd?define(["exports","@hookform/resolvers","@typeschema/main","react-hook-form"],o):o((e||self).hookformResolversTypeschema={},e.hookformResolvers,e.main,e.ReactHookForm)}(this,function(e,o,r,s){var t=function(e,o){for(var r={};e.length;){var t=e[0];if(t.path){var a=t.path.join(".");if(r[a]||(r[a]={message:t.message,type:""}),o){var i=r[a].types,n=i&&i[""];r[a]=s.appendErrors(a,o,r,"",n?[].concat(n,t.message):t.message)}e.shift()}}return r};e.typeschemaResolver=function(e,s,a){return void 0===a&&(a={}),function(s,i,n){try{return Promise.resolve(r.validate(e,s)).then(function(e){return n.shouldUseNativeValidation&&o.validateFieldsNatively({},n),e.success?{errors:{},values:a.raw?s:e.data}:{values:{},errors:o.toNestErrors(t(e.issues,!n.shouldUseNativeValidation&&"all"===n.criteriaMode),n)}})}catch(e){return Promise.reject(e)}}}});
2
+ //# sourceMappingURL=typeschema.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeschema.umd.js","sources":["../src/typeschema.ts"],"sourcesContent":["import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers';\nimport type { ValidationIssue } from '@typeschema/core';\nimport { validate } from '@typeschema/main';\nimport { FieldError, FieldErrors, appendErrors } from 'react-hook-form';\nimport type { Resolver } from './types';\n\nconst parseErrorSchema = (\n typeschemaErrors: ValidationIssue[],\n validateAllFieldCriteria: boolean,\n): FieldErrors => {\n const errors: Record<string, FieldError> = {};\n\n for (; typeschemaErrors.length; ) {\n const error = typeschemaErrors[0];\n\n if (!error.path) {\n continue;\n }\n const _path = error.path.join('.');\n\n if (!errors[_path]) {\n errors[_path] = { message: error.message, type: '' };\n }\n\n if (validateAllFieldCriteria) {\n const types = errors[_path].types;\n const messages = types && types[''];\n\n errors[_path] = appendErrors(\n _path,\n validateAllFieldCriteria,\n errors,\n '',\n messages\n ? ([] as string[]).concat(messages as string[], error.message)\n : error.message,\n ) as FieldError;\n }\n\n typeschemaErrors.shift();\n }\n\n return errors;\n};\n\nexport const typeschemaResolver: Resolver =\n (schema, _, resolverOptions = {}) =>\n async (values, _, options) => {\n const result = await validate(schema, values);\n\n options.shouldUseNativeValidation && validateFieldsNatively({}, options);\n\n if (result.success) {\n return {\n errors: {} as FieldErrors,\n values: resolverOptions.raw ? values : (result.data as any),\n };\n }\n\n return {\n values: {},\n errors: toNestErrors(\n parseErrorSchema(\n result.issues,\n !options.shouldUseNativeValidation && options.criteriaMode === 'all',\n ),\n options,\n ),\n };\n };\n"],"names":["parseErrorSchema","typeschemaErrors","validateAllFieldCriteria","errors","length","error","path","_path","join","message","type","types","messages","appendErrors","concat","shift","schema","_","resolverOptions","values","options","Promise","resolve","validate","then","result","shouldUseNativeValidation","validateFieldsNatively","success","raw","data","toNestErrors","issues","criteriaMode","e","reject"],"mappings":"ubAMA,IAAMA,EAAmB,SACvBC,EACAC,GAIA,IAFA,IAAMC,EAAqC,CAAE,EAEtCF,EAAiBG,QAAU,CAChC,IAAMC,EAAQJ,EAAiB,GAE/B,GAAKI,EAAMC,KAAX,CAGA,IAAMC,EAAQF,EAAMC,KAAKE,KAAK,KAM9B,GAJKL,EAAOI,KACVJ,EAAOI,GAAS,CAAEE,QAASJ,EAAMI,QAASC,KAAM,KAG9CR,EAA0B,CAC5B,IAAMS,EAAQR,EAAOI,GAAOI,MACtBC,EAAWD,GAASA,EAAM,IAEhCR,EAAOI,GAASM,EAAYA,aAC1BN,EACAL,EACAC,EACA,GACAS,EACK,GAAgBE,OAAOF,EAAsBP,EAAMI,SACpDJ,EAAMI,QAEd,CAEAR,EAAiBc,OAtBjB,CAuBF,CAEA,OAAOZ,CACT,uBAGE,SAACa,EAAQC,EAAGC,GACLC,YADKD,IAAAA,IAAAA,EAAkB,CAAA,GACvBC,SAAAA,EAAQF,EAAGG,OAAWC,OAAAA,QAAAC,QACNC,EAAQA,SAACP,EAAQG,IAAOK,cAAvCC,GAEmE,OAAzEL,EAAQM,2BAA6BC,EAAsBA,uBAAC,CAAE,EAAEP,GAE5DK,EAAOG,QACF,CACLzB,OAAQ,CAAiB,EACzBgB,OAAQD,EAAgBW,IAAMV,EAAUM,EAAOK,MAI5C,CACLX,OAAQ,CAAE,EACVhB,OAAQ4B,EAAYA,aAClB/B,EACEyB,EAAOO,QACNZ,EAAQM,2BAAsD,QAAzBN,EAAQa,cAEhDb,GAEH,EACH,CAAC,MAAAc,GAAAb,OAAAA,QAAAc,OAAAD,EAAA,CAAA,CAAA"}
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@hookform/resolvers/typeschema",
3
+ "amdName": "hookformResolversTypeschema",
4
+ "version": "1.0.0",
5
+ "private": true,
6
+ "description": "React Hook Form validation resolver: typeschema",
7
+ "main": "dist/typeschema.js",
8
+ "module": "dist/typeschema.module.js",
9
+ "umd:main": "dist/typeschema.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
+ "@typeschema/main": "^0.13.7"
17
+ }
18
+ }
@@ -0,0 +1,82 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import user from '@testing-library/user-event';
3
+ import type { Infer } from '@typeschema/main';
4
+ import React from 'react';
5
+ import { useForm } from 'react-hook-form';
6
+ import { z } from 'zod';
7
+ import { typeschemaResolver } from '..';
8
+
9
+ const USERNAME_REQUIRED_MESSAGE = 'username field is required';
10
+ const PASSWORD_REQUIRED_MESSAGE = 'password field is required';
11
+
12
+ const schema = z.object({
13
+ username: z.string().min(1, { message: USERNAME_REQUIRED_MESSAGE }),
14
+ password: z.string().min(1, { message: PASSWORD_REQUIRED_MESSAGE }),
15
+ });
16
+
17
+ type FormData = Infer<typeof schema>;
18
+
19
+ interface Props {
20
+ onSubmit: (data: FormData) => void;
21
+ }
22
+
23
+ function TestComponent({ onSubmit }: Props) {
24
+ const { register, handleSubmit } = useForm<FormData>({
25
+ resolver: typeschemaResolver(schema),
26
+ shouldUseNativeValidation: true,
27
+ });
28
+
29
+ return (
30
+ <form onSubmit={handleSubmit(onSubmit)}>
31
+ <input {...register('username')} placeholder="username" />
32
+
33
+ <input {...register('password')} placeholder="password" />
34
+
35
+ <button type="submit">submit</button>
36
+ </form>
37
+ );
38
+ }
39
+
40
+ test("form's native validation with TypeSchema", async () => {
41
+ const handleSubmit = vi.fn();
42
+ render(<TestComponent onSubmit={handleSubmit} />);
43
+
44
+ // username
45
+ let usernameField = screen.getByPlaceholderText(
46
+ /username/i,
47
+ ) as HTMLInputElement;
48
+ expect(usernameField.validity.valid).toBe(true);
49
+ expect(usernameField.validationMessage).toBe('');
50
+
51
+ // password
52
+ let passwordField = screen.getByPlaceholderText(
53
+ /password/i,
54
+ ) as HTMLInputElement;
55
+ expect(passwordField.validity.valid).toBe(true);
56
+ expect(passwordField.validationMessage).toBe('');
57
+
58
+ await user.click(screen.getByText(/submit/i));
59
+
60
+ // username
61
+ usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
62
+ expect(usernameField.validity.valid).toBe(false);
63
+ expect(usernameField.validationMessage).toBe(USERNAME_REQUIRED_MESSAGE);
64
+
65
+ // password
66
+ passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
67
+ expect(passwordField.validity.valid).toBe(false);
68
+ expect(passwordField.validationMessage).toBe(PASSWORD_REQUIRED_MESSAGE);
69
+
70
+ await user.type(screen.getByPlaceholderText(/username/i), 'joe');
71
+ await user.type(screen.getByPlaceholderText(/password/i), 'password');
72
+
73
+ // username
74
+ usernameField = screen.getByPlaceholderText(/username/i) as HTMLInputElement;
75
+ expect(usernameField.validity.valid).toBe(true);
76
+ expect(usernameField.validationMessage).toBe('');
77
+
78
+ // password
79
+ passwordField = screen.getByPlaceholderText(/password/i) as HTMLInputElement;
80
+ expect(passwordField.validity.valid).toBe(true);
81
+ expect(passwordField.validationMessage).toBe('');
82
+ });
@@ -0,0 +1,53 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import user from '@testing-library/user-event';
3
+ import type { Infer } from '@typeschema/main';
4
+ import React from 'react';
5
+ import { useForm } from 'react-hook-form';
6
+ import { z } from 'zod';
7
+ import { typeschemaResolver } from '..';
8
+
9
+ const schema = z.object({
10
+ username: z.string().min(1, { message: 'username field is required' }),
11
+ password: z.string().min(1, { message: 'password field is required' }),
12
+ });
13
+
14
+ type FormData = Infer<typeof schema> & { unusedProperty: string };
15
+
16
+ interface Props {
17
+ onSubmit: (data: FormData) => void;
18
+ }
19
+
20
+ function TestComponent({ onSubmit }: Props) {
21
+ const {
22
+ register,
23
+ handleSubmit,
24
+ formState: { errors },
25
+ } = useForm<FormData>({
26
+ resolver: typeschemaResolver(schema), // Useful to check TypeScript regressions
27
+ });
28
+
29
+ return (
30
+ <form onSubmit={handleSubmit(onSubmit)}>
31
+ <input {...register('username')} />
32
+ {errors.username && <span role="alert">{errors.username.message}</span>}
33
+
34
+ <input {...register('password')} />
35
+ {errors.password && <span role="alert">{errors.password.message}</span>}
36
+
37
+ <button type="submit">submit</button>
38
+ </form>
39
+ );
40
+ }
41
+
42
+ test("form's validation with TypeSchema and TypeScript's integration", async () => {
43
+ const handleSubmit = vi.fn();
44
+ render(<TestComponent onSubmit={handleSubmit} />);
45
+
46
+ expect(screen.queryAllByRole('alert')).toHaveLength(0);
47
+
48
+ await user.click(screen.getByText(/submit/i));
49
+
50
+ expect(screen.getByText(/username field is required/i)).toBeInTheDocument();
51
+ expect(screen.getByText(/password field is required/i)).toBeInTheDocument();
52
+ expect(handleSubmit).not.toHaveBeenCalled();
53
+ });
@@ -0,0 +1,88 @@
1
+ import { Field, InternalFieldName } from 'react-hook-form';
2
+ import { z } from 'zod';
3
+
4
+ export const schema = z
5
+ .object({
6
+ username: z.string().regex(/^\w+$/).min(3).max(30),
7
+ password: z
8
+ .string()
9
+ .regex(new RegExp('.*[A-Z].*'), 'One uppercase character')
10
+ .regex(new RegExp('.*[a-z].*'), 'One lowercase character')
11
+ .regex(new RegExp('.*\\d.*'), 'One number')
12
+ .regex(
13
+ new RegExp('.*[`~<>?,./!@#$%^&*()\\-_+="\'|{}\\[\\];:\\\\].*'),
14
+ 'One special character',
15
+ )
16
+ .min(8, 'Must be at least 8 characters in length'),
17
+ repeatPassword: z.string(),
18
+ accessToken: z.union([z.string(), z.number()]),
19
+ birthYear: z.number().min(1900).max(2013).optional(),
20
+ email: z.string().email().optional(),
21
+ tags: z.array(z.string()),
22
+ enabled: z.boolean(),
23
+ url: z.string().url('Custom error url').or(z.literal('')),
24
+ like: z
25
+ .array(
26
+ z.object({
27
+ id: z.number(),
28
+ name: z.string().length(4),
29
+ }),
30
+ )
31
+ .optional(),
32
+ dateStr: z
33
+ .string()
34
+ .transform((value) => new Date(value))
35
+ .refine((value) => !isNaN(value.getTime()), {
36
+ message: 'Invalid date',
37
+ }),
38
+ })
39
+ .refine((obj) => obj.password === obj.repeatPassword, {
40
+ message: 'Passwords do not match',
41
+ path: ['confirm'],
42
+ });
43
+
44
+ export const validData: z.input<typeof schema> = {
45
+ username: 'Doe',
46
+ password: 'Password123_',
47
+ repeatPassword: 'Password123_',
48
+ birthYear: 2000,
49
+ email: 'john@doe.com',
50
+ tags: ['tag1', 'tag2'],
51
+ enabled: true,
52
+ accessToken: 'accessToken',
53
+ url: 'https://react-hook-form.com/',
54
+ like: [
55
+ {
56
+ id: 1,
57
+ name: 'name',
58
+ },
59
+ ],
60
+ dateStr: '2020-01-01',
61
+ };
62
+
63
+ export const invalidData = {
64
+ password: '___',
65
+ email: '',
66
+ birthYear: 'birthYear',
67
+ like: [{ id: 'z' }],
68
+ url: 'abc',
69
+ };
70
+
71
+ export const fields: Record<InternalFieldName, Field['_f']> = {
72
+ username: {
73
+ ref: { name: 'username' },
74
+ name: 'username',
75
+ },
76
+ password: {
77
+ ref: { name: 'password' },
78
+ name: 'password',
79
+ },
80
+ email: {
81
+ ref: { name: 'email' },
82
+ name: 'email',
83
+ },
84
+ birthday: {
85
+ ref: { name: 'birthday' },
86
+ name: 'birthday',
87
+ },
88
+ };
@@ -0,0 +1,225 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`typeschemaResolver > should return a single error from typeschemaResolver when validation fails 1`] = `
4
+ {
5
+ "errors": {
6
+ "accessToken": {
7
+ "message": "Invalid input",
8
+ "ref": undefined,
9
+ "type": "",
10
+ },
11
+ "birthYear": {
12
+ "message": "Expected number, received string",
13
+ "ref": undefined,
14
+ "type": "",
15
+ },
16
+ "dateStr": {
17
+ "message": "Required",
18
+ "ref": undefined,
19
+ "type": "",
20
+ },
21
+ "email": {
22
+ "message": "Invalid email",
23
+ "ref": {
24
+ "name": "email",
25
+ },
26
+ "type": "",
27
+ },
28
+ "enabled": {
29
+ "message": "Required",
30
+ "ref": undefined,
31
+ "type": "",
32
+ },
33
+ "like": [
34
+ {
35
+ "id": {
36
+ "message": "Expected number, received string",
37
+ "ref": undefined,
38
+ "type": "",
39
+ },
40
+ "name": {
41
+ "message": "Required",
42
+ "ref": undefined,
43
+ "type": "",
44
+ },
45
+ },
46
+ ],
47
+ "password": {
48
+ "message": "One uppercase character",
49
+ "ref": {
50
+ "name": "password",
51
+ },
52
+ "type": "",
53
+ },
54
+ "repeatPassword": {
55
+ "message": "Required",
56
+ "ref": undefined,
57
+ "type": "",
58
+ },
59
+ "tags": {
60
+ "message": "Required",
61
+ "ref": undefined,
62
+ "type": "",
63
+ },
64
+ "url": {
65
+ "message": "Custom error url",
66
+ "ref": undefined,
67
+ "type": "",
68
+ },
69
+ "username": {
70
+ "message": "Required",
71
+ "ref": {
72
+ "name": "username",
73
+ },
74
+ "type": "",
75
+ },
76
+ },
77
+ "values": {},
78
+ }
79
+ `;
80
+
81
+ exports[`typeschemaResolver > should return all the errors from typeschemaResolver when validation fails with \`validateAllFieldCriteria\` set to true 1`] = `
82
+ {
83
+ "errors": {
84
+ "accessToken": {
85
+ "message": "Invalid input",
86
+ "ref": undefined,
87
+ "type": "",
88
+ "types": {
89
+ "": "Invalid input",
90
+ },
91
+ },
92
+ "birthYear": {
93
+ "message": "Expected number, received string",
94
+ "ref": undefined,
95
+ "type": "",
96
+ "types": {
97
+ "": "Expected number, received string",
98
+ },
99
+ },
100
+ "dateStr": {
101
+ "message": "Required",
102
+ "ref": undefined,
103
+ "type": "",
104
+ "types": {
105
+ "": "Required",
106
+ },
107
+ },
108
+ "email": {
109
+ "message": "Invalid email",
110
+ "ref": {
111
+ "name": "email",
112
+ },
113
+ "type": "",
114
+ "types": {
115
+ "": "Invalid email",
116
+ },
117
+ },
118
+ "enabled": {
119
+ "message": "Required",
120
+ "ref": undefined,
121
+ "type": "",
122
+ "types": {
123
+ "": "Required",
124
+ },
125
+ },
126
+ "like": [
127
+ {
128
+ "id": {
129
+ "message": "Expected number, received string",
130
+ "ref": undefined,
131
+ "type": "",
132
+ "types": {
133
+ "": "Expected number, received string",
134
+ },
135
+ },
136
+ "name": {
137
+ "message": "Required",
138
+ "ref": undefined,
139
+ "type": "",
140
+ "types": {
141
+ "": "Required",
142
+ },
143
+ },
144
+ },
145
+ ],
146
+ "password": {
147
+ "message": "One uppercase character",
148
+ "ref": {
149
+ "name": "password",
150
+ },
151
+ "type": "",
152
+ "types": {
153
+ "": [
154
+ "One uppercase character",
155
+ "One lowercase character",
156
+ "One number",
157
+ "Must be at least 8 characters in length",
158
+ ],
159
+ },
160
+ },
161
+ "repeatPassword": {
162
+ "message": "Required",
163
+ "ref": undefined,
164
+ "type": "",
165
+ "types": {
166
+ "": "Required",
167
+ },
168
+ },
169
+ "tags": {
170
+ "message": "Required",
171
+ "ref": undefined,
172
+ "type": "",
173
+ "types": {
174
+ "": "Required",
175
+ },
176
+ },
177
+ "url": {
178
+ "message": "Custom error url",
179
+ "ref": undefined,
180
+ "type": "",
181
+ "types": {
182
+ "": "Custom error url",
183
+ },
184
+ },
185
+ "username": {
186
+ "message": "Required",
187
+ "ref": {
188
+ "name": "username",
189
+ },
190
+ "type": "",
191
+ "types": {
192
+ "": "Required",
193
+ },
194
+ },
195
+ },
196
+ "values": {},
197
+ }
198
+ `;
199
+
200
+ exports[`typeschemaResolver > should return parsed values from typeschemaResolver when validation pass 1`] = `
201
+ {
202
+ "errors": {},
203
+ "values": {
204
+ "accessToken": "accessToken",
205
+ "birthYear": 2000,
206
+ "dateStr": 2020-01-01T00:00:00.000Z,
207
+ "email": "john@doe.com",
208
+ "enabled": true,
209
+ "like": [
210
+ {
211
+ "id": 1,
212
+ "name": "name",
213
+ },
214
+ ],
215
+ "password": "Password123_",
216
+ "repeatPassword": "Password123_",
217
+ "tags": [
218
+ "tag1",
219
+ "tag2",
220
+ ],
221
+ "url": "https://react-hook-form.com/",
222
+ "username": "Doe",
223
+ },
224
+ }
225
+ `;
@@ -0,0 +1,70 @@
1
+ import * as typeschema from '@typeschema/main';
2
+ import { typeschemaResolver } from '..';
3
+ import { fields, invalidData, schema, validData } from './__fixtures__/data';
4
+
5
+ const shouldUseNativeValidation = false;
6
+
7
+ vi.mock('@typeschema/main', async (importOriginal) => {
8
+ const module: object = await importOriginal();
9
+ return { ...module };
10
+ });
11
+
12
+ describe('typeschemaResolver', () => {
13
+ it('should return values from typeschemaResolver when validation pass & raw=true', async () => {
14
+ const validateSpy = vi.spyOn(typeschema, 'validate');
15
+
16
+ const result = await typeschemaResolver(schema, undefined, { raw: true })(
17
+ validData,
18
+ undefined,
19
+ { fields, shouldUseNativeValidation },
20
+ );
21
+
22
+ expect(validateSpy).toHaveBeenCalledTimes(1);
23
+ expect(result).toEqual({ errors: {}, values: validData });
24
+ });
25
+
26
+ it('should return parsed values from typeschemaResolver when validation pass', async () => {
27
+ const validateSpy = vi.spyOn(typeschema, 'validate');
28
+
29
+ const result = await typeschemaResolver(schema)(validData, undefined, {
30
+ fields,
31
+ shouldUseNativeValidation,
32
+ });
33
+
34
+ expect(validateSpy).toHaveBeenCalledTimes(1);
35
+ expect(result.errors).toEqual({});
36
+ expect(result).toMatchSnapshot();
37
+ });
38
+
39
+ it('should return a single error from typeschemaResolver when validation fails', async () => {
40
+ const result = await typeschemaResolver(schema)(invalidData, undefined, {
41
+ fields,
42
+ shouldUseNativeValidation,
43
+ });
44
+
45
+ expect(result).toMatchSnapshot();
46
+ });
47
+
48
+ it('should return all the errors from typeschemaResolver when validation fails with `validateAllFieldCriteria` set to true', async () => {
49
+ const result = await typeschemaResolver(schema)(invalidData, undefined, {
50
+ fields,
51
+ criteriaMode: 'all',
52
+ shouldUseNativeValidation,
53
+ });
54
+
55
+ expect(result).toMatchSnapshot();
56
+ });
57
+
58
+ it('should throw any error unrelated to TypeSchema', async () => {
59
+ const schemaWithCustomError = schema.refine(() => {
60
+ throw Error('custom error');
61
+ });
62
+ const promise = typeschemaResolver(schemaWithCustomError)(
63
+ validData,
64
+ undefined,
65
+ { fields, shouldUseNativeValidation },
66
+ );
67
+
68
+ await expect(promise).rejects.toThrow('custom error');
69
+ });
70
+ });
@@ -0,0 +1,2 @@
1
+ export * from './typeschema';
2
+ export * from './types';
@@ -0,0 +1,18 @@
1
+ import type { Schema } from '@typeschema/main';
2
+ import { FieldValues, ResolverOptions, ResolverResult } from 'react-hook-form';
3
+
4
+ export type Resolver = <T extends Schema>(
5
+ schema: T,
6
+ schemaOptions?: never,
7
+ factoryOptions?: {
8
+ /**
9
+ * Return the raw input values rather than the parsed values.
10
+ * @default false
11
+ */
12
+ raw?: boolean;
13
+ },
14
+ ) => <TFieldValues extends FieldValues, TContext>(
15
+ values: TFieldValues,
16
+ context: TContext | undefined,
17
+ options: ResolverOptions<TFieldValues>,
18
+ ) => Promise<ResolverResult<TFieldValues>>;