import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers'; import * as Either from 'fp-ts/Either'; import { pipe } from 'fp-ts/function'; import * as t from 'io-ts'; import { FieldErrors, FieldValues, Resolver, ResolverError, ResolverSuccess, } from 'react-hook-form'; import errorsToRecord, { ErrorObject } from './errorsToRecord'; export function ioTsResolver( schema: t.Type, resolverOptions?: { mode?: 'async' | 'sync'; raw?: false; }, ): Resolver; export function ioTsResolver( schema: t.Type, resolverOptions: { mode?: 'async' | 'sync'; raw: true; }, ): Resolver; /** * Creates a resolver for react-hook-form using io-ts schema validation * @param {t.Type} schema - The io-ts schema to validate against * @param {Object} options - Additional resolver configuration * @param {string} [options.mode='async'] - Validation mode * @returns {Resolver>} A resolver function compatible with react-hook-form * @example * const schema = t.type({ * name: t.string, * age: t.number * }); * * useForm({ * resolver: ioTsResolver(schema) * }); */ export function ioTsResolver( schema: t.Type, ): Resolver { return (values, _context, options) => pipe( values, schema.decode, Either.mapLeft( errorsToRecord( !options.shouldUseNativeValidation && options.criteriaMode === 'all', ), ), Either.mapLeft((errors: ErrorObject) => toNestErrors(errors, options), ), Either.fold< FieldErrors, Output, ResolverError | ResolverSuccess >( (errors) => ({ values: {}, errors, }), (values) => { options.shouldUseNativeValidation && validateFieldsNatively({}, options); return { values, errors: {}, }; }, ), ); }