UNPKG

@formulier/core

Version:

Simple, performant form library

84 lines (83 loc) 2.65 kB
import clone from 'shallow-clone'; import isEqual from 'lodash.isequal'; function getPath(source, path, fallback) { let p = 0; const pathArray = toPath(path); while (source && p < pathArray.length) { source = source[pathArray[p++]]; if (typeof source === 'string' && p < pathArray.length - 1) return fallback; } return source === undefined ? fallback : source; } function setPath(obj, path, value) { const res = clone(obj); let resVal = res; let i = 0; const pathArray = toPath(path); for (; i < pathArray.length - 1; i++) { const currentPath = pathArray[i]; const currentObj = getPath(obj, pathArray.slice(0, i + 1)); if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) { resVal = resVal[currentPath] = clone(currentObj); } else { const nextPath = pathArray[i + 1]; resVal = resVal[currentPath] = isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {}; } } if ((i === 0 ? obj : resVal)[pathArray[i]] === value) { return obj; } if (value === undefined) { delete resVal[pathArray[i]]; } else { resVal[pathArray[i]] = value; } if (i === 0 && value === undefined) { delete res[pathArray[i]]; } return res; } function setKey(source, key, value) { if (isEqual(source[key], value)) { return source; } return { ...source, [key]: value }; } function removeKey(source, key) { if (!Object.prototype.hasOwnProperty.call(source, key)) { return source; } return Object.fromEntries(Object.entries(source).filter(entry => entry[0] !== key)); } function toPath(path) { if (Array.isArray(path)) return path; const result = []; const rePropName = /[^.[\]]+|\[(?:([^"'][^[]*)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; const reEscapeChar = /\\(\\)?/g; if (path.charCodeAt(0) === '.'.charCodeAt(0)) { result.push(''); } path.replace(rePropName, (match, expression, quote, subString) => { let key = match; if (quote) { key = subString.replace(reEscapeChar, '$1'); } else if (expression) { key = expression.trim(); } result.push(key); return ''; }); return result; } function isInteger(source) { return String(Math.floor(Number(source))) === source; } function isObject(source) { return source !== null && typeof source === 'object'; } export { clone, isEqual, getPath, setPath, setKey, removeKey, toPath, isInteger, isObject };