const MOMENTUM_API = "https://api.momentum-mod.org/v1"; interface MomentumMapThumbnail { id: string; small: string; medium: string; large: string; xl: string; } interface MomentumMapLeaderboard { gamemode: number; trackType: number; trackNum: number; style: number; tier: number | null; tags: number[]; type: number; linear: boolean | null; } interface MomentumMapInfo { description: string; youtubeID: string; creationDate: string; approvedDate: string; requiredGames: number[]; } interface MomentumMap { id: number; name: string; thumbnail: MomentumMapThumbnail | null; images: MomentumMapThumbnail[]; info: MomentumMapInfo | null; leaderboards: MomentumMapLeaderboard[]; } interface MomentumMapsResponse { totalCount: number; returnCount: number; data: MomentumMap[]; } export interface MapInfo { mapId: number | null; thumbnailUrl: string | null; tier: number | null; mapDate: string | null; } const mapInfoCache = new Map(); function extractSurfTier( leaderboards: MomentumMapLeaderboard[], ): number | null { const mainLeaderboard = leaderboards.find( (lb) => lb.gamemode === 1 && lb.trackType === 0 && lb.style === 0, ); return mainLeaderboard?.tier ?? null; } export async function getMapInfo(mapName: string): Promise { const cached = mapInfoCache.get(mapName); if (cached) return cached; try { const url = `${MOMENTUM_API}/maps?search=${encodeURIComponent(mapName)}&take=1&expand=info,leaderboards`; const res = await fetch(url); if (!res.ok) { const info: MapInfo = { mapId: null, thumbnailUrl: null, tier: null, mapDate: null, }; mapInfoCache.set(mapName, info); return info; } const json: MomentumMapsResponse = await res.json(); const map = json.data?.[0]; if (!map || map.name !== mapName) { const info: MapInfo = { mapId: null, thumbnailUrl: null, tier: null, mapDate: null, }; mapInfoCache.set(mapName, info); return info; } const thumbnailUrl = map.thumbnail?.small ?? map.images?.[0]?.small ?? null; const tier = extractSurfTier(map.leaderboards ?? []); const mapDate = map.info?.creationDate ?? null; const info: MapInfo = { mapId: map.id, thumbnailUrl, tier, mapDate }; mapInfoCache.set(mapName, info); return info; } catch { const info: MapInfo = { mapId: null, thumbnailUrl: null, tier: null, mapDate: null, }; mapInfoCache.set(mapName, info); return info; } } export async function getMapThumbnail(mapName: string): Promise { const info = await getMapInfo(mapName); return info.thumbnailUrl; }