/** * Form Validation Utilities * Utilities for applying API validation errors to form fields */ import type { ApiError } from '@/schemas/apiSchemas'; import { getValidationErrors, getErrorCategory } from './apiErrorHandler'; import type { UseFormSetError, Path } from 'react-hook-form'; /** * Applies API validation errors to react-hook-form fields * @param error - The API error containing validation details * @param setError - react-hook-form's setError function * @param fieldNameMap - Optional mapping from API field names to form field names * @returns true if validation errors were applied, false otherwise */ export function applyApiValidationErrors>( error: ApiError | Error | unknown, setError: UseFormSetError, fieldNameMap?: Record, ): boolean { // Check if this is a validation error const apiError = error && typeof error === 'object' && 'message' in error ? (error as ApiError) : null; if (!apiError) { return false; } const category = getErrorCategory(apiError); if (category !== 'validation') { return false; } // Extract validation errors from error.details const validationErrors = getValidationErrors(apiError); if (Object.keys(validationErrors).length === 0) { return false; } // Apply errors to form fields let appliedCount = 0; for (const [apiFieldName, message] of Object.entries(validationErrors)) { // Map API field name to form field name if mapping provided const formFieldName = (fieldNameMap?.[apiFieldName] || apiFieldName) as Path; // Set error on the form field setError(formFieldName, { type: 'server', message, }); appliedCount++; } return appliedCount > 0; } /** * Gets validation error for a specific field from an API error * @param error - The API error * @param fieldName - The field name to get error for * @param fieldNameMap - Optional mapping from API field names to form field names * @returns Error message for the field, or undefined if no error */ export function getFieldValidationError( error: ApiError | Error | unknown, fieldName: string, fieldNameMap?: Record, ): string | undefined { const apiError = error && typeof error === 'object' && 'message' in error ? (error as ApiError) : null; if (!apiError) { return undefined; } const category = getErrorCategory(apiError); if (category !== 'validation') { return undefined; } const validationErrors = getValidationErrors(apiError); // Check direct field name if (validationErrors[fieldName]) { return validationErrors[fieldName]; } // Check mapped field name if (fieldNameMap) { for (const [apiFieldName, formFieldName] of Object.entries(fieldNameMap)) { if (formFieldName === fieldName && validationErrors[apiFieldName]) { return validationErrors[apiFieldName]; } } } return undefined; } /** * Checks if an error is a validation error * @param error - The error to check * @returns true if the error is a validation error */ export function isValidationError(error: ApiError | Error | unknown): boolean { const apiError = error && typeof error === 'object' && 'message' in error ? (error as ApiError) : null; if (!apiError) { return false; } return getErrorCategory(apiError) === 'validation'; }