useAp2iRequestService.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import type { Ref } from 'vue'
  2. import type { FetchContext, FetchOptions } from 'ofetch'
  3. import { TYPE_ALERT } from '~/types/enum/enums'
  4. import ApiRequestService from '~/services/data/apiRequestService'
  5. import { usePageStore } from '~/stores/page'
  6. import UnauthorizedError from '~/services/error/UnauthorizedError'
  7. import { useAccessProfileStore } from '~/stores/accessProfile'
  8. import type { AssociativeArray } from '~/types/data'
  9. /**
  10. * Retourne une instance de ApiRequestService configurée pour interroger l'api Ap2i
  11. *
  12. * @see https://github.com/unjs/ohmyfetch/blob/main/README.md#%EF%B8%8F-create-fetch-with-default-options
  13. */
  14. let apiRequestServiceClass: null | ApiRequestService = null
  15. export const useAp2iRequestService = () => {
  16. const runtimeConfig = useRuntimeConfig()
  17. const baseURL = runtimeConfig.baseUrl ?? runtimeConfig.public.baseUrl
  18. const pending: Ref<boolean> = ref(false)
  19. /**
  20. * Peuple les headers avant l'envoi de la requête
  21. *
  22. * @param request
  23. * @param options
  24. */
  25. const onRequest = function ({ request, options }: FetchContext) {
  26. // @ts-expect-error options is not aware of noXaccessId
  27. if (options && options.noXaccessId) {
  28. return
  29. }
  30. const accessProfileStore = useAccessProfileStore()
  31. const headers: AssociativeArray = {
  32. 'x-accessid': String(accessProfileStore.id),
  33. Authorization: 'BEARER ' + accessProfileStore.bearer,
  34. }
  35. if (accessProfileStore.switchId) {
  36. headers['x-switch-user'] = String(accessProfileStore.switchId)
  37. }
  38. options.headers = { ...options.headers, ...headers }
  39. pending.value = true
  40. console.log('Request : ' + request + ' (SSR: ' + process.server + ')')
  41. }
  42. const onRequestError = function (_: FetchContext) {
  43. pending.value = false
  44. }
  45. /**
  46. * Server responded
  47. */
  48. const onResponse = function (_: FetchContext) {
  49. pending.value = false
  50. }
  51. /**
  52. * Gère les erreurs retournées par l'api
  53. *
  54. * @param request
  55. * @param response
  56. * @param error
  57. */
  58. const onResponseError = function ({ response, error }: FetchContext) {
  59. pending.value = false
  60. if (response && response.status === 401) {
  61. throw new UnauthorizedError('Ap2i - Unauthorized')
  62. } else if (response && response.status === 403) {
  63. console.error('! Request error: Forbidden')
  64. usePageStore().addAlert(TYPE_ALERT.ALERT, ['forbidden'])
  65. } else if (
  66. response &&
  67. (response.status === 400 || response.status >= 404)
  68. ) {
  69. // @see https://developer.mozilla.org/fr/docs/Web/HTTP/Status
  70. const errorMsg = error ? error.message : response.statusText
  71. console.error('! Request error: ' + errorMsg)
  72. usePageStore().addAlert(TYPE_ALERT.ALERT, [errorMsg])
  73. }
  74. }
  75. const config: FetchOptions = {
  76. baseURL,
  77. onRequest,
  78. onRequestError,
  79. onResponse,
  80. onResponseError,
  81. }
  82. // Avoid memory leak
  83. if (apiRequestServiceClass === null) {
  84. // Utilise la fonction `create` d'ohmyfetch pour générer un fetcher dédié à l'interrogation de Ap2i
  85. const fetcher = $fetch.create(config)
  86. apiRequestServiceClass = new ApiRequestService(fetcher)
  87. }
  88. return { apiRequestService: apiRequestServiceClass, pending }
  89. }