ts-fusion-parser
Version:
Parser for Neos Fusion Files
140 lines (139 loc) • 6.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Arrays = void 0;
const is_object = (thing) => typeof thing === 'object' && thing !== null && Array.isArray(thing);
class Arrays {
static arrayMergeRecursiveOverrule(firstArray, secondArray, doNotAddNewKeys = false, emptyValuesOverride = true, overrideKeys = []) {
const secondArraySanitized = secondArray !== null && secondArray !== void 0 ? secondArray : {};
for (const [key, value] of Object.entries(secondArraySanitized)) {
if (firstArray[key] !== undefined && firstArray[key] !== null && typeof firstArray[key] === "object") {
if (overrideKeys.includes(key)) {
firstArray[key] = secondArray[key];
}
else {
firstArray[key] = this.arrayMergeRecursiveOverrule(firstArray[key], value, doNotAddNewKeys, emptyValuesOverride, overrideKeys);
}
}
else if (!doNotAddNewKeys || Object.keys(firstArray).includes(key)) {
firstArray[key] = emptyValuesOverride || !value || value.length > 0 ? value : firstArray[key];
}
}
return firstArray;
}
/**
* Merges two arrays recursively and "binary safe" (integer keys are overridden as well), overruling similar values in the first array ($firstArray) with the values of the second array ($secondArray)
* In case of identical keys, ie. keeping the values of the second. The given $toArray closure will be used if one of the two array keys contains an array and the other not. It should return an array.
*
* @param array $firstArray First array
* @param array $secondArray Second array, overruling the first array
* @param \Closure $toArray The given callable will get a value that is not an array and has to return an array.
* This is to allow custom merging of simple types with (sub) arrays
* @param \Closure|null $overrideFirst The given callable will determine whether the value of the first array should be overridden.
* It should have the following signature $callable($key, ?array $firstValue = null, ?array $secondValue = null): bool
* @return array Resulting array where $secondArray values has overruled $firstArray values
*/
static arrayMergeRecursiveOverruleWithCallback(firstArray, secondArray, toArray, overrideFirst) {
// {[key: string]: any}
let data = [firstArray, secondArray];
let entryCount = 1;
for (let i = 0; i < entryCount; i++) {
let firstArrayInner = data[i * 2];
let secondArrayInner = data[i * 2 + 1];
for (const key in secondArrayInner) {
let value = secondArrayInner[key];
if (!firstArrayInner[key] || (!is_object(firstArrayInner[key]) && !is_object(value))) {
firstArrayInner[key] = value;
}
else {
if (!is_object(value))
value = toArray(value);
if (!is_object(firstArrayInner[key]))
firstArrayInner[key] = toArray(firstArrayInner[key]);
if (is_object(firstArrayInner[key]) && is_object(value)) {
if (overrideFirst === null || overrideFirst === void 0 ? void 0 : overrideFirst(key, firstArrayInner[key], value))
firstArrayInner[key] = value;
data.push(firstArrayInner[key]);
data.push(value);
entryCount++;
}
else {
firstArrayInner[key] = value;
}
}
}
}
return firstArray;
}
static unsetValueByPath(arr, path) {
if (typeof path === "string") {
path = path.split(".");
}
else if (!Array.isArray(path)) {
throw new Error("unsetValueByPath() expects path to be string or array");
}
const [key, ...remainingPath] = path;
if (!remainingPath.length) {
delete arr[key];
}
else if (typeof arr[key] === "object") {
arr[key] = this.unsetValueByPath(arr[key], remainingPath);
}
return arr;
}
static getValueByPath(array, path) {
if (typeof path === "string") {
path = path.split('.');
}
else if (typeof path !== "object") {
throw new Error('getValueByPath() expects path to be string or array, "' + (typeof path) + '" given.');
// throw new \InvalidArgumentException('getValueByPath() expects path to be string or array, "' . gettype(path) . '" given.', 1304950007);
}
const key = path.shift();
if (key !== undefined && array[key] !== undefined) {
if (path.length > 0) {
return (typeof array[key] === "object") ? this.getValueByPath(array[key], path) : null;
}
else {
return array[key];
}
}
else {
return null;
}
}
static mergeArraysRecursively(firstArray, secondArray, toArray, overrideFirst = null) {
const data = [firstArray, secondArray];
let entryCount = 1;
for (let i = 0; i < entryCount; i++) {
const firstArrayInner = data[i * 2];
const secondArrayInner = data[i * 2 + 1];
for (const key in secondArrayInner) {
let value = secondArrayInner[key];
if (firstArrayInner[key] === undefined || typeof firstArrayInner[key] !== "object" || typeof value !== "object") {
firstArrayInner[key] = value;
}
else {
if (typeof value !== "object")
value = toArray(value);
if (typeof firstArrayInner[key] !== "object") {
firstArrayInner[key] = toArray(firstArrayInner[key]);
}
if (typeof firstArrayInner[key] === "object" && typeof value === "object") {
if (overrideFirst === null || overrideFirst === void 0 ? void 0 : overrideFirst(key, firstArrayInner[key], value)) {
firstArrayInner[key] = value;
}
else {
data.push(firstArrayInner[key], value);
entryCount += 1;
}
}
else {
firstArrayInner[key] = value;
}
}
}
}
return firstArray;
}
}
exports.Arrays = Arrays;