From fb8b8fd02c159a0ba77875f2920cd25b14dd725f Mon Sep 17 00:00:00 2001 From: Anil Loutombam Date: Fri, 31 Jul 2026 15:10:15 +0530 Subject: [PATCH 1/2] fix: prioritize exact matches in Algolia search --- app/composables/npm/useAlgoliaSearch.ts | 12 ++++++-- .../composables/use-algolia-search.spec.ts | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/app/composables/npm/useAlgoliaSearch.ts b/app/composables/npm/useAlgoliaSearch.ts index 7b925e5bc8..3c533e4f6c 100644 --- a/app/composables/npm/useAlgoliaSearch.ts +++ b/app/composables/npm/useAlgoliaSearch.ts @@ -333,7 +333,7 @@ export function useAlgoliaSearch() { filters: `objectID:${checks.checkPackage}`, length: 1, analyticsTags: ['npmx.dev'], - attributesToRetrieve: EXISTENCE_CHECK_ATTRS, + attributesToRetrieve: ATTRIBUTES_TO_RETRIEVE, attributesToHighlight: [], }) } @@ -369,7 +369,15 @@ export function useAlgoliaSearch() { let packageExists: boolean | null = null if (packageQueryIndex >= 0) { const pkgResponse = results[packageQueryIndex] as SearchResponse | undefined - packageExists = (pkgResponse?.nbHits ?? 0) > 0 + const exactHit = pkgResponse?.hits[0] + packageExists = exactHit ? exactHit.name === checks?.checkPackage : false + + if (exactHit) { + searchResult.objects = [ + hitToSearchResult(exactHit), + ...searchResult.objects.filter(result => result.package.name !== exactHit.name), + ] + } } return { search: searchResult, orgExists, userExists, packageExists } diff --git a/test/nuxt/composables/use-algolia-search.spec.ts b/test/nuxt/composables/use-algolia-search.spec.ts index 1e0113691e..d4ea9f1daf 100644 --- a/test/nuxt/composables/use-algolia-search.spec.ts +++ b/test/nuxt/composables/use-algolia-search.spec.ts @@ -24,4 +24,33 @@ describe('useAlgoliaSearch', () => { const filtered = objects.filter(o => !o.package.isSecurityHeld).map(o => o.package.name) expect(filtered).toEqual(['npmx-connector']) }) + + it('places an exact package match before the regular search results', async () => { + const otherHit = fixture.find(hit => hit.name === 'vuln-npm') + const exactHit = fixture.find(hit => hit.name === 'npmx-connector') + + if (!otherHit || !exactHit) { + throw new Error('Expected Algolia fixtures are missing') + } + + mockSearch.mockResolvedValue({ + results: [ + { hits: [otherHit], nbHits: 2 }, + { hits: [exactHit], nbHits: 1 }, + ], + }) + + const { searchWithSuggestions } = useAlgoliaSearch() + const result = await searchWithSuggestions( + 'npmx-connector', + {}, + { checkPackage: 'npmx-connector' }, + ) + + expect(result.packageExists).toBe(true) + expect(result.search.objects.map(item => item.package.name)).toEqual([ + 'npmx-connector', + 'vuln-npm', + ]) + }) }) From 4900a70b3e1594495866dfd870fc9e352737e007 Mon Sep 17 00:00:00 2001 From: Anil Loutombam Date: Fri, 31 Jul 2026 15:33:19 +0530 Subject: [PATCH 2/2] fix: verify exact Algolia match --- app/composables/npm/useAlgoliaSearch.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/composables/npm/useAlgoliaSearch.ts b/app/composables/npm/useAlgoliaSearch.ts index 3c533e4f6c..81ec747e6c 100644 --- a/app/composables/npm/useAlgoliaSearch.ts +++ b/app/composables/npm/useAlgoliaSearch.ts @@ -369,10 +369,12 @@ export function useAlgoliaSearch() { let packageExists: boolean | null = null if (packageQueryIndex >= 0) { const pkgResponse = results[packageQueryIndex] as SearchResponse | undefined - const exactHit = pkgResponse?.hits[0] - packageExists = exactHit ? exactHit.name === checks?.checkPackage : false + const [exactHit] = pkgResponse?.hits ?? [] + const isExactHit = exactHit?.name === checks?.checkPackage - if (exactHit) { + packageExists = isExactHit + + if (exactHit && isExactHit) { searchResult.objects = [ hitToSearchResult(exactHit), ...searchResult.objects.filter(result => result.package.name !== exactHit.name),