@stimulus-library/utilities
Version:
A library of useful controllers for Stimulus
162 lines (161 loc) • 5.29 kB
JavaScript
const reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
const reIsPlainProp = /^\w*$/;
const rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
const reIsUint = /^(?:0|[1-9]\d*)$/;
const reEscapeChar = /\\(\\)?/g;
const symbolTag = "[object Symbol]";
const hasOwnProperty = Object.prototype.hasOwnProperty;
const isArray = Array.isArray;
const symbolProto = Symbol ? Symbol.prototype : undefined;
const symbolToString = symbolProto ? symbolProto.toString : undefined;
const INFINITY = 1 / 0;
const MAX_SAFE_INTEGER = 9007199254740991;
function arrayMap(array, iteratee) {
let index = -1;
const length = array == null ? 0 : array.length;
const result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
function baseToString(value) {
if (typeof value == "string") {
return value;
}
if (isArray(value)) {
return arrayMap(value, baseToString) + "";
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : "";
}
const result = (value + "");
return (result == "0" && (1 / value) == -INFINITY) ? "-0" : result;
}
function toString(value) {
return value == null ? "" : baseToString(value);
}
export function stringToPath(str) {
const result = [];
if (str.charCodeAt(0) === 46) {
result.push("");
}
str.replace(rePropName, function (match, number, quote, subString) {
result.push(quote ? subString.replace(reEscapeChar, "$1") : (number || match));
});
return result;
}
function defineProperty(object, key, value) {
object[key] = value;
return object;
}
function castPath(value, object) {
if (isArray(value)) {
return value;
}
return isKey(value, object) ? [value] : stringToPath(toString(value));
}
function toKey(value) {
if (typeof value == "string" || isSymbol(value)) {
return value;
}
const result = (value + "");
return (result == "0" && (1 / value) == -Infinity) ? "-0" : result;
}
function isKey(value, object) {
if (isArray(value)) {
return false;
}
const type = typeof value;
if (type == "number" || type == "boolean" ||
value == null || isSymbol(value)) {
return true;
}
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
(object != null && value in Object(object));
}
function isObjectLike(value) {
return value != null && typeof value == "object";
}
function isSymbol(value) {
return typeof value == "symbol" ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
function baseGetTag(value) {
return objectToString.call(value);
}
function objectToString(value) {
return objectProto.toString.call(value);
}
const objectProto = Object.prototype;
function baseGet(object, path) {
const castedPath = castPath(path, object);
let index = 0;
const length = castedPath.length;
while (object != null && index < length) {
object = object[toKey(castedPath[index++])];
}
return (index && index == length) ? object : undefined;
}
function isObject(value) {
const type = typeof value;
return value != null && (type == "object" || type == "function");
}
function isIndex(value, length = null) {
const type = typeof value;
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length && (type == "number" || (type != "symbol" && reIsUint.test(value))) && (value > -1 && value % 1 == 0 && value < length);
}
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
function assignValue(object, key, value) {
const objValue = object[key];
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
(value === undefined && !(key in object))) {
baseAssignValue(object, key, value);
}
}
function baseAssignValue(object, key, value) {
if (key == "__proto__" && defineProperty) {
defineProperty(object, key, {
"configurable": true,
"enumerable": true,
"value": value,
"writable": true,
});
}
else {
object[key] = value;
}
}
function baseSet(object, path, value) {
if (!isObject(object)) {
return object;
}
const castedPath = castPath(path, object);
let index = -1;
const length = castedPath.length;
const lastIndex = length - 1;
let nested = object;
while (nested != null && ++index < length) {
const key = toKey(castedPath[index]);
let newValue = value;
if (index != lastIndex) {
const objValue = nested[key];
newValue = isObject(objValue)
? objValue
: (isIndex(castedPath[index + 1]) ? [] : {});
}
assignValue(nested, key, newValue);
nested = nested[key];
}
return object;
}
export function get(object, path, defaultValue = null) {
const result = object == null ? undefined : baseGet(object, path);
return result === undefined ? defaultValue : result;
}
export function set(object, path, value) {
return object == null ? object : baseSet(object, path, value);
}