import { TypeAndRecordOfType } from "../_types/types"; class Objects { /** * Effectue une comparaison d'égalité non profonde entre deux objets. */ /*eslint-disable @typescript-eslint/no-explicit-any*/ static shallowEqual(object1: any, object2: any, useStrictComparaison = true) { const keys1 = Object.keys(object1); const keys2 = Object.keys(object2); if (keys1.length !== keys2.length && useStrictComparaison) { return false; } for (const key of keys1) { const val1 = object1[key]; const val2 = object2[key]; const areEqual = useStrictComparaison ? val1 !== val2 : val1 != val2; if (areEqual) { return false; } } return true; } /*eslint-enable @typescript-eslint/no-explicit-any*/ /** * Effectue une comparaison d'égalité profonde entre deux objets. */ /*eslint-disable @typescript-eslint/no-explicit-any*/ static deepEqual(object1: any, object2: any, useStrictComparaison = true) { const keys1 = Object.keys(object1); const keys2 = Object.keys(object2); if (keys1.length !== keys2.length && useStrictComparaison) { return false; } for (const key of keys1) { const val1 = object1[key]; const val2 = object2[key]; const areObjects = Objects.isObject(val1) && Objects.isObject(val2); const areEqual = useStrictComparaison ? val1 !== val2 : val1 != val2; if ( (areObjects && !Objects.deepEqual(val1, val2)) || (!areObjects && areEqual) ) { return false; } } return true; } /*eslint-enable @typescript-eslint/no-explicit-any*/ /** * @returns true si l'objet est un objet ou un tableau (qui est un objet). mais false si null (car sinon typeof null "object") */ static isObject(object: T) { return object != null && typeof object === "object"; } /** * @returns true si l'argument est null ou undefined */ static isUndefindOrNull(object: T) { return object === null || object === undefined; } static isEmpty(object: Record) { if (Objects.isUndefindOrNull(object)) return true; return Object.keys(object).length === 0; } /** * traverse l'objet pour obtenir la valeur a l'adresse donnée via le tableau de clés pathArray. * Si extendValues = true, les propriétés des objets parents sont copiées au fur et a mesure de la descente dans la hierarchie, avant l'assignation des propriétés de l'objet lui même. */ /*eslint-disable @typescript-eslint/no-explicit-any*/ static traverse(obj: any, pathArray: string[], extendValues = false) { for (const key of pathArray) { const newObj = obj[key]; if (newObj === undefined) { return undefined; } if (extendValues && Objects.isObject(newObj)) { obj = Object.assign(Array.isArray(newObj) ? [] : {}, obj, newObj); } else { obj = obj[key]; } } return obj; } static traverseDotNotation( obj: Record, path: string, extendValues = false ) { return Objects.traverse(obj, path.split("."), extendValues); } /*eslint-enable @typescript-eslint/no-explicit-any*/ static getURLSearchArray( sourceObject?: TypeAndRecordOfType, prefix = "" ) { let arr: string[] = []; for (let key in sourceObject) { const value = (sourceObject as TypeAndRecordOfType)[key]; if (prefix) key = prefix + "[" + key + "]"; if (Objects.isObject(value)) { arr = [ ...arr, ...this.getURLSearchArray(value as TypeAndRecordOfType, key), ]; } else { arr.push(`${key}=${value}`); } } return arr; } static getURLSearchString(sourceObject: TypeAndRecordOfType) { return Objects.getURLSearchArray(sourceObject, "").join("&"); } } export default Objects; export const traverseDotNotation = Objects.traverseDotNotation;