Skip to content

fix: fix tag issue and sort tagged versions#2105

Open
ShroXd wants to merge 4 commits intonpmx-dev:mainfrom
ShroXd:fix-version-history-latest-tag
Open

fix: fix tag issue and sort tagged versions#2105
ShroXd wants to merge 4 commits intonpmx-dev:mainfrom
ShroXd:fix-version-history-latest-tag

Conversation

@ShroXd
Copy link
Contributor

@ShroXd ShroXd commented Mar 16, 2026

🔗 Linked issue

Resolves #2102

🧭 Context

A implementation bug caused the confusing UI.

📚 Description

Fix unstable ordering of the tagged versions array. Tags are now sorted by semantic priority, with the exception of latest which remains pinned at the top.

Scenario Screenshot
After QQ20260316-231723
Before version list page before

@vercel
Copy link

vercel bot commented Mar 16, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Mar 17, 2026 2:43pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Mar 17, 2026 2:43pm
npmx-lunaria Ignored Ignored Mar 17, 2026 2:43pm

Request Review

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

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

Files with missing lines Patch % Lines
app/pages/package/[[org]]/[name]/versions.vue 81.81% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@ShroXd ShroXd marked this pull request as ready for review March 16, 2026 15:32
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a dist-tag priority system and applies it to the package versions page. Introduces TAG_PRIORITY and getTagPriority(tag) (with fuzzy matching) in app/utils/versions.ts. The versions page (app/pages/package/[[org]]/[name]/versions.vue) now computes latestTagRow (first row containing the latest tag) and otherTagRows (remaining rows sorted by tag priority then by publish time) and updates rendering to use these computed values instead of direct array indexing.

Suggested labels

help wanted

Suggested reviewers

  • danielroe
  • alexdln
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly references the linked issue and explains the fix for unstable ordering of tagged versions with semantic priority sorting.
Linked Issues check ✅ Passed The code changes implement all primary requirements: ensuring 'latest' tag is pinned at top, sorting other tags by semantic priority, and preventing RC/pre-release tags from appearing as the prominent featured version.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing tag ordering and priority. No unrelated functionality modifications or out-of-scope changes detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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

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

Tip

CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.

Add a .trivyignore file to your project to customize which findings Trivy reports.

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.

🧹 Nitpick comments (1)
app/utils/versions.ts (1)

77-83: Fuzzy matching may cause unexpected priority assignment for unconventional tag names.

The String.includes() check matches substrings anywhere in the tag, so tags like "arc" would match "rc" (priority 1) and "betamax" would match "beta" (priority 2). Additionally, since iteration stops on first match, the order of entries in TAG_PRIORITY determines which keyword wins for tags containing multiple keywords (e.g., "beta-rc" matches "rc" first).

This is likely acceptable for real-world npm dist-tags, but consider word-boundary matching if edge cases arise.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0522bfda-26e4-4b24-bcd8-83f8d51327a6

📥 Commits

Reviewing files that changed from the base of the PR and between 07a9ea9 and 5b9f12f.

📒 Files selected for processing (2)
  • app/pages/package/[[org]]/[name]/versions.vue
  • app/utils/versions.ts

/**
* Priority order for well-known dist-tags.
* Lower number = higher priority in display order.
* Unknown tags fall back to Infinity and are sorted by publish date descending.
Copy link
Contributor

Choose a reason for hiding this comment

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

I was reading through the code and wondering how it's possible that "latest" is not a well-known tag. It might be worth having a comment here explaining that it's handled manually elsewhere :)

Copy link
Contributor Author

@ShroXd ShroXd Mar 16, 2026

Choose a reason for hiding this comment

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

I was reading through the code and wondering how it's possible that "latest" is not a well-known tag. It might be worth having a comment here explaining that it's handled manually elsewhere :)

Nice point, thanks for bringing it up! I reconsidered TAG_PRIORITY — it's definitely weird to exclude latest from it. Although we filter it out in the UI, it doesn't make sense for a general constant to be affected by specific UI logic.
So I've added latest: 0 and shifted the other priorities by 1.

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.

🧹 Nitpick comments (1)
app/pages/package/[[org]]/[name]/versions.vue (1)

70-73: Normalise the latest-tag predicate once.

getTagPriority() already lowercases tags, but the featured-row split still relies on exact 'latest' checks. A tiny helper would keep the card selection, exclusion filter, and label rendering aligned if mixed-case tags ever leak through.

♻️ Proposed tidy-up
 const tagRows = computed(() => buildTaggedVersionRows(distTags.value))
-const latestTagRow = computed(() => tagRows.value.find(r => r.tags.includes('latest')) ?? null)
+const isLatestTag = (tag: string) => tag.toLowerCase() === 'latest'
+
+const latestTagRow = computed(() => tagRows.value.find(r => r.tags.some(isLatestTag)) ?? null)
 const otherTagRows = computed(() =>
   tagRows.value
-    .filter(r => !r.tags.includes('latest'))
+    .filter(r => !r.tags.some(isLatestTag))
     .sort((a, b) => {
       const pa = getTagPriority(a.primaryTag)
       const pb = getTagPriority(b.primaryTag)
       if (pa !== pb) return pa - pb
       const ta = versionTimes.value[a.version] ?? ''
       const tb = versionTimes.value[b.version] ?? ''
       return tb.localeCompare(ta)
     }),
 )
-                v-for="tag in latestTagRow!.tags.filter(t => t !== 'latest')"
+                v-for="tag in latestTagRow!.tags.filter(t => !isLatestTag(t))"

Also applies to: 241-241


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 940f3047-49fc-4769-acec-3d22c747c9c2

📥 Commits

Reviewing files that changed from the base of the PR and between 5b9f12f and c9f5ea4.

📒 Files selected for processing (2)
  • app/pages/package/[[org]]/[name]/versions.vue
  • app/utils/versions.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/utils/versions.ts

Comment on lines +75 to +80
const pa = getTagPriority(a.primaryTag)
const pb = getTagPriority(b.primaryTag)
if (pa !== pb) return pa - pb
const ta = versionTimes.value[a.version] ?? ''
const tb = versionTimes.value[b.version] ?? ''
return tb.localeCompare(ta)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I would recommend to use readable vars

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nit: I would recommend to use readable vars

Nice point! I will refactor this.

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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 023d94fd-4ca9-498b-aa2a-3299cf80450b

📥 Commits

Reviewing files that changed from the base of the PR and between c9f5ea4 and caa77f1.

📒 Files selected for processing (1)
  • app/pages/package/[[org]]/[name]/versions.vue

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.

Confusing UI for "latest" tag in versions history

3 participants