hydraDenormalizer.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {AnyJson, ApiResponse, HydraMetadata} from '~/types/data'
  2. import UrlUtils from '~/services/utils/urlUtils'
  3. import {METADATA_TYPE} from '~/types/enum/data'
  4. /**
  5. * Normalisation et dé-normalisation ddu format de données Hydra
  6. */
  7. class HydraDenormalizer {
  8. /**
  9. * Parse une réponse Hydra et retourne un objet ApiResponse
  10. *
  11. * @param {AnyJson} data
  12. * @return {AnyJson} réponse parsée
  13. */
  14. public static denormalize(data: AnyJson): ApiResponse {
  15. return {
  16. data: HydraDenormalizer.getData(data),
  17. metadata: HydraDenormalizer.getMetadata(data)
  18. }
  19. }
  20. protected static getData(hydraData: AnyJson): AnyJson {
  21. if (hydraData['@type'] === 'hydra:Collection') {
  22. let members = hydraData['hydra:member']
  23. let results = []
  24. for (let item of members) {
  25. results.push(HydraDenormalizer.denormalizeItem(item))
  26. }
  27. return results
  28. } else {
  29. return HydraDenormalizer.denormalizeItem(hydraData)
  30. }
  31. }
  32. /**
  33. * Dénormalise un item d'une réponse hydra
  34. *
  35. * @param item
  36. * @protected
  37. */
  38. protected static denormalizeItem(item: AnyJson): AnyJson {
  39. for (let key in item) {
  40. if (item.hasOwnProperty(key)) {
  41. let value = item[key]
  42. // If value is an array of URIs (ex: `/api/persons/1`), replace this array with an array of numeric ids (ex: `1`)
  43. if (
  44. Array.isArray(value) &&
  45. value.length > 0 &&
  46. typeof value[0] === 'string' &&
  47. value[0].match(/\/api\/[\w\/]+\d+/)
  48. ) {
  49. let childrenIds: Array<number> = []
  50. for (let child of value) {
  51. childrenIds.push(UrlUtils.extractIdFromUri(child) as number)
  52. }
  53. item[key] = childrenIds
  54. }
  55. }
  56. }
  57. return item
  58. }
  59. /**
  60. * Génère les métadonnées d'un item ou d'une collection
  61. *
  62. * @param data
  63. * @protected
  64. */
  65. protected static getMetadata(data: AnyJson): HydraMetadata {
  66. if (data['@type'] !== 'hydra:Collection') {
  67. // A single item, no metadata
  68. return { type: METADATA_TYPE.ITEM }
  69. }
  70. const metadata: HydraMetadata = {
  71. totalItems: data['hydra:totalItems']
  72. }
  73. if (data['hydra:view']) {
  74. /**
  75. * Extract the page number from the IRIs in the hydra:view section
  76. */
  77. const extractPageNumber = (pos: string, default_: number | undefined=undefined): number | undefined => {
  78. const iri = data['hydra:view']['hydra:' + pos]
  79. if (!iri) {
  80. return default_
  81. }
  82. return UrlUtils.getParameter(
  83. data['hydra:view']['hydra:' + pos],
  84. 'page',
  85. default_
  86. ) as number | undefined
  87. }
  88. // TODO: utile d'ajouter la page en cours?
  89. metadata.firstPage = extractPageNumber('first', 1)
  90. metadata.lastPage = extractPageNumber('last', 1)
  91. metadata.nextPage = extractPageNumber('next')
  92. metadata.previousPage = extractPageNumber('previous')
  93. }
  94. metadata.type = METADATA_TYPE.COLLECTION
  95. return metadata
  96. }
  97. }
  98. export default HydraDenormalizer