← Public packages
@hypercubed/web-search
Unified web search - Brave via BraveSearch secret (api.search.brave.com), then DDG Instant, then Wikipedia. Normalized {provider, results} shape.
src/index.ts
7 lines · 2.1 KB · TypeScripttype Result = { title: string, url: string, snippet: string };
export async function search(q: string, count=5): Promise<{provider:string, query:string, results: Result[]}> {
try { const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(q)}&count=${count}`; const r = await fetch(url, { headers: { 'X-Subscription-Token': '{{secret:BraveSearch}}', 'Accept': 'application/json' } as any }); const t = await r.text(); if (r.ok) { const j=JSON.parse(t); const raw=j.results||j.web?.results||[]; const results=raw.slice(0,count).map((x:any)=>({title:x.title||'',url:x.url||'',snippet:(x.description||x.snippet||'').slice(0,250)})); if(results.length>0) return {provider:'brave',query:q,results}; } } catch {}
try { const url=`https://api.duckduckgo.com/?q=${encodeURIComponent(q)}&format=json&no_html=1&skip_disambig=1`; const r=await fetch(url,{headers:{'User-Agent':'Mozilla/5.0'} as any}); const j:any=await r.json(); const results:Result[]=[]; if(j.AbstractURL) results.push({title:j.Heading||q,url:j.AbstractURL,snippet:(j.AbstractText||'').slice(0,250)}); for(const t of (j.RelatedTopics||[])){ if(results.length>=count) break; if(t.FirstURL&&t.Text) results.push({title:t.Text.split(' - ')[0].slice(0,80),url:t.FirstURL,snippet:t.Text.slice(0,250)}); else if(t.Topics) for(const s of t.Topics){ if(results.length>=count) break; if(s.FirstURL) results.push({title:s.Text.split(' - ')[0].slice(0,80),url:s.FirstURL,snippet:s.Text.slice(0,250)}); } } if(results.length>0) return {provider:'duckduckgo-instant',query:q,results:results.slice(0,count)}; } catch {}
const url=`https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(q)}&format=json&srlimit=${count}&origin=*`; const r=await fetch(url,{headers:{'User-Agent':'Mozilla/5.0'} as any}); const j:any=await r.json(); const results:Result[]=(j.query?.search||[]).slice(0,count).map((s:any)=>({title:s.title,url:`https://en.wikipedia.org/wiki/${encodeURIComponent(s.title.replace(/ /g,'_'))}`,snippet:s.snippet.replace(/<[^>]+>/g,'').slice(0,250)})); return {provider:'wikipedia',query:q,results};
}
export default { search };