hydra.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. return {
  28. data: hydraData,
  29. metadata: Hydra.definedMetadataForItem(hydraData)
  30. }
  31. }
  32. /**
  33. * Méthode de parsing appelé si on est dans un GET
  34. *
  35. * @param {AnyJson} hydraData
  36. */
  37. private static definedMetadataForItem (hydraData: AnyJson): AnyJson {
  38. const metadata:HydraMetadata = {}
  39. // if (hydraData['hydra:previous']) {
  40. // const iriParts = hydraData['hydra:previous'].split('/')
  41. // hydraData.previous = iriParts[iriParts.length - 1]
  42. // }
  43. // if (hydraData['hydra:next']) {
  44. // const iriParts = hydraData['hydra:next'].split('/')
  45. // hydraData.next = iriParts[iriParts.length - 1]
  46. // }
  47. // if (hydraData['hydra:totalItems']) {
  48. // hydraData.totalItems = hydraData['hydra:totalItems']
  49. // }
  50. // if (hydraData['hydra:itemPosition']) {
  51. // hydraData.itemPosition = hydraData['hydra:itemPosition']
  52. // }
  53. metadata.type = METADATA_TYPE.ITEM
  54. return metadata
  55. }
  56. /**
  57. * Méthode de parsing appelé si on est dans un GET Collection
  58. *
  59. * @param {AnyJson} hydraData
  60. */
  61. private static parseCollection (hydraData: AnyJson): ApiResponse {
  62. const collectionResponse:ApiResponse = {
  63. data:hydraData['hydra:member'],
  64. metadata : Hydra.definedMetadataForCollection(hydraData)
  65. }
  66. // collectionResponse.order = {}
  67. // collectionResponse.search = {}
  68. // Populate href property for all elements of the collection
  69. for (const key in collectionResponse.data) {
  70. const value = collectionResponse.data[key]
  71. Hydra.populateAllData(value)
  72. }
  73. // if (typeof (hydraData['hydra:search']) !== 'undefined') {
  74. // const collectionSearch = hydraData['hydra:search']['hydra:mapping']
  75. // for (const key in collectionSearch) {
  76. // const value = collectionSearch[key]
  77. // if (value.variable.indexOf('filter[order]') === 0) {
  78. // collectionResponse.order[value.property] = value
  79. // } else if (value.variable.indexOf('filter[where]') === 0) {
  80. // collectionResponse.search[value.property] = value
  81. // }
  82. // }
  83. // }
  84. return collectionResponse
  85. }
  86. private static definedMetadataForCollection(data:AnyJson){
  87. const metadata:HydraMetadata = {
  88. totalItems: data['hydra:totalItems']
  89. }
  90. if(data['hydra:view']){
  91. metadata.firstPage = Hydra.getPageNumber(data['hydra:view']['hydra:first'])
  92. metadata.lastPage = Hydra.getPageNumber(data['hydra:view']['hydra:last'])
  93. metadata.nextPage = Hydra.getPageNumber(data['hydra:view']['hydra:next'])
  94. metadata.previousPage = Hydra.getPageNumber(data['hydra:view']['hydra:previous'])
  95. }
  96. metadata.type = METADATA_TYPE.COLLECTION
  97. return metadata
  98. }
  99. private static getPageNumber(uri:string):number {
  100. if(uri){
  101. const number = uri.split('page=').pop()
  102. return number ? parseInt(number) : 0
  103. }
  104. return 0
  105. }
  106. /**
  107. * Hydrate l'objet JSON de façon récursive (afin de gérer les objet nested)
  108. *
  109. * @param {AnyJson} data
  110. */
  111. private static populateAllData (data: AnyJson): void {
  112. for (const key in data) {
  113. const value = data[key]
  114. if (value instanceof Object) {
  115. Hydra.populateAllData(value)
  116. }
  117. }
  118. }
  119. }
  120. export default Hydra