// Helpers for resolving uploaded-asset URLs out of loosely-typed API records. // Response field names vary across endpoints, so we probe a list of common keys // and turn relative storage paths into absolute URLs. import { ASSET_BASE_URL } from "./config"; // Turn a possibly-relative path into an absolute URL. The API serves uploads // from `/storage/...`, while DB fields like `file_path` hold paths relative to // that (e.g. "music/x.mp3"), so we add the `storage/` prefix when missing. export function assetUrl(path?: string | null): string | null { if (!path) return null; if (/^(https?:|data:|blob:)/i.test(path)) return path; let p = String(path).replace(/^\/+/, ""); if (!p.startsWith("storage/")) p = `storage/${p}`; return `${ASSET_BASE_URL}/${p}`; } // A record may store a media reference directly (string) or nested in an object // (e.g. { sound: { url } }). Read the first key that yields a usable value. function readField(row: Record, key: string): string | null { const v = row[key]; if (typeof v === "string" && v) return v; if (v && typeof v === "object") { const obj = v as Record; for (const k of ["url", "path", "src", "file"]) { if (typeof obj[k] === "string" && obj[k]) return obj[k] as string; } } return null; } // Find the first present URL among candidate keys, resolved to absolute. export function pickUrl( row: unknown, keys: string[], ): string | null { if (!row || typeof row !== "object") return null; const record = row as Record; for (const key of keys) { const found = readField(record, key); if (found) return assetUrl(found); } return null; } // Common key sets per media kind. Ordered most-specific / full-URL first. // (`/media` returns the playable file in `external_url`; `/music` uses `url`.) export const SOUND_KEYS = [ "url", "external_url", "sound_url", "sound", "audio_url", "audio", "file_url", "file", "file_path", ]; export const VIDEO_KEYS = [ "external_url", "video_url", "video", "url", "file_url", "file", "file_path", ]; export const IMAGE_KEYS = [ "image_url", "image", "thumbnail", "thumbnail_url", "cover", "url", "path", ];