react-formal
Version:
Classy HTML form management for React
136 lines (135 loc) • 4.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.EMPTY_ERRORS = void 0;
exports.filter = filter;
exports.filterAndMapErrors = filterAndMapErrors;
exports.inclusiveMapErrors = inclusiveMapErrors;
exports.isChildPath = void 0;
exports.move = move;
exports.pickErrors = pickErrors;
exports.prefix = prefix;
exports.remove = remove;
exports.shift = shift;
exports.swap = swap;
exports.unprefix = unprefix;
exports.unshift = unshift;
var _omitBy = _interopRequireDefault(require("lodash/omitBy"));
var _pick = _interopRequireDefault(require("lodash/pick"));
var _paths = require("./utils/paths");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const EMPTY_ERRORS = Object.freeze({});
exports.EMPTY_ERRORS = EMPTY_ERRORS;
let isChildPath = (basePath, path) => path !== basePath && (0, _paths.inPath)(basePath, path);
exports.isChildPath = isChildPath;
function mapKeys(errors, baseName, fn) {
if (errors === EMPTY_ERRORS) return errors;
const newErrors = {};
let workDone = false;
Object.keys(errors).forEach(path => {
let newKey = path;
if (isChildPath(baseName, path)) {
var _fn;
const matches = path.slice(baseName.length).match(/\[(\d+)\](.*)$/);
newKey = (_fn = fn(+matches[1], matches[2] || '', path)) != null ? _fn : path;
if (!workDone && newKey !== path) workDone = true;
}
newErrors[newKey] = errors[path];
});
return workDone ? newErrors : errors;
}
const prefixName = (name, baseName) => baseName + (!name || name[0] === '[' ? '' : '.') + name;
function prefix(errors, baseName) {
const paths = Object.keys(errors);
const result = {};
paths.forEach(path => {
result[prefixName(path, baseName)] = errors[path];
});
return result;
}
function unprefix(errors, baseName) {
const paths = Object.keys(errors);
const result = {};
paths.forEach(path => {
const shortened = path.slice(baseName.length).replace(/^\./, '');
result[shortened] = errors[path];
});
return result;
}
function pickErrors(errors, names) {
if (!names.length) return errors;
return (0, _pick.default)(errors, names);
}
function filter(errors, baseName) {
const paths = Object.keys(errors);
const result = {};
paths.forEach(path => {
if (isChildPath(baseName, path)) {
result[path] = errors[path];
}
});
return result;
}
function filterAndMapErrors({
errors,
names,
mapErrors = pickErrors
}) {
if (!errors || errors === EMPTY_ERRORS) return EMPTY_ERRORS;
return mapErrors(errors, (0, _paths.toArray)(names));
}
function remove(errors, ...basePaths) {
return (0, _omitBy.default)(errors, (_, path) => basePaths.some(b => (0, _paths.inPath)(b, path)));
}
function shift(errors, baseName, atIndex = 0) {
const current = `${baseName}[${atIndex}]`;
return mapKeys(remove(errors, current), baseName, (index, tail) => {
if (index >= atIndex) {
return `${baseName}[${index - 1}]${tail}`;
}
return null;
});
}
function unshift(errors, baseName, atIndex = 0) {
return mapKeys(errors, baseName, (index, tail) => {
if (index >= atIndex) {
return `${baseName}[${index + 1}]${tail}`;
}
return null;
});
}
function move(errors, baseName, fromIndex, toIndex) {
return mapKeys(errors, baseName, (index, tail) => {
if (fromIndex > toIndex) {
if (index === fromIndex) return `${baseName}[${toIndex}]${tail}`;
// increment everything above the pivot
if (index >= toIndex && index < fromIndex) return `${baseName}[${index + 1}]${tail}`;
} else if (fromIndex < toIndex) {
if (index === fromIndex) return `${baseName}[${toIndex}]${tail}`;
// decrement everything above the from item we moved
if (index >= fromIndex && index < toIndex) return `${baseName}[${index - 1}]${tail}`;
}
return null;
});
}
function swap(errors, baseName, indexA, indexB) {
return mapKeys(errors, baseName, (index, tail) => {
if (index === indexA) return `${baseName}[${indexB}]${tail}`;
if (index === indexB) return `${baseName}[${indexA}]${tail}`;
return null;
});
}
function inclusiveMapErrors(errors, names) {
if (!names.length || errors === EMPTY_ERRORS) return EMPTY_ERRORS;
let activeErrors = {};
let paths = Object.keys(errors);
names.forEach(name => {
paths.forEach(path => {
if (errors[path] && (0, _paths.inPath)(name, path)) {
activeErrors[path] = errors[path];
}
});
});
return activeErrors;
}