UNPKG

react-formal

Version:

Classy HTML form management for React

55 lines 2 kB
import { EMPTY_ERRORS } from './Errors'; import errToJSON from './utils/errToJSON'; import { trim, inPath } from './utils/paths'; import uniqBy from 'lodash/uniqBy'; function trimChildren(rootPath, errors) { let result = {}; Object.keys(errors).forEach(path => { if (rootPath !== path && inPath(rootPath, path)) return; result[path] = errors[path]; }); return result; } function reduce(paths) { paths = uniqBy(paths, p => p.path); if (paths.length <= 1) return paths; return paths.reduce((innerPaths, current) => { innerPaths = innerPaths.filter(p => !inPath(current.path, p.path)); if (!innerPaths.some(p => inPath(p.path, current.path))) innerPaths.push(current); return innerPaths; }, []); } export let isValidationError = err => err && err.name === 'ValidationError'; export default function errorManager(handleValidation) { return { async collect(paths, pristineErrors = EMPTY_ERRORS, options) { const specs = reduce(paths.map(p => typeof p === 'string' ? { path: p, shallow: false } : p)); let errors = Object.assign({}, pristineErrors); let nextErrors = errors; let workDone = false; specs.forEach(({ path, shallow }) => { nextErrors = trim(path, nextErrors, shallow); if (errors !== nextErrors) workDone = true; }); let validations = specs.map(spec => Promise.resolve(handleValidation(spec, options)).then(validationError => { if (!validationError) return true; if (!isValidationError(validationError)) throw validationError; if (!spec.shallow) { errToJSON(validationError, nextErrors); return; } const fieldErrors = errToJSON(validationError); Object.assign(nextErrors, trimChildren(spec.path, fieldErrors)); })); const results = await Promise.all(validations); if (!workDone && results.every(Boolean)) return pristineErrors; return nextErrors; } }; }