@felte/common
Advanced tools
Comparing version 1.0.0-next.8 to 1.0.0-next.9
@@ -5,59 +5,534 @@ 'use strict'; | ||
var some = require('./utils/some.js'); | ||
var mapValues = require('./utils/mapValues.js'); | ||
var isFieldValue = require('./utils/isFieldValue.js'); | ||
var cloneDeep = require('./utils/cloneDeep.js'); | ||
var isPlainObject = require('./utils/isPlainObject.js'); | ||
var mergeWith = require('./utils/mergeWith.js'); | ||
var defaultsDeep = require('./utils/defaultsDeep.js'); | ||
var merge = require('./utils/merge.js'); | ||
var get = require('./utils/get.js'); | ||
var set = require('./utils/set.js'); | ||
var unset = require('./utils/unset.js'); | ||
var update = require('./utils/update.js'); | ||
var deepSet = require('./utils/deepSet.js'); | ||
var deepSome = require('./utils/deepSome.js'); | ||
var getIndex = require('./utils/getIndex.js'); | ||
var typeGuards = require('./utils/typeGuards.js'); | ||
var getPath = require('./utils/getPath.js'); | ||
var getPathFromDataset = require('./utils/getPathFromDataset.js'); | ||
var shouldIgnore = require('./utils/shouldIgnore.js'); | ||
var getValue = require('./utils/getValue.js'); | ||
var domUtils = require('./utils/domUtils.js'); | ||
/** @ignore */ | ||
function _some(obj, pred) { | ||
const keys = Object.keys(obj); | ||
return keys.some((key) => pred(obj[key])); | ||
} | ||
/** @ignore */ | ||
function _mapValues(obj, updater) { | ||
const keys = Object.keys(obj); | ||
return keys.reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: updater(obj[key]) })), {}); | ||
} | ||
/** @category Helper */ | ||
function isFieldValue(value) { | ||
if (Array.isArray(value)) { | ||
if (value.length === 0) | ||
return true; | ||
return value.some((v) => v instanceof File || typeof v === 'string'); | ||
} | ||
return (typeof value === 'string' || | ||
typeof value === 'number' || | ||
typeof value === 'boolean' || | ||
value instanceof File); | ||
} | ||
exports._some = some._some; | ||
exports._mapValues = mapValues._mapValues; | ||
exports.isFieldValue = isFieldValue.isFieldValue; | ||
exports._cloneDeep = cloneDeep._cloneDeep; | ||
exports._isPlainObject = isPlainObject._isPlainObject; | ||
exports._mergeWith = mergeWith._mergeWith; | ||
exports._defaultsDeep = defaultsDeep._defaultsDeep; | ||
exports._merge = merge._merge; | ||
exports._get = get._get; | ||
exports._set = set._set; | ||
exports._unset = unset._unset; | ||
exports._update = update._update; | ||
exports.deepSet = deepSet.deepSet; | ||
exports.deepSome = deepSome.deepSome; | ||
exports.getIndex = getIndex.getIndex; | ||
exports.isElement = typeGuards.isElement; | ||
exports.isFieldSetElement = typeGuards.isFieldSetElement; | ||
exports.isFormControl = typeGuards.isFormControl; | ||
exports.isInputElement = typeGuards.isInputElement; | ||
exports.isSelectElement = typeGuards.isSelectElement; | ||
exports.isTextAreaElement = typeGuards.isTextAreaElement; | ||
exports.getPath = getPath.getPath; | ||
exports.getPathFromDataset = getPathFromDataset.getPathFromDataset; | ||
exports.shouldIgnore = shouldIgnore.shouldIgnore; | ||
exports.getValue = getValue.getValue; | ||
exports.addAttrsFromFieldset = domUtils.addAttrsFromFieldset; | ||
exports.executeTransforms = domUtils.executeTransforms; | ||
exports.executeValidation = domUtils.executeValidation; | ||
exports.getFormControls = domUtils.getFormControls; | ||
exports.getFormDefaultValues = domUtils.getFormDefaultValues; | ||
exports.getInputTextOrNumber = domUtils.getInputTextOrNumber; | ||
exports.setControlValue = domUtils.setControlValue; | ||
exports.setForm = domUtils.setForm; | ||
/** @ignore */ | ||
function _isPlainObject(value) { | ||
return Object.prototype.toString.call(value) === '[object Object]'; | ||
} | ||
/** @ignore */ | ||
function _cloneDeep(obj) { | ||
return Object.keys(obj || {}).reduce((res, key) => (Object.assign(Object.assign({}, res), { [key]: _isPlainObject(obj[key]) | ||
? _cloneDeep(obj[key]) | ||
: Array.isArray(obj[key]) | ||
? [...obj[key]] | ||
: obj[key] })), {}); | ||
} | ||
function handleArray(value) { | ||
return function (propVal) { | ||
if (_isPlainObject(propVal)) | ||
return deepSet(propVal, value); | ||
return value; | ||
}; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function deepSet(obj, value) { | ||
return _mapValues(obj, (prop) => _isPlainObject(prop) | ||
? deepSet(prop, value) | ||
: Array.isArray(prop) | ||
? prop.map(handleArray(value)) | ||
: value); | ||
} | ||
/** @ignore */ | ||
function _mergeWith(...args) { | ||
const customizer = args.pop(); | ||
const obj = _cloneDeep(args.shift()); | ||
if (args.length === 0) | ||
return obj; | ||
for (const source of args) { | ||
if (!source) | ||
continue; | ||
const keys = Object.keys(source); | ||
for (const key of keys) { | ||
const rsValue = customizer(obj[key], source[key]); | ||
if (typeof rsValue !== 'undefined') { | ||
obj[key] = rsValue; | ||
} | ||
else if (_isPlainObject(source[key]) && _isPlainObject(obj[key])) { | ||
obj[key] = _mergeWith(obj[key], source[key], customizer); | ||
} | ||
else if (Array.isArray(source[key])) { | ||
obj[key] = source[key].map((val, i) => { | ||
if (!_isPlainObject(val)) | ||
return val; | ||
const newObj = Array.isArray(obj[key]) ? obj[key][i] : obj[key]; | ||
return _mergeWith(newObj, val, customizer); | ||
}); | ||
} | ||
else if (_isPlainObject(source[key])) { | ||
const defaultObj = deepSet(_cloneDeep(source[key]), undefined); | ||
obj[key] = _mergeWith(defaultObj, source[key], customizer); | ||
} | ||
else if (typeof source[key] !== 'undefined') { | ||
obj[key] = source[key]; | ||
} | ||
} | ||
} | ||
return obj; | ||
} | ||
function defaultsCustomizer(objValue, srcValue) { | ||
if (_isPlainObject(objValue) && _isPlainObject(srcValue)) | ||
return; | ||
if (Array.isArray(srcValue)) { | ||
if (srcValue.some(_isPlainObject)) | ||
return; | ||
const objArray = Array.isArray(objValue) ? objValue : []; | ||
return srcValue.map((value, index) => { var _a; return (_a = objArray[index]) !== null && _a !== void 0 ? _a : value; }); | ||
} | ||
if (typeof objValue !== 'undefined') | ||
return objValue; | ||
} | ||
/** @ignore */ | ||
function _defaultsDeep(...args) { | ||
return _mergeWith(...args, defaultsCustomizer); | ||
} | ||
/** @ignore */ | ||
function _merge(...args) { | ||
return _mergeWith(...args, () => undefined); | ||
} | ||
/* From: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_get */ | ||
/** @ignore */ | ||
function _get(obj, path, defaultValue) { | ||
const travel = (regexp) => String.prototype.split | ||
.call(path, regexp) | ||
.filter(Boolean) | ||
.reduce((res, key) => (res !== null && res !== undefined ? res[key] : res), obj); | ||
const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/); | ||
return result === undefined || result === obj ? defaultValue : result; | ||
} | ||
/* From: https://stackoverflow.com/a/54733755 */ | ||
/** @ignore */ | ||
function _set(obj, path, value) { | ||
if (Object(obj) !== obj) | ||
obj = {}; | ||
// When obj is not an object | ||
else if (typeof obj !== 'undefined') | ||
obj = _cloneDeep(obj); | ||
// If not yet an array, get the keys from the string-path | ||
const newPath = !Array.isArray(path) | ||
? path.toString().match(/[^.[\]]+/g) || [] | ||
: path; | ||
newPath.slice(0, -1).reduce((a, c, i // Iterate all of them except the last one | ||
) => Object(a[c]) === a[c] // Does the key exist and is its value an object? | ||
? // Yes: then follow that path | ||
a[c] | ||
: // No: create the key. Is the next key a potential array-index? | ||
(a[c] = | ||
Math.abs(Number(newPath[i + 1])) >> 0 === +newPath[i + 1] | ||
? [] // Yes: assign a new array object | ||
: {}), // No: assign a new plain object | ||
obj)[newPath[newPath.length - 1]] = value; // Finally assign the value to the last key | ||
return obj; // Return the top-level object to allow chaining | ||
} | ||
function _unset(obj, path) { | ||
if (!obj || Object(obj) !== obj) | ||
return; | ||
// When obj is not an object | ||
else if (typeof obj !== 'undefined') | ||
obj = _cloneDeep(obj); | ||
// If not yet an array, get the keys from the string-path | ||
const newPath = !Array.isArray(path) | ||
? path.toString().match(/[^.[\]]+/g) || [] | ||
: path; | ||
const foundProp = newPath.length === 1 ? obj : _get(obj, newPath.slice(0, -1).join('.')); | ||
if (Array.isArray(foundProp)) { | ||
foundProp.splice(Number(newPath[newPath.length - 1]), 1); | ||
} | ||
else { | ||
foundProp === null || foundProp === void 0 ? true : delete foundProp[newPath[newPath.length - 1]]; | ||
} | ||
return obj; | ||
} | ||
/** @ignore */ | ||
function _update(obj, path, updater) { | ||
if (Object(obj) !== obj) | ||
obj = {}; | ||
// When obj is not an object | ||
else if (typeof obj !== 'undefined') | ||
obj = _cloneDeep(obj); | ||
// If not yet an array, get the keys from the string-path | ||
const newPath = path.toString().match(/[^.[\]]+/g) || []; | ||
newPath.slice(0, -1).reduce((a, c, i // Iterate all of them except the last one | ||
) => Object(a[c]) === a[c] // Does the key exist and is its value an object? | ||
? // Yes: then follow that path | ||
a[c] | ||
: // No: create the key. Is the next key a potential array-index? | ||
(a[c] = | ||
Math.abs(Number(newPath[i + 1])) >> 0 === +newPath[i + 1] | ||
? [] // Yes: assign a new array object | ||
: {}), // No: assign a new plain object | ||
obj)[newPath[newPath.length - 1]] = updater(_get(obj, path)); // Finally assign the value to the last key | ||
return obj; // Return the top-level object to allow chaining | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function deepSome(obj, pred) { | ||
return _some(obj, (value) => _isPlainObject(value) ? deepSome(value, pred) : pred(value)); | ||
} | ||
/** | ||
* @ignore | ||
*/ | ||
function getIndex(el) { | ||
return el.hasAttribute('data-felte-index') | ||
? Number(el.dataset.felteIndex) | ||
: undefined; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function isInputElement(el) { | ||
var _a; | ||
return ((_a = el) === null || _a === void 0 ? void 0 : _a.nodeName) === 'INPUT'; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function isTextAreaElement(el) { | ||
var _a; | ||
return ((_a = el) === null || _a === void 0 ? void 0 : _a.nodeName) === 'TEXTAREA'; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function isSelectElement(el) { | ||
var _a; | ||
return ((_a = el) === null || _a === void 0 ? void 0 : _a.nodeName) === 'SELECT'; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function isFieldSetElement(el) { | ||
var _a; | ||
return ((_a = el) === null || _a === void 0 ? void 0 : _a.nodeName) === 'FIELDSET'; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function isFormControl(el) { | ||
return isInputElement(el) || isTextAreaElement(el) || isSelectElement(el); | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function isElement(el) { | ||
return el.nodeType === Node.ELEMENT_NODE; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function getPath(el, name) { | ||
const index = getIndex(el); | ||
let path = ''; | ||
if (name) { | ||
path = name; | ||
} | ||
else if (isFormControl(el)) { | ||
path = el.name; | ||
} | ||
path = typeof index === 'undefined' ? path : `${path}[${index}]`; | ||
let parent = el.parentNode; | ||
if (!parent) | ||
return path; | ||
while (parent && parent.nodeName !== 'FORM') { | ||
if (isFieldSetElement(parent) && parent.name) { | ||
const index = getIndex(parent); | ||
const fieldsetName = typeof index === 'undefined' ? parent.name : `${parent.name}[${index}]`; | ||
path = `${fieldsetName}.${path}`; | ||
} | ||
parent = parent.parentNode; | ||
} | ||
return path; | ||
} | ||
function getPathFromDataset(el) { | ||
const fieldSetName = el.dataset.felteFieldset; | ||
const index = getIndex(el); | ||
const fieldName = typeof index === 'undefined' ? el.name : `${el.name}[${index}]`; | ||
return fieldSetName ? `${fieldSetName}.${fieldName}` : fieldName; | ||
} | ||
/** | ||
* @category Helper | ||
*/ | ||
function shouldIgnore(el) { | ||
let parent = el; | ||
while (parent && parent.nodeName !== 'FORM') { | ||
if (parent.hasAttribute('data-felte-ignore')) | ||
return true; | ||
parent = parent.parentElement; | ||
} | ||
return false; | ||
} | ||
function getValue(storeValue, selectorOrPath) { | ||
if (!_isPlainObject(storeValue) || !selectorOrPath) | ||
return storeValue; | ||
if (typeof selectorOrPath === 'string') { | ||
return _get(storeValue, selectorOrPath); | ||
} | ||
return selectorOrPath(storeValue); | ||
} | ||
/** | ||
* @ignore | ||
*/ | ||
function getFormControls(el) { | ||
if (isFormControl(el)) | ||
return [el]; | ||
if (el.childElementCount === 0) | ||
return []; | ||
const foundControls = new Set(); | ||
for (const child of el.children) { | ||
if (isFormControl(child)) | ||
foundControls.add(child); | ||
if (isFieldSetElement(child)) { | ||
for (const fieldsetChild of child.elements) { | ||
if (isFormControl(fieldsetChild)) | ||
foundControls.add(fieldsetChild); | ||
} | ||
} | ||
if (child.childElementCount > 0) | ||
getFormControls(child).forEach((value) => foundControls.add(value)); | ||
} | ||
return Array.from(foundControls); | ||
} | ||
/** | ||
* @ignore | ||
*/ | ||
function addAttrsFromFieldset(fieldSet) { | ||
for (const element of fieldSet.elements) { | ||
if (!isFormControl(element) && !isFieldSetElement(element)) | ||
continue; | ||
if (fieldSet.name && element.name) { | ||
const index = getIndex(fieldSet); | ||
const fieldsetName = typeof index === 'undefined' | ||
? fieldSet.name | ||
: `${fieldSet.name}[${index}]`; | ||
element.dataset.felteFieldset = fieldSet.dataset.felteFieldset | ||
? `${fieldSet.dataset.felteFieldset}.${fieldsetName}` | ||
: fieldsetName; | ||
} | ||
if (fieldSet.hasAttribute('data-felte-keep-on-remove') && | ||
!element.hasAttribute('data-felte-keep-on-remove')) { | ||
element.dataset.felteKeepOnRemove = fieldSet.dataset.felteKeepOnRemove; | ||
} | ||
} | ||
} | ||
/** @ignore */ | ||
function getInputTextOrNumber(el) { | ||
if (el.type.match(/^(number|range)$/)) { | ||
return !el.value ? undefined : +el.value; | ||
} | ||
else { | ||
return el.value; | ||
} | ||
} | ||
/** | ||
* @ignore | ||
*/ | ||
function getFormDefaultValues(node) { | ||
var _a; | ||
let defaultData = {}; | ||
for (const el of node.elements) { | ||
if (isFieldSetElement(el)) | ||
addAttrsFromFieldset(el); | ||
if (!isFormControl(el) || !el.name) | ||
continue; | ||
const elName = getPath(el); | ||
const index = getIndex(el); | ||
if (isInputElement(el)) { | ||
if (el.type === 'checkbox') { | ||
if (typeof _get(defaultData, elName) === 'undefined') { | ||
const checkboxes = Array.from(node.querySelectorAll(`[name="${el.name}"]`)).filter((checkbox) => { | ||
if (!isFormControl(checkbox)) | ||
return false; | ||
if (typeof index !== 'undefined') { | ||
const felteIndex = Number(checkbox.dataset.felteIndex); | ||
return felteIndex === index; | ||
} | ||
return elName === getPath(checkbox); | ||
}); | ||
if (checkboxes.length === 1) { | ||
defaultData = _set(defaultData, elName, el.checked); | ||
continue; | ||
} | ||
defaultData = _set(defaultData, elName, el.checked ? [el.value] : []); | ||
continue; | ||
} | ||
if (Array.isArray(_get(defaultData, elName)) && el.checked) { | ||
defaultData = _update(defaultData, elName, (value) => { | ||
if (typeof index !== 'undefined' && !Array.isArray(value)) | ||
value = []; | ||
return [...value, el.value]; | ||
}); | ||
} | ||
continue; | ||
} | ||
if (el.type === 'radio') { | ||
if (_get(defaultData, elName)) | ||
continue; | ||
defaultData = _set(defaultData, elName, el.checked ? el.value : undefined); | ||
continue; | ||
} | ||
if (el.type === 'file') { | ||
defaultData = _set(defaultData, elName, el.multiple ? Array.from(el.files || []) : (_a = el.files) === null || _a === void 0 ? void 0 : _a[0]); | ||
continue; | ||
} | ||
} | ||
const inputValue = getInputTextOrNumber(el); | ||
defaultData = _set(defaultData, elName, inputValue); | ||
} | ||
return { defaultData }; | ||
} | ||
function setControlValue(el, value) { | ||
if (!isFormControl(el)) | ||
return; | ||
const fieldValue = value; | ||
if (isInputElement(el)) { | ||
if (el.type === 'checkbox') { | ||
const checkboxesDefaultData = fieldValue; | ||
if (typeof checkboxesDefaultData === 'undefined' || | ||
typeof checkboxesDefaultData === 'boolean') { | ||
el.checked = !!checkboxesDefaultData; | ||
return; | ||
} | ||
if (Array.isArray(checkboxesDefaultData)) { | ||
if (checkboxesDefaultData.includes(el.value)) { | ||
el.checked = true; | ||
} | ||
else { | ||
el.checked = false; | ||
} | ||
} | ||
return; | ||
} | ||
if (el.type === 'radio') { | ||
const radioValue = fieldValue; | ||
if (el.value === radioValue) | ||
el.checked = true; | ||
else | ||
el.checked = false; | ||
return; | ||
} | ||
if (el.type === 'file') { | ||
el.files = null; | ||
el.value = ''; | ||
return; | ||
} | ||
} | ||
el.value = String(fieldValue !== null && fieldValue !== void 0 ? fieldValue : ''); | ||
} | ||
/** Sets the form inputs value to match the data object provided. */ | ||
function setForm(node, data) { | ||
for (const el of node.elements) { | ||
if (isFieldSetElement(el)) | ||
addAttrsFromFieldset(el); | ||
if (!isFormControl(el) || !el.name) | ||
continue; | ||
const elName = getPath(el); | ||
setControlValue(el, _get(data, elName)); | ||
} | ||
} | ||
function executeCustomizer(objValue, srcValue) { | ||
if (_isPlainObject(objValue) || _isPlainObject(srcValue)) | ||
return; | ||
if (objValue === null) | ||
return srcValue; | ||
if (srcValue === null) | ||
return objValue; | ||
if (!objValue || !srcValue) | ||
return; | ||
if (!Array.isArray(objValue)) | ||
objValue = [objValue]; | ||
if (!Array.isArray(srcValue)) | ||
srcValue = [srcValue]; | ||
return [...objValue, ...srcValue]; | ||
} | ||
async function executeValidation(values, validations) { | ||
if (!validations) | ||
return; | ||
if (!Array.isArray(validations)) | ||
return validations(values); | ||
const errorArray = await Promise.all(validations.map((v) => v(values))); | ||
return _mergeWith(...errorArray, executeCustomizer); | ||
} | ||
function executeTransforms(values, transforms) { | ||
if (!transforms) | ||
return values; | ||
if (!Array.isArray(transforms)) | ||
return transforms(values); | ||
return transforms.reduce((res, t) => t(res), values); | ||
} | ||
exports._cloneDeep = _cloneDeep; | ||
exports._defaultsDeep = _defaultsDeep; | ||
exports._get = _get; | ||
exports._isPlainObject = _isPlainObject; | ||
exports._mapValues = _mapValues; | ||
exports._merge = _merge; | ||
exports._mergeWith = _mergeWith; | ||
exports._set = _set; | ||
exports._some = _some; | ||
exports._unset = _unset; | ||
exports._update = _update; | ||
exports.addAttrsFromFieldset = addAttrsFromFieldset; | ||
exports.deepSet = deepSet; | ||
exports.deepSome = deepSome; | ||
exports.executeTransforms = executeTransforms; | ||
exports.executeValidation = executeValidation; | ||
exports.getFormControls = getFormControls; | ||
exports.getFormDefaultValues = getFormDefaultValues; | ||
exports.getIndex = getIndex; | ||
exports.getInputTextOrNumber = getInputTextOrNumber; | ||
exports.getPath = getPath; | ||
exports.getPathFromDataset = getPathFromDataset; | ||
exports.getValue = getValue; | ||
exports.isElement = isElement; | ||
exports.isFieldSetElement = isFieldSetElement; | ||
exports.isFieldValue = isFieldValue; | ||
exports.isFormControl = isFormControl; | ||
exports.isInputElement = isInputElement; | ||
exports.isSelectElement = isSelectElement; | ||
exports.isTextAreaElement = isTextAreaElement; | ||
exports.setControlValue = setControlValue; | ||
exports.setForm = setForm; | ||
exports.shouldIgnore = shouldIgnore; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@felte/common", | ||
"version": "1.0.0-next.8", | ||
"version": "1.0.0-next.9", | ||
"description": "Common utilities for Felte packages", | ||
@@ -9,2 +9,3 @@ "author": "Pablo Berganza <pablo@berganza.dev>", | ||
"main": "dist/cjs/index.js", | ||
"browser": "dist/esm/index.js", | ||
"module": "dist/esm/index.js", | ||
@@ -11,0 +12,0 @@ "types": "dist/types/index.d.ts", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
134444
73
1452