import type { Ref } from 'vue' import type { FetchContext, FetchOptions } from 'ofetch' import { TYPE_ALERT } from '~/types/enum/enums' import ApiRequestService from '~/services/data/apiRequestService' import { usePageStore } from '~/stores/page' import UnauthorizedError from '~/services/error/UnauthorizedError' import { useAccessProfileStore } from '~/stores/accessProfile' /** * Retourne une instance de ApiRequestService configurée pour interroger l'api Ap2i * * @see https://github.com/unjs/ohmyfetch/blob/main/README.md#%EF%B8%8F-create-fetch-with-default-options */ let apiRequestServiceClass: null | ApiRequestService = null export const useAp2iRequestService = () => { const runtimeConfig = useRuntimeConfig() const baseURL = runtimeConfig.baseUrl ?? runtimeConfig.public.baseUrl const pending: Ref = ref(false) /** * Peuple les headers avant l'envoi de la requête * * @param request * @param options */ const onRequest = function ({ request, options }: FetchContext) { // @ts-expect-error options is not aware of noXaccessId if (options && options.noXaccessId) { return } const accessProfileStore = useAccessProfileStore() const headers = new Headers(options.headers) headers.set('x-accessid', String(accessProfileStore.id)) headers.set('Authorization', 'BEARER ' + accessProfileStore.bearer) if (accessProfileStore.switchId) { headers.set('x-switch-user', String(accessProfileStore.switchId)) } options.headers = headers pending.value = true console.log('Request : ' + request + ' (SSR: ' + import.meta.server + ')') } const onRequestError = function (_: FetchContext) { pending.value = false } /** * Server responded */ const onResponse = function (_: FetchContext) { pending.value = false } /** * Gère les erreurs retournées par l'api * * @param request * @param response * @param error */ const onResponseError = function ({ response, error }: FetchContext) { pending.value = false if (response && response.status === 401) { throw new UnauthorizedError('Ap2i - Unauthorized') } else if (response && response.status === 403) { console.error('! Request error: Forbidden') usePageStore().addAlert(TYPE_ALERT.ALERT, ['forbidden']) } else if ( response && (response.status === 400 || response.status >= 404) ) { // @see https://developer.mozilla.org/fr/docs/Web/HTTP/Status let errorMsg if (error) { errorMsg = error.message } else if (response._data && response._data.detail) { errorMsg = response._data.detail } else if (response.statusText) { errorMsg = response.statusText } else { errorMsg = 'An error occured' } console.error('! Request error: ' + errorMsg) usePageStore().addAlert(TYPE_ALERT.ALERT, [errorMsg]) } } const config: FetchOptions = { baseURL, onRequest, onRequestError, onResponse, onResponseError, } // Avoid memory leak if (apiRequestServiceClass === null) { // Utilise la fonction `create` d'ohmyfetch pour générer un fetcher dédié à l'interrogation de Ap2i const fetcher = $fetch.create(config) apiRequestServiceClass = new ApiRequestService(fetcher) } return { apiRequestService: apiRequestServiceClass, pending } }