import { useStorage } from "@vueuse/core"; export default defineNuxtPlugin((nuxtApp) => { // ====================== // Runtime Config (Public) // ====================== const config = useRuntimeConfig(); const BASE_URL = config.public.NUXT_PUBLIC_BASE_URL || ""; const API_NAME = config.public.NUXT_PUBLIC_API_NAME || ""; // ====================== // Safe URL Joiner // ====================== const joinURL = (base: string, path: string) => { return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`; }; const baseURL = joinURL(BASE_URL, API_NAME); // ====================== // Reactive Token // ====================== const token = useStorage("id_token", "GuestAccess"); // ====================== // Fetch Instance // ====================== const api = $fetch.create({ baseURL, // ====================== // Request Interceptor // ====================== onRequest({ options }) { const auth = token.value; if (!auth) return; const headers = (options.headers ||= {}); if (headers instanceof Headers) { headers.set("Authorization", auth); } else if (Array.isArray(headers)) { headers.push(["Authorization", auth]); } else { headers.Authorization = auth; } }, // ====================== // Response Handler // ====================== onResponse({ response }) { return response._data; }, // ====================== // Error Handler // ====================== async onResponseError({ response }) { const status = response?.status; if (status === 401) { token.value = null; await nuxtApp.runWithContext(() => navigateTo("/login")); } throw { status, message: response?._data?.message || response?.statusText || "خطای نامشخص", data: response?._data || null, }; }, }); // ====================== // HTTP Service (Public API) // ====================== const http = { getRequest: (url: string, options: any = {}) => api(url, { method: "GET", ...options }), postRequest: (url: string, body: any, options: any = {}) => api(url, { method: "POST", body, ...options }), putRequest: (url: string, body: any, options: any = {}) => api(url, { method: "PUT", body, ...options }), patchRequest: (url: string, body: any, options: any = {}) => api(url, { method: "PATCH", body, ...options }), deleteRequest: (url: string, options: any = {}) => api(url, { method: "DELETE", ...options }), }; // ====================== // Provide to Nuxt // ====================== return { provide: { http, }, }; });