import { AnyJson } from '~/types/interfaces' import BaseDenormalizer from '~/services/serializer/denormalizer/baseDenormalizer' import { DENORMALIZER_TYPE } from '~/types/enums' /** * Classe permettant d'assurer la dénormalization d'un objet Hydra en JSON */ class Hydra extends BaseDenormalizer { static support (type: DENORMALIZER_TYPE): boolean { return type === DENORMALIZER_TYPE.HYDRA } /** * Parcourt une réponse Hydra pour retourner son équivalent en Json * * @param {AnyJson} hydraData * @return {AnyJson} réponse parsée */ public static denormalize (hydraData: AnyJson): AnyJson { if (hydraData['hydra:member']) { hydraData.totalCount = hydraData['hydra:totalItems'] return Hydra.parseCollection(hydraData) } else { return Hydra.parseItem(hydraData) } } /** * Méthode de parsing appelé si on est dans un GET * * @param {AnyJson} hydraData */ private static parseItem (hydraData: AnyJson): AnyJson { if (hydraData['hydra:previous']) { const iriParts = hydraData['hydra:previous'].split('/') hydraData.previous = iriParts[iriParts.length - 1] } if (hydraData['hydra:next']) { const iriParts = hydraData['hydra:next'].split('/') hydraData.next = iriParts[iriParts.length - 1] } if (hydraData['hydra:totalItems']) { hydraData.totalItems = hydraData['hydra:totalItems'] } if (hydraData['hydra:itemPosition']) { hydraData.itemPosition = hydraData['hydra:itemPosition'] } return hydraData } /** * Méthode de parsing appelé si on est dans un GET Collection * * @param {AnyJson} hydraData */ private static parseCollection (hydraData: AnyJson): AnyJson { const collectionResponse = hydraData['hydra:member'] collectionResponse.metadata = {} collectionResponse.order = {} collectionResponse.search = {} // Put metadata in a property of the collection for (const key in hydraData) { const value = hydraData[key] if (key !== 'hydra:member') { collectionResponse.metadata[key] = value } } // Populate href property for all elements of the collection for (const key in collectionResponse) { const value = collectionResponse[key] Hydra.populateAllData(value) } if (typeof (hydraData['hydra:search']) !== 'undefined') { const collectionSearch = hydraData['hydra:search']['hydra:mapping'] for (const key in collectionSearch) { const value = collectionSearch[key] if (value.variable.indexOf('filter[order]') === 0) { collectionResponse.order[value.property] = value } else if (value.variable.indexOf('filter[where]') === 0) { collectionResponse.search[value.property] = value } } } return collectionResponse } /** * Hydrate l'objet JSON de façon récursive (afin de gérer les objet nested) * * @param {AnyJson} data */ private static populateAllData (data: AnyJson): void { for (const key in data) { const value = data[key] if (value instanceof Object) { Hydra.populateAllData(value) } } } } export default Hydra