|
|
@@ -1,144 +1,71 @@
|
|
|
-import {AnyJson, ApiResponse, HydraMetadata} from "~/types/data";
|
|
|
-import Url from "~/services/utils/url";
|
|
|
-import {METADATA_TYPE} from "~/types/enum/data";
|
|
|
+import {AnyJson, ApiResponse, HydraMetadata} from '~/types/data'
|
|
|
+import UrlUtils from '~/services/utils/urlUtils'
|
|
|
+import {METADATA_TYPE} from '~/types/enum/data'
|
|
|
|
|
|
/**
|
|
|
- * Classe permettant d'assurer la dé-normalization d'un objet Hydra en JSON
|
|
|
+ * Classe permettant d'assurer la dénormalization d'un objet Hydra en JSON
|
|
|
*/
|
|
|
class HydraDenormalizer {
|
|
|
/**
|
|
|
* Parse une réponse Hydra pour retourner son équivalent en Json
|
|
|
*
|
|
|
- * @param {AnyJson} data
|
|
|
+ * @param {AnyJson} hydraData
|
|
|
* @return {AnyJson} réponse parsée
|
|
|
*/
|
|
|
- public static denormalize (data: AnyJson): ApiResponse {
|
|
|
- if (data['hydra:member']) {
|
|
|
- return HydraDenormalizer.parseCollection(data)
|
|
|
- }
|
|
|
-
|
|
|
- return HydraDenormalizer.parseItem(data)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Parse une réponse Hydra contenant un item
|
|
|
- *
|
|
|
- * @param hydraData
|
|
|
- * @private
|
|
|
- */
|
|
|
- private static parseItem (hydraData: AnyJson): ApiResponse {
|
|
|
+ public static denormalize(hydraData: AnyJson): ApiResponse {
|
|
|
return {
|
|
|
- data: hydraData,
|
|
|
- metadata: HydraDenormalizer.constructMetadataForItem(hydraData)
|
|
|
+ data: HydraDenormalizer.getData(hydraData),
|
|
|
+ metadata: HydraDenormalizer.getMetadata(hydraData)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 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.constructMetadataForCollection(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
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Génère les metadonnées d'un item
|
|
|
- *
|
|
|
- * @param {AnyJson} hydraData
|
|
|
- */
|
|
|
- private static constructMetadataForItem (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
|
|
|
-
|
|
|
+ protected static getData(hydraData: AnyJson): AnyJson {
|
|
|
+ return hydraData['@type'] === 'hydra:Collection' ? hydraData['hydra:member'] : hydraData
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Génère les métadonnées d'une collection
|
|
|
+ * Génère les métadonnées d'un item ou d'une collection
|
|
|
*
|
|
|
* @param data
|
|
|
- * @private
|
|
|
+ * @protected
|
|
|
*/
|
|
|
- private static constructMetadataForCollection(data:AnyJson){
|
|
|
+ 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']){
|
|
|
- metadata.firstPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:first'], 1) as number
|
|
|
- metadata.lastPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:last'], 1) as number
|
|
|
- metadata.nextPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:next']) ?? undefined
|
|
|
- metadata.previousPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:previous']) ?? undefined
|
|
|
+ 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
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 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)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static getPageFromUri(uri: string, default_: number | null = null): number | null {
|
|
|
- const url = 'https://foo' + uri // Pour que l'uri partielle soit parsée, on doit y ajouter une url de base bidon
|
|
|
- const page = Url.getParameter(url, 'page')
|
|
|
- return page ? parseInt(page) : default_
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
export default HydraDenormalizer
|