/** * @category Services/utils * @class ObjectProperties * Classe aidant à manipuler des Objets */ import {AnyJson} from "~/types/types"; class ObjectProperties { /** * Flatten un objet nested en un objet avec un seul niveau avec des noms de propriétés transformées comme cela 'foo.bar' * L'objet passé en paramètre reste inchangé car il est cloné * @example cloneAndFlatten({ a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } }, i: { j: 6 } }, ['i']) => { a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5, i: { j: 6 } } } * @param {AnyJson} object * @param {Array} excludedProperties * @param excludedProperties * @return {AnyJson} */ cloneAndFlatten(object:AnyJson, excludedProperties:Array = []):AnyJson { if (typeof object !== 'object') { throw new Error('Expecting an object parameter'); } return Object.keys(object).reduce((values: AnyJson, name: string) => { if (!object.hasOwnProperty(name)) return values; if (this.isObject(object[name])) { if (excludedProperties.indexOf(name) === -1) { let flatObject = this.cloneAndFlatten(object[name]); Object.keys(flatObject).forEach(flatObjectKey => { if (!flatObject.hasOwnProperty(flatObjectKey)) return; values[name + '.' + flatObjectKey] = flatObject[flatObjectKey]; }) } else { values[name] = this.clone(object[name]); } } else { values[name] = object[name]; } return values; }, {}); }; /** * Trasnforme un objet flattened en un objet nested. L'objet passé en paramètre reste inchangé * @example cloneAndNest({ a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5 } ) => { a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } } } * @param {AnyJson} object * @return {AnyJson} */ cloneAndNest(object:AnyJson):AnyJson { if (typeof object !== 'object') { throw new Error('Expecting an object parameter'); } return Object.keys(object).reduce((values, name) => { if (!object.hasOwnProperty(name)) return values; name.split('.').reduce((previous: AnyJson, current: string, index: number, list: Array) => { if (previous != null) { if (typeof previous[current] === 'undefined') previous[current] = {}; if (index < (list.length - 1)) { return previous[current]; }; previous[current] = object[name]; } }, values) return values; }, {}) } /** * Test si le paramètre est un objet * @param {AnyJson} value * @return {boolean} */ isObject(value:any):boolean { if (value === null) return false; if (typeof value !== 'object') return false; if (Array.isArray(value)) return false; if (Object.prototype.toString.call(value) === '[object Date]') return false; return true; } /** * Clone l'objet et ces propriétés. * @param {Object} object * @return {Object} */ clone(object: AnyJson): AnyJson { return Object.keys(object).reduce((values: AnyJson, name: string) => { if (object.hasOwnProperty(name)) { values[name] = object[name]; } return values; }, {}); } } export const $objectProperties = new ObjectProperties()