import { FrontendVariables } from "@Front/Config/VariablesFront"; import CookieService from "@Front/Services/CookieService/CookieService"; import { uuid } from "uuidv4"; export enum ContentType { JSON = "application/json", PDF = "application/pdf", FORM_DATA = "multipart/form-data;", } export default abstract class BaseApiService { private static baseUrl: string; protected readonly variables = FrontendVariables.getInstance(); protected constructor() { BaseApiService.baseUrl ??= this.variables.BACK_API_PROTOCOL + this.variables.BACK_API_HOST + this.variables.BACK_API_ROOT_URL + this.variables.BACK_API_VERSION; } protected getBaseUrl(): string { return BaseApiService.baseUrl; } protected buildHeaders(contentType: ContentType) { const token = CookieService.getInstance().getCookie("leCoffreAccessToken"); const headers = new Headers(); if (contentType === ContentType.JSON || contentType === ContentType.PDF) { headers.set("Content-Type", contentType); } headers.set("Authorization", `Bearer ${token}`); return headers; } protected buildBody(body: { [key: string]: unknown }): string { return JSON.stringify(body); } protected async getRequest(url: URL, token?: string, contentType?: ContentType, filename?: string) { const request = async () => await fetch(url, { method: "GET", headers: this.buildHeaders(contentType ?? ContentType.JSON), }); return this.sendRequest(request, filename); } protected async postRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { return this.sendRequest( async () => await fetch(url, { method: "POST", headers: this.buildHeaders(ContentType.JSON), body: this.buildBody(body), }), ); } protected async postRequestFormData(url: URL, body: FormData) { return this.sendRequest( async () => await fetch(url, { method: "POST", headers: this.buildHeaders(ContentType.FORM_DATA), body, }), ); } protected async putRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { const request = async () => await fetch(url, { method: "PUT", headers: this.buildHeaders(ContentType.JSON), body: this.buildBody(body), }); return this.sendRequest(request); } protected async patchRequest(url: URL, body: { [key: string]: unknown } = {}) { const request = async () => await fetch(url, { method: "PATCH", headers: this.buildHeaders(ContentType.JSON), body: this.buildBody(body), }); return this.sendRequest(request); } protected async deleteRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { const request = async () => await fetch(url, { method: "DELETE", headers: this.buildHeaders(ContentType.JSON), body: this.buildBody(body), }); return this.sendRequest(request); } protected async putFormDataRequest(url: URL, body: FormData, token?: string) { const request = async () => await fetch(url, { method: "PUT", headers: this.buildHeaders(ContentType.FORM_DATA), body, }); return this.sendRequest(request); } private async sendRequest(request: () => Promise, filename?: string): Promise { const response = await request(); return this.processResponse(response, request, filename); } protected async processResponse(response: Response, request: () => Promise, filename?: string): Promise { let responseContent: T; if (response.ok) { // Check the Content-Type header to determine the response type const contentType = response.headers.get("Content-Type"); if (contentType && contentType.includes("application/octet-stream")) { // Handle PDF response const blob = await response.blob(); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = filename ?? `${uuid()}.pdf`; anchor.click(); URL.revokeObjectURL(url); responseContent = {} as T; } else { // Handle JSON response try { responseContent = await response.json(); } catch (err) { return Promise.reject(err); } } } else { // Handle error response try { const responseJson = await response.json(); return Promise.reject(responseJson); } catch (err) { return Promise.reject(err); } } return responseContent; } protected onError(error: unknown) { //console.error(error); } } export interface IResponse { http_status: number; }