import {AnyJson, ApiResponse, HydraMetadata} from '~/types/data' import UrlUtils from '~/services/utils/urlUtils' import {METADATA_TYPE} from '~/types/enum/data' /** * Normalisation et dé-normalisation ddu format de données Hydra */ class HydraDenormalizer { /** * Parse une réponse Hydra et retourne un objet ApiResponse * * @param {AnyJson} data * @return {AnyJson} réponse parsée */ public static denormalize(data: AnyJson): ApiResponse { return { data: HydraDenormalizer.getData(data), metadata: HydraDenormalizer.getMetadata(data) } } protected static getData(hydraData: AnyJson): AnyJson { if (hydraData['@type'] === 'hydra:Collection') { let members = hydraData['hydra:member'] let results = [] for (let item of members) { results.push(HydraDenormalizer.denormalizeItem(item)) } return results } else { return HydraDenormalizer.denormalizeItem(hydraData) } } /** * Dénormalise un item d'une réponse hydra * * @param item * @protected */ protected static denormalizeItem(item: AnyJson): AnyJson { for (let key in item) { if (item.hasOwnProperty(key)) { let value = item[key] // If value is an array of URIs (ex: `/api/persons/1`), replace this array with an array of numeric ids (ex: `1`) if ( Array.isArray(value) && value.length > 0 && typeof value[0] === 'string' && value[0].match(/\/api\/[\w\/]+\d+/) ) { let childrenIds: Array = [] for (let child of value) { childrenIds.push(UrlUtils.extractIdFromUri(child) as number) } item[key] = childrenIds } } } return item } /** * Génère les métadonnées d'un item ou d'une collection * * @param data * @protected */ protected static getMetadata(data: AnyJson): HydraMetadata { if (data['@type'] !== 'hydra:Collection') { // A single item, no metadata return { type: METADATA_TYPE.ITEM } } const metadata: HydraMetadata = { totalItems: data['hydra:totalItems'] } if (data['hydra:view']) { /** * Extract the page number from the IRIs in the hydra:view section */ const extractPageNumber = (pos: string, default_: number | undefined=undefined): number | undefined => { const iri = data['hydra:view']['hydra:' + pos] if (!iri) { return default_ } return UrlUtils.getParameter( data['hydra:view']['hydra:' + pos], 'page', default_ ) as number | undefined } // TODO: utile d'ajouter la page en cours? metadata.firstPage = extractPageNumber('first', 1) metadata.lastPage = extractPageNumber('last', 1) metadata.nextPage = extractPageNumber('next') metadata.previousPage = extractPageNumber('previous') } metadata.type = METADATA_TYPE.COLLECTION return metadata } } export default HydraDenormalizer