Skip to content

fix: normalize user and org names to lowercase in search and routing#1519

Open
yshashi wants to merge 1 commit intonpmx-dev:mainfrom
yshashi:fix/org-user-case-normalization
Open

fix: normalize user and org names to lowercase in search and routing#1519
yshashi wants to merge 1 commit intonpmx-dev:mainfrom
yshashi:fix/org-user-case-normalization

Conversation

@yshashi
Copy link

@yshashi yshashi commented Feb 15, 2026

Changes

  • Normalized org/user names to lowercase when creating search suggestions in useSearch.ts
  • Ensured route parameters use lowercase in SearchSuggestionCard.vue
  • Normalized org parameter in server API endpoint
  • Normalized route parameters in org and user page components
  • Added unit tests for case normalization behavior

Testing

  • Searched for "AnGuLAR" (mixed case)
  • Verified suggestion displays "@angular" (lowercase)
  • Clicked on org tile
  • Verified navigation to /org/angular (lowercase)
  • Verified page loads without 404 error
  • Tested with user suggestions (~username)

Fixes: #1507

@vercel
Copy link

vercel bot commented Feb 15, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 15, 2026 7:57pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 15, 2026 7:57pm
npmx-lunaria Ignored Ignored Feb 15, 2026 7:57pm

Request Review

@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

❌ Patch coverage is 25.00000% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/composables/npm/useSearch.ts 25.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 15, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Route and name handling were normalised to lowercase across the app: search suggestion routes now pass names as toLowerCase(), the useSearch composable uses lowercase names for suggestion creation and existence checks, organisation and user page route params are lowercased before use (affecting API calls, routing and UI strings), the server org packages API lowercases the org param when reading and when building cache keys, and a unit test was added to verify search suggestion case normalisation behaviour.

Possibly related PRs

Suggested reviewers

  • danielroe
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly describes case normalization changes across multiple files and references the linked issue.
Linked Issues check ✅ Passed The pull request directly addresses all requirements from issue #1507: lowercase org/user titles in search results, prevention of 404s through route normalization, and consistent case-handling.
Out of Scope Changes check ✅ Passed All changes are directly scoped to case normalization for org/user names in search, routing, and API handlers as specified in issue #1507.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/composables/npm/useSearch.ts (1)

371-418: ⚠️ Potential issue | 🟠 Major

Pass lowercased names to NPM existence checks.

The functions checkOrgNpm(name) and checkUserNpm(name) are called with the original casing, but their results are cached with lowerName keys. Both functions send queries to the NPM registry using the original case (line 15 in checkOrgExists sends @${name}, and line 25 in checkUserExists sends maintainer:${name}). If the registry is case-sensitive, mixed-case input could produce false negatives—for example, a search for 'Node-Red' might fail, but the result gets cached as org:node-red, causing a subsequent search for 'node-red' to incorrectly use the cached failure. Pass lowerName to both functions to ensure consistent API queries and alignment with cache keys.

Suggested fix
-          checkOrgNpm(name)
+          checkOrgNpm(lowerName)
...
-          checkUserNpm(name)
+          checkUserNpm(lowerName)
🧹 Nitpick comments (1)
server/api/registry/org/[org]/packages.get.ts (1)

19-59: Normalise the cache key to avoid duplicate entries.

With the handler lowercasing org, the cache key still uses the raw route param, so /org/Angular and /org/angular won’t share cache entries. Consider lowercasing in getKey as well.

Suggested fix
   getKey: event => {
-    const org = getRouterParam(event, 'org') ?? ''
+    const org = getRouterParam(event, 'org')?.toLowerCase() ?? ''
     return `org-packages:v1:${org}`
   },

Copy link
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/api/registry/org/[org]/packages.get.ts (1)

56-59: ⚠️ Potential issue | 🟠 Major

Cache key does not normalise org to lowercase, causing cache fragmentation.

The handler normalises org to lowercase at line 19, but the cache getKey function uses the raw parameter. Requests for /org/Angular/packages and /org/angular/packages will produce different cache keys (org-packages:v1:Angular vs org-packages:v1:angular) yet fetch identical data from the npm registry.

🔧 Proposed fix to normalise cache key
     getKey: event => {
-      const org = getRouterParam(event, 'org') ?? ''
-      return `org-packages:v1:${org}`
+      const org = getRouterParam(event, 'org')?.toLowerCase() ?? ''
+      return `org-packages:v1:${org}`
     },
🧹 Nitpick comments (1)
test/unit/search-case-normalization.spec.ts (1)

37-45: Consider removing this test block — it only asserts JavaScript's toLowerCase() behaviour.

The "Case normalization expectations" describe block doesn't test any application logic; it merely confirms that 'AnGuLAR'.toLowerCase() equals 'angular'. If the intent is to document that consumers must normalise, a code comment in parseSuggestionIntent or useSearch.ts would be clearer.

Alternatively, consider testing the actual normalisation in useSearch.ts by mocking the composable and verifying that suggestions contain lowercased names.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: org/user title in search results follows search query letter case

1 participant