[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add OpenSearch support (#113)

authored by

Burak Yigit Kaya and committed by
GitHub
49cff3b9 9d83bc56

+52
+9
nuxt.config.ts
··· 22 22 app: { 23 23 head: { 24 24 htmlAttrs: { lang: 'en' }, 25 + link: [ 26 + { 27 + rel: 'search', 28 + type: 'application/opensearchdescription+xml', 29 + title: 'npm', 30 + href: '/opensearch.xml', 31 + }, 32 + ], 25 33 }, 26 34 }, 27 35 ··· 39 47 40 48 routeRules: { 41 49 '/': { prerender: true }, 50 + '/opensearch.xml': { isr: true }, 42 51 '/**': { isr: 60 }, 43 52 '/package/**': { isr: 60 }, 44 53 '/search': { isr: false, cache: false },
+27
server/api/opensearch/suggestions.get.ts
··· 1 + import type { NpmSearchResponse } from '#shared/types' 2 + import { NPM_REGISTRY } from '#shared/utils/constants' 3 + 4 + export default defineCachedEventHandler( 5 + async event => { 6 + const query = getQuery(event) 7 + const q = String(query.q || '').trim() 8 + 9 + if (!q) { 10 + return [q, []] 11 + } 12 + 13 + const params = new URLSearchParams({ text: q, size: '10' }) 14 + const response = await $fetch<NpmSearchResponse>(`${NPM_REGISTRY}/-/v1/search?${params}`) 15 + 16 + const suggestions = response.objects.map(obj => obj.package.name) 17 + return [q, suggestions] 18 + }, 19 + { 20 + maxAge: 60, 21 + swr: true, 22 + getKey: event => { 23 + const query = getQuery(event) 24 + return `opensearch-suggestions:${query.q || ''}` 25 + }, 26 + }, 27 + )
+16
server/routes/opensearch.xml.get.ts
··· 1 + export default defineEventHandler(async event => { 2 + const url = getRequestURL(event) 3 + const origin = url.origin 4 + return ` 5 + <?xml version="1.0" encoding="UTF-8"?> 6 + <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> 7 + <ShortName>npm</ShortName> 8 + <Description>Search npm packages on npmx.dev</Description> 9 + <InputEncoding>UTF-8</InputEncoding> 10 + <Image width="16" height="16" type="image/svg+xml">${origin}/favicon.svg</Image> 11 + <Url type="text/html" template="${origin}/search?q={searchTerms}"/> 12 + <Url type="application/x-suggestions+json" template="${origin}/api/opensearch/suggestions?q={searchTerms}"/> 13 + <Url type="application/opensearchdescription+xml" rel="self" template="${origin}/opensearch.xml"/> 14 + </OpenSearchDescription> 15 + `.trim() 16 + })