jefflix-website/app/api/music/musicbrainz/route.ts

58 lines
1.6 KiB
TypeScript

import { NextResponse } from 'next/server'
interface MBRecording {
id: string
title: string
score: number
length?: number
'artist-credit'?: { name: string }[]
releases?: { title: string; date?: string }[]
}
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const q = searchParams.get('q')
if (!q || q.length < 2) {
return NextResponse.json({ results: [] })
}
try {
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 5000)
const res = await fetch(
`https://musicbrainz.org/ws/2/recording?query=${encodeURIComponent(q)}&fmt=json&limit=20`,
{
headers: {
'User-Agent': 'SoulSync/1.0 (jeffemmett@gmail.com)',
Accept: 'application/json',
},
signal: controller.signal,
cache: 'no-store',
}
)
clearTimeout(timeout)
if (!res.ok) {
throw new Error(`MusicBrainz returned ${res.status}`)
}
const data = await res.json()
const results = (data.recordings || []).map((r: MBRecording) => ({
mbid: r.id,
title: r.title,
artist: r['artist-credit']?.[0]?.name || 'Unknown',
album: r.releases?.[0]?.title || '',
year: r.releases?.[0]?.date?.slice(0, 4) || '',
duration: r.length ? Math.round(r.length / 1000) : 0,
score: r.score,
}))
return NextResponse.json({ results })
} catch (error) {
console.error('MusicBrainz search error:', error)
return NextResponse.json({ error: 'MusicBrainz search failed' }, { status: 502 })
}
}