hydraDenormalizer.ts 4.3 KB

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