/** * Commercial registry HTTP — Core Commercial APIs only. * Supports: ready | empty | unavailable | permission_denied | error * Never invents catalog rows. */ import { getValidAccessToken } from "@/lib/auth"; import type { AdapterResult, RegistryAvailability } from "../types"; const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL || process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000"; async function authHeaders(): Promise { const headers = new Headers({ "Content-Type": "application/json" }); const token = await getValidAccessToken(); if (token) headers.set("Authorization", `Bearer ${token}`); return headers; } function availabilityFromStatus(status: number): RegistryAvailability { if (status === 401 || status === 403) return "permission_denied"; if (status === 404 || status === 501 || status === 502 || status === 503) { return "unavailable"; } return "error"; } export async function commercialGet( path: string ): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> { try { const res = await fetch(`${API_BASE}${path}`, { headers: await authHeaders() }); if (!res.ok) { const body = await res.json().catch(() => ({})); return { ok: false, status: res.status, availability: availabilityFromStatus(res.status), message: (body as { error?: { message?: string } })?.error?.message || res.statusText || "درخواست ناموفق", }; } return { ok: true, data: (await res.json()) as T }; } catch (err) { return { ok: false, status: 0, availability: "unavailable", message: err instanceof Error ? err.message : "خطای شبکه", }; } } export async function commercialPost( path: string, body: unknown ): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> { return commercialMutate("POST", path, body); } export async function commercialPut( path: string, body: unknown ): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> { return commercialMutate("PUT", path, body); } export async function commercialPatch( path: string, body: unknown ): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> { return commercialMutate("PATCH", path, body); } export async function commercialDelete( path: string ): Promise<{ ok: true; data: null } | { ok: false; availability: RegistryAvailability; message: string; status: number }> { try { const res = await fetch(`${API_BASE}${path}`, { method: "DELETE", headers: await authHeaders(), }); if (!res.ok) { const payload = await res.json().catch(() => ({})); return { ok: false, status: res.status, availability: availabilityFromStatus(res.status), message: (payload as { error?: { message?: string } })?.error?.message || res.statusText || "حذف ناموفق", }; } return { ok: true, data: null }; } catch (err) { return { ok: false, status: 0, availability: "unavailable", message: err instanceof Error ? err.message : "خطای شبکه", }; } } async function commercialMutate( method: "POST" | "PUT" | "PATCH", path: string, body: unknown ): Promise<{ ok: true; data: T } | { ok: false; availability: RegistryAvailability; message: string; status: number }> { try { const res = await fetch(`${API_BASE}${path}`, { method, headers: await authHeaders(), body: JSON.stringify(body), }); if (!res.ok) { const payload = await res.json().catch(() => ({})); return { ok: false, status: res.status, availability: availabilityFromStatus(res.status), message: (payload as { error?: { message?: string } })?.error?.message || res.statusText || "درخواست ناموفق", }; } if (res.status === 204) return { ok: true, data: {} as T }; return { ok: true, data: (await res.json()) as T }; } catch (err) { return { ok: false, status: 0, availability: "unavailable", message: err instanceof Error ? err.message : "خطای شبکه", }; } } /** Extract items array from common commercial list envelopes. */ export function extractItems(payload: unknown, keys: string[]): T[] { if (!payload || typeof payload !== "object") return []; const obj = payload as Record; for (const key of keys) { const v = obj[key]; if (Array.isArray(v)) return v as T[]; } if (Array.isArray(payload)) return payload as T[]; return []; } export function listResult( items: T[], source: string, emptyMessage?: string ): AdapterResult { return { availability: items.length ? "ready" : "empty", data: items, source, message: items.length ? undefined : emptyMessage, }; } export function failResult( availability: RegistryAvailability, message: string, empty: T ): AdapterResult { return { availability, data: empty, message, source: "none" }; }