Skip to content

feat: strip version info from the search query#1626

Open
Codefoxdev wants to merge 6 commits intonpmx-dev:mainfrom
Codefoxdev:feat/searchquery-version-stripping
Open

feat: strip version info from the search query#1626
Codefoxdev wants to merge 6 commits intonpmx-dev:mainfrom
Codefoxdev:feat/searchquery-version-stripping

Conversation

@Codefoxdev
Copy link
Copy Markdown

🔗 Linked issue

Partially addresses #1416

🧭 Context

Currently, when searching for a package along with version info (e.g. when copying a package name from the output of a package manager) it just returns random results, instead of useful ones. (e.g. https://npmx.dev/[email protected])

This pr strips the version info from the query to improve search results.

📚 Description

This pr implements a new regex query to extract essential date from the search query on the search page, such as package scope (which replaces an existing method), package specifier and (optionally) version info. The query is then reconstructed without version info to support the existing search api. It can currently parse a package name in the following format:

@scope/specifier@version

An object containing the separate parts of the query is exposed as the parsedQuery ref and it is able to be used for other features. (Such as implementing the other part of the linked issue)

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Apr 30, 2026 8:25pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Apr 30, 2026 8:25pm
npmx-lunaria Ignored Ignored Apr 30, 2026 8:25pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 540d4a0e-e56d-4978-8305-fe21f894ccb7

📥 Commits

Reviewing files that changed from the base of the PR and between 9d50b40 and 0e1aafd.

📒 Files selected for processing (1)
  • app/pages/search.vue
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/pages/search.vue

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Search now ignores version specifiers for matching and ordering, improving exact-match detection and results relevance.
    • Package scope and trailing text in queries are recognised more reliably (e.g. scoped packages, versions, and extra text).
  • Refactor

    • Centralised query parsing to produce consistent name/specifier/scope/version/trailing outputs used across search behaviours.
  • Tests

    • Added unit tests to validate parsing of scoped/unscoped packages, versions and trailing text.

Walkthrough

Adds a parser and composable to extract package, scope, version and trailing text from search input. The search page now uses a version‑stripped query and parsed scope for fetches, exact‑match logic, no‑results payload and rendered list. Unit tests validate the parser.

Changes

Cohort / File(s) Summary
Search page
app/pages/search.vue
Switches from raw query to versionStrippedQuery (from useParsedSearchQuery) for useSearch input, result reordering/exact-match detection, hasExactPackageMatch, no-results translation payload and PackageList search-query prop; removes manual scoped-package regex.
Composable
app/composables/useParsedSearchQuery.ts
New composable useParsedSearchQuery(query) returning computed refs for parsed fields: name, specifier, scope, version, trailing.
Utilities
app/utils/search.ts
New ParsedSearchQuery interface and parseSearchQuery(query) implementation that parses @scope/specifier@version-style strings (captures scope, specifier, version, trailing) and normalises name.
Tests
test/unit/app/utils/search.spec.ts
New Vitest unit tests covering scoped/unscoped inputs, versions (including pre-release/canary), and preservation of trailing text.

Sequence Diagram(s)

sequenceDiagram
participant User
participant SearchPage as "Search Page"
participant Composable as "useParsedSearchQuery"
participant Parser as "parseSearchQuery"
participant SearchHook as "useSearch"
participant PackageList

User->>SearchPage: enter raw query
SearchPage->>Composable: pass raw query
Composable->>Parser: parse raw query
Parser-->>Composable: parsed fields (name, scope, version, trailing)
Composable-->>SearchPage: versionStrippedQuery & packageScope
SearchPage->>SearchHook: fetch with versionStrippedQuery
SearchHook-->>SearchPage: search results
SearchPage->>PackageList: render with search-query=versionStrippedQuery
Loading
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: stripping version information from search queries to improve search results.
Description check ✅ Passed The description is clearly related to the changeset, providing context about the problem, solution approach, and implementation details of version stripping from search queries.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/searchquery-version-stripping

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 6/8 reviews remaining, refill in 7 minutes and 47 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
app/pages/search.vue (2)

36-55: Tighten scope parsing and normalise trailing whitespace.

The current regex allows whitespace inside the captured scope and strippedQuery can insert double spaces when trailing already starts with one. Tightening the character classes and trimming the trailing chunk keeps scopes valid and avoids noisy search strings.

Suggested update
-  const match = q.match(/^(?:@([^/]+)\/)?([^/@ ]+)(?:@([^ ]*))?(.*)/)
+  const match = q.match(/^(?:@([^/\s]+)\/)?([^/@\s]+)(?:@([^\s]*))?(.*)/)
...
-  const strippedQuery = `${name} ${trailing ?? ''}`.trim()
+  const strippedQuery = `${name}${trailing ? ` ${trailing.trimStart()}` : ''}`.trim()

216-216: Keep exact‑match handling aligned with the stripped search term.

Now that search uses strippedQuery, versioned inputs like [email protected] will fetch results for nuxt, but exact‑match boosting/highlighting and claim/availability checks still compare against the raw query. Consider switching those comparisons to parsedQuery.value.name (or strippedQuery) so the UI behaviour matches the search term.


ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c52d259 and c32e845.

📒 Files selected for processing (1)
  • app/pages/search.vue

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@github-actions github-actions Bot added the stale This has become stale and may be closed soon label Apr 18, 2026
@npmx-dev npmx-dev deleted a comment from github-actions Bot Apr 18, 2026
@github-actions github-actions Bot removed the stale This has become stale and may be closed soon label Apr 19, 2026
@serhalp serhalp added the needs review This PR is waiting for a review from a maintainer label Apr 20, 2026
Comment thread app/pages/search.vue Outdated
Comment on lines +38 to +54
const parsedQuery = computed(() => {
const q = query.value.trim()
// Regex matches a (un)scoped package and optionally extracts versioning info using the following syntax: @scope/specifier@version
// It makes use of 4 capture groups to extract this info.
const match = q.match(
/^(?:@(?<scope>[^/]+)\/)?(?<specifier>[^/@ ]+)(?:@(?<version>[^ ]*))?(?<trailing>.*)/,
)
if (!match) return { scope: null, name: q, version: null, strippedQuery: q }

const { scope, specifier, version, trailing } = match.groups ?? {}
// Reconstruct the query without the version info, essentially stripping the version data:
// anything directly after the @ for the version specifier is stripped.
const name = scope ? `@${scope}/${specifier}` : (specifier ?? '')
const strippedQuery = `${name} ${trailing ?? ''}`.trim()

return { scope: scope ?? null, name: name, version: version || null, strippedQuery }
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good idea to extract this into a util and add a unit test for it

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have extracted this into a util file and added some basic unit tests in the new commits

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/pages/search.vue`:
- Around line 42-44: The computed versionStrippedQuery is adding an extra space
because it inserts a literal space before queryTrailing even though
queryTrailing already contains its leading whitespace; update the template in
versionStrippedQuery to concatenate packageName.value and queryTrailing.value
without the extra literal space (e.g. `${packageName.value}${queryTrailing.value
?? ''}`) so you don't produce double spaces, and keep the .trim() only if you
still need to guard against accidental surrounding whitespace.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2cc7a54c-3f24-4bda-aa85-92ad8f0fd45e

📥 Commits

Reviewing files that changed from the base of the PR and between 123a992 and 9d50b40.

📒 Files selected for processing (4)
  • app/composables/useParsedSearchQuery.ts
  • app/pages/search.vue
  • app/utils/search.ts
  • test/unit/app/utils/search.spec.ts

Comment thread app/pages/search.vue
@Codefoxdev
Copy link
Copy Markdown
Author

There are maybe some places where this util can be used instead of existing implementations.
The most prominent example is in modules/runtime/server/cache.ts with the parseScopedPackageWithVersion function, which implements a part of this method's functionality.

Copy link
Copy Markdown
Contributor

@gameroman gameroman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall 👍

Comment thread app/pages/search.vue Outdated
} = useParsedSearchQuery(query)

const versionStrippedQuery = computed(() =>
`${packageName.value} ${queryTrailing.value ?? ''}`.trim(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the tests, this probably doesn't need an extra space since the queryTrailing seems to have it

Suggested change
`${packageName.value} ${queryTrailing.value ?? ''}`.trim(),
`${packageName.value}${queryTrailing.value ?? ''}`.trim(),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, already fixed it

@Codefoxdev
Copy link
Copy Markdown
Author

@gameroman Should I also update the similar existing implementations to use this new method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review This PR is waiting for a review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants