oberknecht-utils
Version:
Utils for oberknecht packages
119 lines (107 loc) • 4.21 kB
text/typescript
import {
extendedType_String,
extendedType_Symbol,
extendedType_Any,
extendedTypeof,
extendedTypeofCustom,
} from "../extendedTypeof";
import { addKeysToObject } from "./addKeysToObject";
import { filterByArray } from "../arrayModifiers/filterByArray";
type advancedRulesType = {
strictFiltering?: boolean; // will return undefined if not all keys match and replacingObject is not set
strictFilteringByKeys?: boolean; // will remove an object if its child keys do not match the target object's keys
arrayStrictFiltering?: boolean; // only returns the array if all items match the target array, if false: partial matches are allowed (will remove items inbetween the allowed ones)
// replacingObject?: Record<string, any>,
defaultReturnValue?: Record<string, any>;
strictMatchingFailedCallback?: () => void;
};
export function filterByJson(
object: Record<string, any>,
targetObject: Record<string, any>,
useExtendedTypes?: boolean,
advancedRules?: advancedRulesType
// arrayFilterStrict?: boolean // only returns the array if all items match the target array, if false: partial matches are allowed (will remove items inbetween the allowed ones)
) {
let r = {};
let strictMatchFailed = false;
function _filter(
obj_: Record<string, any>,
targetObj_: Record<string | symbol, any>,
currentPath: Array<string>
) {
if (Object.keys(targetObj_).length === 0) {
[extendedType_String, extendedType_Symbol].forEach((a) => {
if (targetObj_[a] !== undefined) {
Object.keys(obj_).forEach((key) => {
if (a !== extendedType_Any && extendedTypeofCustom(key) !== a)
return;
return _filter(obj_[key], targetObj_[a], [...currentPath, key]);
});
}
});
} else {
if (
advancedRules?.strictFilteringByKeys === true &&
Object.keys(obj_).sort().join("\u0000") !==
Object.keys(targetObj_).sort().join("\u0000")
)
return (strictMatchFailed = true);
Object.keys(targetObj_).forEach((key, i) => {
let key_: string = "";
if (typeof key === "symbol") {
if (
key !== extendedType_Any &&
extendedTypeofCustom(obj_[key]) !== key
) {
return (strictMatchFailed = true);
}
key_ = Object.keys(obj_)[i];
} else if (obj_[key] === undefined) {
return (strictMatchFailed = true);
} else {
key_ = key;
}
if (key_.length === 0) return (strictMatchFailed = true);
if (extendedTypeof(targetObj_[key]) === "json") {
if (extendedTypeof(obj_[key]) !== "json")
return (strictMatchFailed = true);
// addKeysToObject(r, [...currentPath, key], {});
_filter(obj_[key], targetObj_[key], [...currentPath, key]);
} else if (extendedTypeof(targetObj_[key]) === "array") {
if (extendedTypeof(obj_[key]) !== "array")
return (strictMatchFailed = true);
let arrFilter = filterByArray(
obj_[key],
targetObj_[key],
useExtendedTypes,
{
filterStrict: advancedRules?.arrayStrictFiltering ?? false,
strictMatchingFailedCallback: () => {
strictMatchFailed = true;
},
}
);
if (arrFilter !== undefined)
addKeysToObject(r, [...currentPath, key], arrFilter);
} else if (
useExtendedTypes
? targetObj_[key] === extendedType_Any ||
targetObj_[key] === extendedTypeofCustom(obj_[key]) ||
targetObj_[key] === obj_[key]
: // : extendedTypeof(targetObj_[key]) === extendedTypeof(obj_[key])
targetObj_[key] === obj_[key]
) {
addKeysToObject(r, [...currentPath, key], obj_[key]);
} else {
strictMatchFailed = true;
}
});
}
}
_filter(object, targetObject, []);
if (advancedRules?.strictFiltering === true && strictMatchFailed) {
advancedRules?.strictMatchingFailedCallback?.();
return advancedRules?.defaultReturnValue ?? undefined;
}
return r;
}