/** * Converts a direct R2 public URL to a same-origin proxy URL. * Used in API responses so tags load via /api/img instead of * pub-xxx.r2.dev (which returns 503 for cross-origin sub-resource requests * due to Cloudflare Bot Management on the r2.dev domain). */ function getR2BaseUrl() { const pub = process.env.R2_PUBLIC_URL; const id = process.env.R2_ACCOUNT_ID; return pub || `https://pub-${id}.r2.dev`; } export function toProxyUrl(r2Url: string | null | undefined): string | null { if (!r2Url) return null; const base = getR2BaseUrl(); if (r2Url.startsWith(base + "/")) { const key = r2Url.slice(base.length + 1); return `/api/img?key=${encodeURIComponent(key)}`; } return r2Url; }