/** * Minimal PeerTube provider handler */ const handler = { id: 'pt', label: 'PeerTube', /** * @param {string} q * @param {{ limit: number, page?: number }} opts * @returns {Promise>} */ async search(q, opts) { const { limit = 10, page = 1 } = opts || {}; try { // Use PeerTube API search const response = await fetch( `https://sepiasearch.org/api/v1/search/videos?` + new URLSearchParams({ search: q, count: Math.min(limit, 50).toString(), start: Math.max(0, (Math.max(1, Number(page || 1)) - 1) * Math.min(limit, 50)).toString() }) ); if (!response.ok) { throw new Error(`PeerTube API error: ${response.status}`); } const data = await response.json(); return (data.data || []).map(item => { const rawThumb = item.thumbnailUrl || item.thumbnailPath || ''; const thumbnail = rawThumb ? rawThumb.startsWith('http') ? rawThumb : rawThumb.startsWith('//') ? `https:${rawThumb}` : new URL(rawThumb, item.url || 'https://sepiasearch.org').toString() : undefined; return { title: item.name, id: item.uuid, url: item.url, thumbnail, uploaderName: (item.account && (item.account.displayName || item.account.name)) || undefined, type: 'video', duration: typeof item.duration === 'number' && item.duration > 0 ? Math.round(item.duration) : undefined }; }); } catch (error) { console.error('PeerTube search error:', error); return []; } } }; export default handler;