hydraDenormalizer.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import {AnyJson, ApiResponse, HydraMetadata, METADATA_TYPE} from "~/types/data.d";
  2. import Url from "~/services/utils/url";
  3. /**
  4. * Classe permettant d'assurer la dé-normalization d'un objet Hydra en JSON
  5. */
  6. class HydraDenormalizer {
  7. /**
  8. * Parse une réponse Hydra pour retourner son équivalent en Json
  9. *
  10. * @param {AnyJson} data
  11. * @return {AnyJson} réponse parsée
  12. */
  13. public static denormalize (data: AnyJson): ApiResponse {
  14. if (data['hydra:member']) {
  15. return HydraDenormalizer.parseCollection(data)
  16. }
  17. return HydraDenormalizer.parseItem(data)
  18. }
  19. /**
  20. * Parse une réponse Hydra contenant un item
  21. *
  22. * @param hydraData
  23. * @private
  24. */
  25. private static parseItem (hydraData: AnyJson): ApiResponse {
  26. return {
  27. data: hydraData,
  28. metadata: HydraDenormalizer.constructMetadataForItem(hydraData)
  29. }
  30. }
  31. /**
  32. * Méthode de parsing appelé si on est dans un GET Collection
  33. *
  34. * @param {AnyJson} hydraData
  35. */
  36. private static parseCollection (hydraData: AnyJson): ApiResponse {
  37. const collectionResponse:ApiResponse = {
  38. data:hydraData['hydra:member'],
  39. metadata : HydraDenormalizer.constructMetadataForCollection(hydraData)
  40. }
  41. // collectionResponse.order = {}
  42. // collectionResponse.search = {}
  43. // Populate href property for all elements of the collection
  44. for (const key in collectionResponse.data) {
  45. const value = collectionResponse.data[key]
  46. HydraDenormalizer.populateAllData(value)
  47. }
  48. // if (typeof (hydraData['hydra:search']) !== 'undefined') {
  49. // const collectionSearch = hydraData['hydra:search']['hydra:mapping']
  50. // for (const key in collectionSearch) {
  51. // const value = collectionSearch[key]
  52. // if (value.variable.indexOf('filter[order]') === 0) {
  53. // collectionResponse.order[value.property] = value
  54. // } else if (value.variable.indexOf('filter[where]') === 0) {
  55. // collectionResponse.search[value.property] = value
  56. // }
  57. // }
  58. // }
  59. return collectionResponse
  60. }
  61. /**
  62. * Génère les metadonnées d'un item
  63. *
  64. * @param {AnyJson} hydraData
  65. */
  66. private static constructMetadataForItem (hydraData: AnyJson): AnyJson {
  67. const metadata: HydraMetadata = {}
  68. // if (hydraData['hydra:previous']) {
  69. // const iriParts = hydraData['hydra:previous'].split('/')
  70. // hydraData.previous = iriParts[iriParts.length - 1]
  71. // }
  72. // if (hydraData['hydra:next']) {
  73. // const iriParts = hydraData['hydra:next'].split('/')
  74. // hydraData.next = iriParts[iriParts.length - 1]
  75. // }
  76. // if (hydraData['hydra:totalItems']) {
  77. // hydraData.totalItems = hydraData['hydra:totalItems']
  78. // }
  79. // if (hydraData['hydra:itemPosition']) {
  80. // hydraData.itemPosition = hydraData['hydra:itemPosition']
  81. // }
  82. metadata.type = METADATA_TYPE.ITEM
  83. return metadata
  84. }
  85. /**
  86. * Génère les métadonnées d'une collection
  87. *
  88. * @param data
  89. * @private
  90. */
  91. private static constructMetadataForCollection(data:AnyJson){
  92. const metadata: HydraMetadata = {
  93. totalItems: data['hydra:totalItems']
  94. }
  95. if(data['hydra:view']){
  96. metadata.firstPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:first'], 1) as number
  97. metadata.lastPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:last'], 1) as number
  98. metadata.nextPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:next']) ?? undefined
  99. metadata.previousPage = HydraDenormalizer.getPageFromUri(data['hydra:view']['hydra:previous']) ?? undefined
  100. }
  101. metadata.type = METADATA_TYPE.COLLECTION
  102. return metadata
  103. }
  104. /**
  105. * Hydrate l'objet JSON de façon récursive (afin de gérer les objet nested)
  106. *
  107. * @param {AnyJson} data
  108. */
  109. private static populateAllData (data: AnyJson): void {
  110. for (const key in data) {
  111. const value = data[key]
  112. if (value instanceof Object) {
  113. HydraDenormalizer.populateAllData(value)
  114. }
  115. }
  116. }
  117. private static getPageFromUri(uri: string, default_: number | null = null): number | null {
  118. const url = 'https://foo' + uri // Pour que l'uri partielle soit parsée, on doit y ajouter une url de base bidon
  119. const page = Url.getParameter(url, 'page')
  120. return page ? parseInt(page) : default_
  121. }
  122. }
  123. export default HydraDenormalizer