/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ import type { GetAllObjectPaths, GetPathObjectType } from '@under-control/core'; import type { ValidationError, ValidationErrorsArray, ValidationErrorsListProps, } from '../types'; const CACHE_EMPTY_ERRORS_ARRAY: Readonly> = Object.freeze([]); type FormExtractorAttrs = { includeGlobals?: boolean; nested?: boolean; }; type FormErrorsExtractor =

>( path: P, attrs?: FormExtractorAttrs, ) => ValidationErrorsListProps>; type GlobalFormErrorsExtractor = () => ValidationErrorsListProps; export type FormValidatorMessagesHookAttrs = { errors: ValidationErrorsArray; }; export type FormValidatorMessagesHookResult = { all: ValidationErrorsArray; global: GlobalFormErrorsExtractor; extract: FormErrorsExtractor; }; export function useFormValidatorMessages({ errors, }: FormValidatorMessagesHookAttrs): FormValidatorMessagesHookResult { const extract: FormErrorsExtractor = ( path, { includeGlobals, nested } = {}, ) => { const extractedErrors = errors.flatMap(item => { const itemPath = item.path as string; if (nested) { const nestedPath = `${path as string}.`; const nestedArrayPath = `${path as string}[`; if (itemPath?.startsWith(nestedPath)) { return [ { ...item, path: itemPath.replace(nestedPath, ''), } as unknown as ValidationError, ]; } if (itemPath?.startsWith(nestedArrayPath)) { return [ { ...item, path: itemPath.substring((path as string).length), } as unknown as ValidationError, ]; } return []; } if ((!itemPath || itemPath !== path) && (!includeGlobals || itemPath)) { return []; } return [ { ...item, path: null, } as unknown as ValidationError, ]; }); if (extractedErrors.length) { return { errors: extractedErrors, }; } return { errors: CACHE_EMPTY_ERRORS_ARRAY as ValidationErrorsArray, }; }; const global: GlobalFormErrorsExtractor = () => ({ errors: errors.filter(error => !(error.path as string)), }); return { all: errors, global, extract, }; }