import { formatIssue } from '@effect/schema/ArrayFormatter'; import { decodeUnknown } from '@effect/schema/ParseResult'; import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers'; import * as Effect from 'effect/Effect'; import type { FieldErrors } from 'react-hook-form'; import type { Resolver } from './types'; export const effectTsResolver: Resolver = (schema, config = { errors: 'all', onExcessProperty: 'ignore' }) => (values, _, options) => { return decodeUnknown( schema, config, )(values).pipe( Effect.catchAll((parseIssue) => Effect.flip(formatIssue(parseIssue))), Effect.mapError((issues) => { const errors = issues.reduce((acc, current) => { const key = current.path.join('.'); acc[key] = { message: current.message, type: current._tag }; return acc; }, {} as FieldErrors); return toNestErrors(errors, options); }), Effect.tap(() => Effect.sync( () => options.shouldUseNativeValidation && validateFieldsNatively({}, options), ), ), Effect.match({ onFailure: (errors) => ({ errors, values: {} }), onSuccess: (result) => ({ errors: {}, values: result }), }), Effect.runPromise, ); };