// eslint-disable-next-line @typescript-eslint/no-explicit-any const cfg = (window as any).accessmateConfig ?? {}; const BASE = cfg.restBase ?? '/wp-json/accessmate/v1'; const NONCE = cfg.nonce ?? ''; export const isPremium: boolean = !!cfg.isPremium; export const upgradeUrl: string = cfg.upgradeUrl ?? ''; export const assetsUrl: string = cfg.assetsUrl ?? ''; export const siteUrl: string = cfg.siteUrl ?? ''; /** * Whether a scanned URL is the site's homepage — the page's own * (captured as the scan's `title`) is whatever the theme renders there, * which for some sites has nothing recognisable as "home" in it (seen in * the wild rendering as the bare domain), so callers should prefer this * over the scan's title when labelling the homepage in a report/email. */ export function isHomepageUrl(url: string): boolean { if (!siteUrl) return false; try { const target = new URL(url); const site = new URL(siteUrl); return target.origin === site.origin && (target.pathname === '/' || target.pathname === '') && !target.search; } catch { return false; } } export async function apiFetch<T>(path: string, options: RequestInit = {}): Promise<T> { // With plain WordPress permalinks, BASE already contains '?rest_route=…'. // Split path into route and query parts so we join with '&' rather than '?'. const [routePart, queryPart] = path.split('?'); const sep = BASE.includes('?') ? '&' : '?'; const url = BASE + routePart + (queryPart ? sep + queryPart : ''); const res = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': NONCE, ...options.headers, }, }); if (!res.ok) { const text = await res.text(); let message = text || res.statusText; try { const json = JSON.parse(text) as { error?: string; message?: string }; message = json.error ?? json.message ?? res.statusText; } catch (_e) { // Non-JSON error body — show it as-is. } throw new Error(message); } return res.json() as Promise<T>; }