hydra.ts 4.2 KB

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