UNPKG

oberknecht-utils

Version:
119 lines (107 loc) 4.21 kB
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; }