import axios from "axios"; import { getCookie, setCookie } from "cookies-next"; import { getAuth } from "./auth"; type MethodType = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD"; type HeaderMap = Record; type PayloadMap = Record; interface AxiosParameters { method: MethodType; url: string; headers: HeaderMap; data?: string; } interface AuthPayload { token?: string; email?: string; // properti lain biarkan unknown [key: string]: unknown; } const API_HOST = process.env.NEXT_PUBLIC_ODOO_API_HOST ?? ""; /** ── Ambil service token dari /api/token (public) ─────────────────────────── */ const renewToken = async (): Promise => { const token = await axios.get(`${API_HOST}/api/token`); setCookie("token", token.data.result); return token.data.result as string; }; const getToken = async (): Promise => { let token = getCookie("token") as string | undefined; if (token == null) token = await renewToken(); return token; }; /** ── Hanya endpoint tertentu yang butuh Authorization service ─────────────── */ const SERVICE_AUTH_WHITELIST = [ "/api/token", "/api/v1/user/login", ]; const needsServiceAuth = (url: string) => SERVICE_AUTH_WHITELIST.some((p) => url.startsWith(p)); /** ── Client API utama ─────────────────────────────────────────────────────── */ const odooApi = async ( method: MethodType, url: string, data: PayloadMap = {}, headers: HeaderMap = {} ) => { try { const authObj = getAuth() as AuthPayload | string | null; const axiosParameter: AxiosParameters = { method, url: `${API_HOST}${url}`, headers: { ...headers }, }; // 1) PASANG Authorization HANYA untuk endpoint di whitelist if (needsServiceAuth(url)) { const bearer = await getToken(); if (bearer) { axiosParameter.headers["Authorization"] = bearer; } } // 2) PASANG header Token (user FE) bila ada if (authObj && typeof authObj === "object" && "token" in authObj) { const t = authObj.token; if (typeof t === "string" && t) { axiosParameter.headers["Token"] = t; } } const upper = method.toUpperCase() as MethodType; // 3) Body methods → gunakan x-www-form-urlencoded (sesuai backend kamu) if (upper === "POST" || upper === "PUT" || upper === "PATCH") { axiosParameter.headers["Content-Type"] = "application/x-www-form-urlencoded"; } // 4) Hanya kirim body untuk method yang pakai body if (Object.keys(data).length > 0 && upper !== "GET" && upper !== "HEAD") { const entries = Object.entries(data).filter( ([, v]) => typeof v === "string" && v !== "" ) as [string, string][]; axiosParameter.data = new URLSearchParams(entries).toString(); } const response = await axios(axiosParameter); return response.data as unknown; } catch (error) { console.log(JSON.stringify(error)); throw error; } }; export default odooApi;