Skip to content

fix: tag sorting on package versions page - #2105

Merged
ghostdevv merged 5 commits into
npmx-dev:mainfrom
ShroXd:fix-version-history-latest-tag
Mar 20, 2026
Merged

fix: tag sorting on package versions page#2105
ghostdevv merged 5 commits into
npmx-dev:mainfrom
ShroXd:fix-version-history-latest-tag

Conversation

@ShroXd

@ShroXdShroXd commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

🔗 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.

ScenarioScreenshot
AfterQQ20260316-231723
Beforeversion list page before

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

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

ProjectDeploymentActionsUpdated (UTC)
npmx.devReadyReadyPreview, CommentMar 19, 2026 8:48am
2 Skipped Deployments
ProjectDeploymentActionsUpdated (UTC)
docs.npmx.devIgnoredIgnoredPreviewMar 19, 2026 8:48am
npmx-lunariaIgnoredIgnoredMar 19, 2026 8:48am

Request Review

@codecov

codecovBot commented Mar 16, 2026

Copy link
Copy Markdown

Codecov Report

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

Files with missing linesPatch %Lines
app/pages/package/[[org]]/[name]/versions.vue66.66%2 Missing ⚠️
app/utils/versions.ts88.88%1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

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

coderabbitaiBot commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

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 nameStatusExplanation
Description check✅ PassedThe 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✅ PassedThe 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✅ PassedAll 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 OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.

OpenGrep is compatible with Semgrep configurations. Add an opengrep.yml or semgrep.ymlconfiguration file to your project to enable OpenGrep analysis.

@coderabbitaicoderabbitaiBot left a comment

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.

🧹 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

Comment threadapp/utils/versions.ts

@coderabbitaicoderabbitaiBot left a comment

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.

🧹 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
Copy Markdown
Member

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
Copy Markdown
ContributorAuthor

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.

@coderabbitaicoderabbitaiBot left a comment

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.

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

Comment threadapp/pages/package/[[org]]/[name]/versions.vue Outdated
@mbtools

Copy link
Copy Markdown

The version page is great! And thanks for this fix, too

Maybe move the sort logic to sortTagsLatestFirst in versions.ts and add some tests to test/unit/app/utils/versions.spec.ts 🙏

Just a bit feedback for your next PRs 😉

  1. It's not obvious that you can enter semver ranges to filter
imageimage

It's nicely done on the package page. I suggest using the same for the version page:

image

2, The dates for the dist-tags are missing the timestamp on hover

image

Nice work,
Marc

@ShroXd

Copy link
Copy Markdown
ContributorAuthor

@mbtools Thanks for pointing it out!
I refactored my code and added unit tests. And I will finish the remaining UX part in a new PR to make this PR focus on the fix.

@mbtools

Copy link
Copy Markdown

Nice! LGTM 👍

@ghostdevvghostdevv changed the title fix: fix tag issue and sort tagged versionsfix: package versions page tag sortingMar 20, 2026
@ghostdevvghostdevv changed the title fix: package versions page tag sortingfix: tag sorting on package versions pageMar 20, 2026
@ghostdevv
ghostdevv added this pull request to the merge queueMar 20, 2026
Merged via the queue into npmx-dev:main with commit 5e2e09eMar 20, 2026
22 checks passed
@github-actionsgithub-actionsBot mentioned this pull request Mar 20, 2026
@ShroXd
ShroXd deleted the fix-version-history-latest-tag branch March 20, 2026 08:43
Sign up for freeto 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

5 participants

@ShroXd@mbtools@nicolo-ribaudo@ghostdevv@graphieros