const API_BASE = (typeof window === 'undefined' ? process.env.API_INTERNAL_URL : process.env.NEXT_PUBLIC_API_URL) ?? process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:4000/api/v1' export class MarketplaceApiError extends Error { status: number code?: string nextAvailableAt?: string | null constructor(message: string, status: number, code?: string, nextAvailableAt?: string | null) { super(message) this.name = 'MarketplaceApiError' this.status = status this.code = code this.nextAvailableAt = nextAvailableAt } } export async function marketplaceFetch(path: string, init?: RequestInit): Promise { const res = await fetch(`${API_BASE}${path}`, { cache: 'no-store', credentials: 'include', ...init, }) const json = await res.json().catch(() => null) if (!res.ok) throw new MarketplaceApiError(json?.message ?? 'Request failed', res.status, json?.error, json?.nextAvailableAt) return json.data as T } export async function marketplaceFetchOrDefault(path: string, fallback: T): Promise { try { return await marketplaceFetch(path) } catch { return fallback } } export async function marketplacePost(path: string, body: unknown): Promise { const base = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:4000/api/v1' const res = await fetch(`${base}${path}`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }) const json = await res.json().catch(() => null) if (!res.ok) throw new MarketplaceApiError(json?.message ?? 'Request failed', res.status, json?.error, json?.nextAvailableAt) return json.data as T }