Skip to content

Add package catalog at /[name] route with curated version comparisons#1040

Merged
oBusk merged 17 commits intomainfrom
copilot/add-catalog-page-dynamic-route
Feb 8, 2026
Merged

Add package catalog at /[name] route with curated version comparisons#1040
oBusk merged 17 commits intomainfrom
copilot/add-catalog-page-dynamic-route

Conversation

Copy link
Contributor

Copilot AI commented Jan 26, 2026

Summary of Changes

Fixed critical comparison logic bug and addressed all code review comments:

Critical Fix (commit 017022c)

Comparison Logic Bug: Was comparing with LAST version instead of FIRST

  • Before: 18.3.1...19.2.4 (wrong - 19.2.4 is not first of major 19)
  • After: 18.3.1...19.0.0 (correct - 19.0.0 is first of major 19)

Latest UI Fixes (commit [current])

  1. ✅ Reset next-env.d.ts to match main branch
  2. ✅ Fixed awkward line breaks in comparison display
    • Changed from flex items-center to inline span elements
    • Package name and version now flow as single text string
    • No more breaks between package name and version number

Before fix: Long package names would break, and version appeared as separate flex item
After fix: Full comparison text flows inline naturally

Fixed comparison display

Bot Review Fixes (commit 5861ec6)

  1. ✅ Removed unused _versionMap parameter from generateComparisons()
  2. ✅ Created PackageNamePrefix component to reduce package name duplication
  3. ✅ Updated all tests to remove unused versionMap variables

Previous Refactoring (commit c27f223)

  1. ✅ Restored use of getVersionData() - reuses existing cached function
  2. ✅ Fixed spacing in comparison display - no gaps between elements
  3. ✅ Faded package names to emphasize versions
  4. ✅ Extracted generateCatalogMetadata() to separate file
  5. ✅ Simplified isCatalogPage() to work with arrays directly
  6. ✅ Cleaned up page.tsx - more concise and maintainable

All Previous Changes

  1. ✅ Fixed generateComparisons to compare first vs last correctly
  2. ✅ Simplified prerelease filter to single expression
  3. ✅ Sort by from version instead of to
  4. ✅ Removed redundant getChangedPart function
  5. ✅ Added aria-label for accessibility
  6. ✅ Changed heading to "Suggested Diffs"
  7. ✅ Show full package specs (react@19.0.0...react@19.0.1)
  8. ✅ Added SEO metadata (keywords, openGraph)

All 131 tests passing, build successful, linter passing.

Original prompt

Objective: Implement a new dynamic route /pkg/[name] in our Next.js application to serve as a "Catalog" page for a specific npm package. This page should be triggered when a user visits a package name without specific versions.

1. Data Sourcing:

  • Fetch the package metadata (packument) from the npm registry using the provided package name.
  • Use the latest tag for general metadata (Description, License, Author).
  • Use existing logic for fetching package versions and their publish dates.

2. Comparison Generation Logic (The "Spokes"):
Identify exactly 10 distinct comparisons to link to. Follow these strict hierarchy rules:

  • Major Bumps (Target: 3): Identify the first release of a major version (e.g., 2.0.0) and compare it against the absolute last release of the previous major (e.g., 1.9.4).
  • Minor Bumps (Target: 3): Identify the first release of a minor version (e.g., 2.1.0) and compare it against the last release of the previous minor within that same major (e.g., 2.0.12).
  • Patch Bumps (Target: 4): Compare the most recent 4 patches sequentially (e.g., 2.1.4 vs 2.1.3).
  • Fallback Logic: If any category has fewer than its target (e.g., a new package with no major bumps), backfill the remaining slots from the other categories in this priority: Majors > Minors > Patches. Total links MUST equal 10 unless the package has fewer than 11 total versions.

3. UI Requirements (Two-Column Layout):

  • Left Column (Meta): Display Package Name, latest version string, "Last Published" (formatted date), and external links (NPM, GitHub/Homepage).
  • Right Column (Diff List): * Sort the 10 generated comparisons chronologically (newest at the top).
  • Visual Highlighting: For each link, visually highlight the specific semver digit that changed.
  • If 1.2.32.0.0: Highlight the 1 and the 2.
  • If 2.2.32.3.0: Highlight the middle 2 and the 3.
  • If 2.3.42.3.5: Highlight the final 4 and the 5.

4. Implementation Constraints:

  • This PR should only introduce the /pkg/[name] route and its components.
  • Do not modify existing /compare logic.
  • The comparison links should point to our existing immutable URL structure: /compare/pkg@versionA...pkg@versionB.
  • The comparison links should not be preloaded (to avoid unnecessary diff generation).

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel
Copy link

vercel bot commented Jan 26, 2026

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

Project Deployment Actions Updated (UTC)
npm-diff Ready Ready Preview, Comment Feb 8, 2026 2:31pm

@oBusk
Copy link
Owner

oBusk commented Jan 26, 2026

@copilot I misspoke, I want the url to be /react, no pkg prefix. This means it needs to have some logic to work with the existing catch-all route.
Also, looks like all catalogs has 4 or 5 diffs which is just the current version diffed with itself as the first 5 entries.

Copy link
Contributor Author

Copilot AI commented Jan 26, 2026

@copilot I misspoke, I want the url to be /react, no pkg prefix. This means it needs to have some logic to work with the existing catch-all route.
Also, looks like all catalogs has 4 or 5 diffs which...

Fixed in commit 2975f59:

  1. URL change: Catalog pages now work at /react instead of /pkg/react - integrated into the catch-all route
  2. Bug fix: Removed duplicate comparisons - prerelease versions with same major.minor.patch (like 19.3.0-canary-xxx) are no longer compared as patches

Fixed catalog

Copilot AI changed the title Add /pkg/[name] catalog route with curated version comparisons Add package catalog at /[name] route with curated version comparisons Jan 26, 2026
@oBusk oBusk force-pushed the copilot/add-catalog-page-dynamic-route branch from dd0eb80 to 8ba1186 Compare February 1, 2026 20:12
@oBusk
Copy link
Owner

oBusk commented Feb 1, 2026

@copilot fix the failing test

Copy link
Contributor Author

Copilot AI commented Feb 1, 2026

@copilot fix the failing test

Fixed in commit 5323b83. The test was failing due to a transient 500 error from npm registry. Added retry logic (3 attempts with 1s delay) to handle network failures gracefully.

Copilot AI and others added 2 commits February 4, 2026 00:10
Co-authored-by: oBusk <13413409+oBusk@users.noreply.github.com>
Co-authored-by: oBusk <13413409+oBusk@users.noreply.github.com>
- Restore use of getVersionData() instead of manual extraction
- Fix spacing in ComparisonList: remove gaps between elements
- Fade package names with text-muted-foreground to emphasize versions
- Extract generateCatalogMetadata() to separate file
- Simplify isCatalogPage() to accept arrays directly
- Clean up page.tsx by using utility functions

Co-authored-by: oBusk <13413409+oBusk@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a new catalog page feature at the /[name] route that provides curated version comparisons for npm packages. When users visit a package name without specific versions, they see a two-column layout with package metadata and 10 suggested version comparisons (major, minor, and patch bumps).

Changes:

  • Added catalog page detection and routing logic
  • Implemented comparison generation algorithm with hierarchical bumping strategy (3 major, 3 minor, 4 patch comparisons)
  • Created metadata generation for SEO optimization
  • Built UI components for package metadata display and comparison list with visual highlighting

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/lib/utils/isCatalogPage.ts Validates catalog page requests and extracts package names from specs
src/lib/utils/generateComparisons.ts Core logic for generating 10 curated version comparisons with backfill strategy
src/lib/utils/generateComparisons.test.ts Comprehensive test suite covering comparison generation edge cases
src/app/[...parts]/page.tsx Added catalog page detection and routing in main page component
src/app/[...parts]/_page/catalog/generateCatalogMetadata.ts Generates SEO metadata for catalog pages
src/app/[...parts]/_page/catalog/VersionWithHighlight.tsx Highlights changed semver digits in version comparisons
src/app/[...parts]/_page/catalog/PackageMeta.tsx Left column displaying package information and external links
src/app/[...parts]/_page/catalog/ComparisonList.tsx Right column showing suggested version comparisons with highlighting
src/app/[...parts]/_page/catalog/CatalogPage.tsx Main catalog page component with data fetching and layout

Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The parameter _versionMap is prefixed with an underscore indicating it's unused, but this prefix typically signals intentionally unused parameters. Since the versionMap is genuinely not used in the function, consider removing this parameter entirely from the function signature.

Suggested change
_versionMap: Record<string, { time: string }>,

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot Please fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 5861ec6. Removed the unused _versionMap parameter from generateComparisons() signature and updated all call sites and tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 5861ec6. Removed unused _versionMap parameter from generateComparisons() function signature and updated all call sites and tests.

Comment on lines 67 to 69
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The package name is repeated four times in the comparison display (lines 67-69 and 77-79). Consider extracting this into a reusable component or constant to reduce duplication and improve maintainability.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot Please fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 5861ec6. Created PackageNamePrefix component to extract the repeated package name display, reducing duplication from 4 occurrences to a reusable component.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 5861ec6. Extracted PackageNameAt component to eliminate duplication - package name now rendered through a reusable component instead of being repeated 4 times inline.

- Remove unused _versionMap parameter from generateComparisons()
- Update all call sites and tests to not pass versionMap
- Create PackageNamePrefix component to reduce duplication
- Extract repeated package name display into reusable component
- Improves maintainability and reduces code repetition

Co-authored-by: oBusk <13413409+oBusk@users.noreply.github.com>
@oBusk
Copy link
Owner

oBusk commented Feb 7, 2026

@copilot

  1. Do not check in the next-env file, reset it to match main branch.
  2. There's awkard line breaks when package names is too long. The name itself breaks and then the version number looks like it's a flex sibling to the packagename, it should probably be inline so that the full name and version are a joined string of text.

…play

- Reset next-env.d.ts to match main branch (.next/dev/types/routes.d.ts)
- Change comparison display from flex to inline span elements
- Package name and version now flow as single text, preventing awkward breaks
- Long package names no longer cause version numbers to appear as separate flex items

Co-authored-by: oBusk <13413409+oBusk@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 7, 2026

@copilot

  1. Do not check in the next-env file, reset it to match main branch.
    ...

Fixed in commit 8556f1d:

  1. Reset next-env.d.ts to match main branch (.next/dev/types/routes.d.ts)
  2. Fixed line breaks by changing comparison display from div with flex items-center to inline span - package name and version now flow as single text string

Fixed comparison display

@oBusk oBusk marked this pull request as ready for review February 8, 2026 14:33
@oBusk oBusk merged commit 9360279 into main Feb 8, 2026
14 checks passed
@oBusk oBusk deleted the copilot/add-catalog-page-dynamic-route branch February 8, 2026 14:33
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.

2 participants

Comments