import type { Actions } from './$types'; import { fail } from '@sveltejs/kit'; import { parseSpotifyInput } from '$lib/map-finder/input'; import type { TrackMatchResult } from '$lib/map-finder/types'; import { getSpotifyMetadata } from '$lib/server/spotify'; import { getOsuMaps, MATCH_CONCURRENCY } from '$lib/server/osu'; import { ApiError, publicError, logApiError, mapConcurrent } from '$lib/server/finder-http'; import { acquireSearch } from '$lib/server/finder-limit'; export const actions: Actions = { default: async ({ request, fetch, getClientAddress }) => { const data = await request.formData(); const value = data.get('query'); const query = typeof value === 'string' ? value.trim().slice(0, 501) : ''; let input; try { input = parseSpotifyInput(query); } catch (error) { return fail(400, { query, error: (error as Error).message }); } if (input.kind === 'unsupported') return fail(400, { query, error: `Unsupported Spotify resource: ${input.resource}. Use a track, playlist, or album.` }); let address: string; try { address = getClientAddress(); } catch { address = 'shared-unknown'; } const release = acquireSearch( address, input.kind === 'playlist' || input.kind === 'album' ? 6 : 1 ); if (!release) return fail(429, { query, error: 'Site search limit reached. Wait up to 10 minutes, and finish any pending search before trying again.' }); try { const metadata = await getSpotifyMetadata(fetch, input); const results = await mapConcurrent( metadata.tracks, MATCH_CONCURRENCY, async (track): Promise => { try { const matches = await getOsuMaps(fetch, track); return { track, matches, status: matches.some((m) => m.confidence !== 'low') ? 'matched' : 'no_match' }; } catch (error) { logApiError(error); return { track, matches: [], status: 'error', error: publicError(error) }; } } ); return { query, results, collection: metadata.collection, truncated: metadata.truncated }; } catch (error) { logApiError(error); return fail( error instanceof ApiError && error.status === 429 ? 429 : error instanceof ApiError && [403, 404].includes(error.status) ? 404 : 502, { query, error: publicError(error) } ); } finally { release(); } } };