/** * @typedef {Object} Suggestion * @property {string} title * @property {string} id * @property {number=} duration * @property {boolean=} isShort * @property {string=} url * @property {string=} thumbnail * @property {string=} uploaderName * @property {string=} type */ /** @type {{ id: 'yt', label: string, search: (q: string, opts: { limit: number, page?: number }) => Promise }} */ const handler = { id: 'yt', label: 'YouTube', async search(q, opts) { const { limit = 10 } = opts; try { const API_KEY = process.env.YOUTUBE_API_KEY; if (!API_KEY) { throw new Error('YOUTUBE_API_KEY not configured'); } const response = await fetch( `https://www.googleapis.com/youtube/v3/search?` + new URLSearchParams({ part: 'snippet', q: q, type: 'video', maxResults: Math.min(limit, 50).toString(), key: API_KEY, order: 'relevance' }) ); if (!response.ok) { throw new Error(`YouTube API error: ${response.status}`); } const data = await response.json(); return (data.items || []).map(item => ({ title: item.snippet.title, id: item.id.videoId, url: `https://www.youtube.com/watch?v=${item.id.videoId}`, thumbnail: item.snippet.thumbnails?.medium?.url || item.snippet.thumbnails?.default?.url, uploaderName: item.snippet.channelTitle, type: 'video' })); } catch (error) { console.error('YouTube search error:', error); return []; } } }; export default handler;