import {AnyJson, ApiResponse, HydraMetadata} from '~/types/interfaces' import {METADATA_TYPE} from '~/types/enums' /** * Classe permettant d'assurer la dénormalization d'un objet Hydra en JSON */ class HydraDenormalizer { /** * Parcourt une réponse Hydra pour retourner son équivalent en Json * * @param {AnyJson} data * @return {AnyJson} réponse parsée */ public static denormalize (data: AnyJson): AnyJson { if (data['hydra:member']) { data.totalCount = data['hydra:totalItems'] return HydraDenormalizer.parseCollection(data) } else { return HydraDenormalizer.parseItem(data) } } private static parseItem (hydraData: AnyJson): ApiResponse { return { data: hydraData, metadata: HydraDenormalizer.definedMetadataForItem(hydraData) } } /** * Méthode de parsing appelé si on est dans un GET * * @param {AnyJson} hydraData */ private static definedMetadataForItem (hydraData: AnyJson): AnyJson { const metadata:HydraMetadata = {} // 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'] // } metadata.type = METADATA_TYPE.ITEM return metadata } /** * Méthode de parsing appelé si on est dans un GET Collection * * @param {AnyJson} hydraData */ private static parseCollection (hydraData: AnyJson): ApiResponse { const collectionResponse:ApiResponse = { data:hydraData['hydra:member'], metadata : HydraDenormalizer.definedMetadataForCollection(hydraData) } // collectionResponse.order = {} // collectionResponse.search = {} // Populate href property for all elements of the collection for (const key in collectionResponse.data) { const value = collectionResponse.data[key] HydraDenormalizer.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 } private static definedMetadataForCollection(data:AnyJson){ const metadata:HydraMetadata = { totalItems: data['hydra:totalItems'] } if(data['hydra:view']){ metadata.firstPage = HydraDenormalizer.getPageNumber(data['hydra:view']['hydra:first']) metadata.lastPage = HydraDenormalizer.getPageNumber(data['hydra:view']['hydra:last']) metadata.nextPage = HydraDenormalizer.getPageNumber(data['hydra:view']['hydra:next']) metadata.previousPage = HydraDenormalizer.getPageNumber(data['hydra:view']['hydra:previous']) } metadata.type = METADATA_TYPE.COLLECTION return metadata } private static getPageNumber(uri:string):number { if(uri){ const number = uri.split('page=').pop() return number ? parseInt(number) : 0 } return 0 } /** * 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) { HydraDenormalizer.populateAllData(value) } } } } export default HydraDenormalizer