Date: Thu, 5 Feb 2026 00:00:25 +0100
Subject: [PATCH 13/17] Refactor ComparisonList to use specs for diff path
generation and improve key handling
---
.../[...parts]/_page/catalog/ComparisonList.tsx | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/app/[...parts]/_page/catalog/ComparisonList.tsx b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
index 5bd74e2a..3a60778b 100644
--- a/src/app/[...parts]/_page/catalog/ComparisonList.tsx
+++ b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
@@ -3,6 +3,7 @@ import BorderBox from "^/components/ui/BorderBox";
import Heading from "^/components/ui/Heading";
import Stack from "^/components/ui/Stack";
import type { Comparison } from "^/lib/utils/generateComparisons";
+import specsToDiff from "^/lib/utils/specsToDiff";
import VersionWithHighlight from "./VersionWithHighlight";
export interface ComparisonListProps {
@@ -48,18 +49,19 @@ export default function ComparisonList({
- {comparisons.map((comparison, index) => {
+ {comparisons.map((comparison) => {
const highlightIndex = getHighlightIndex(comparison.type);
- const diffString = `${packageName}@${comparison.from}...${packageName}@${comparison.to}`;
- const url = `/${diffString}`;
+ const fromSpec = `${packageName}@${comparison.from}`;
+ const toSpec = `${packageName}@${comparison.to}`;
+ const diffPath = specsToDiff([fromSpec, toSpec]);
return (
From dabf32aab58658e547bed793a4bf683c23dfda07 Mon Sep 17 00:00:00 2001
From: Oscar Busk
Date: Thu, 5 Feb 2026 00:07:29 +0100
Subject: [PATCH 14/17] Refactor PackageMeta to simplify conditional rendering
and improve maintainers and keywords display
---
.../[...parts]/_page/catalog/PackageMeta.tsx | 26 +++++++++----------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/src/app/[...parts]/_page/catalog/PackageMeta.tsx b/src/app/[...parts]/_page/catalog/PackageMeta.tsx
index 23233c32..6fa5235a 100644
--- a/src/app/[...parts]/_page/catalog/PackageMeta.tsx
+++ b/src/app/[...parts]/_page/catalog/PackageMeta.tsx
@@ -87,31 +87,29 @@ export default function PackageMeta({ packument }: PackageMetaProps) {
)}
- {Boolean(
- latestManifest.maintainers &&
- latestManifest.maintainers.length > 0,
- ) && (
+ {latestManifest.maintainers &&
+ latestManifest.maintainers.length > 0 ? (
Maintainers:{" "}
- {latestManifest.maintainers?.length}
+ {latestManifest.maintainers.length}
- )}
+ ) : null}
- {Boolean(keywords && keywords.length > 0) && (
+ {keywords && keywords.length > 0 ? (
- {keywords?.slice(0, 10).map((keyword, index) => (
+ {keywords.slice(0, 10).map((keyword) => (
{keyword}
))}
- )}
+ ) : null}
- {Boolean(repositoryUrl) && (
+ {repositoryUrl ? (
Repository →
- )}
+ ) : null}
- {Boolean(homepageUrl && homepageUrl !== repositoryUrl) && (
+ {homepageUrl && homepageUrl !== repositoryUrl ? (
Homepage →
- )}
+ ) : null}
);
From 5861ec6055a117085d08fb95d3a2385b8a699892 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Feb 2026 14:12:36 +0000
Subject: [PATCH 15/17] Fix bot review issues: remove unused parameter and
reduce duplication
- 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>
---
.../[...parts]/_page/catalog/CatalogPage.tsx | 2 +-
.../_page/catalog/ComparisonList.tsx | 9 +--
.../_page/catalog/PackageNamePrefix.tsx | 12 +++
src/lib/utils/generateComparisons.test.ts | 79 +++----------------
src/lib/utils/generateComparisons.ts | 5 +-
5 files changed, 28 insertions(+), 79 deletions(-)
create mode 100644 src/app/[...parts]/_page/catalog/PackageNamePrefix.tsx
diff --git a/src/app/[...parts]/_page/catalog/CatalogPage.tsx b/src/app/[...parts]/_page/catalog/CatalogPage.tsx
index b3a31f44..441fa4e6 100644
--- a/src/app/[...parts]/_page/catalog/CatalogPage.tsx
+++ b/src/app/[...parts]/_page/catalog/CatalogPage.tsx
@@ -33,7 +33,7 @@ async function CatalogPageInner({ specs }: CatalogPageProps) {
const versions = Object.keys(versionMap);
// Generate comparisons
- const comparisons = generateComparisons(versions, versionMap);
+ const comparisons = generateComparisons(versions);
return (
diff --git a/src/app/[...parts]/_page/catalog/ComparisonList.tsx b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
index 3a60778b..86519fb2 100644
--- a/src/app/[...parts]/_page/catalog/ComparisonList.tsx
+++ b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
@@ -4,6 +4,7 @@ import Heading from "^/components/ui/Heading";
import Stack from "^/components/ui/Stack";
import type { Comparison } from "^/lib/utils/generateComparisons";
import specsToDiff from "^/lib/utils/specsToDiff";
+import PackageNamePrefix from "./PackageNamePrefix";
import VersionWithHighlight from "./VersionWithHighlight";
export interface ComparisonListProps {
@@ -64,9 +65,7 @@ export default function ComparisonList({
aria-label={`Compare ${fromSpec}...${toSpec} (${comparison.type} version change)`}
>
-
- {packageName}@
-
+
...
-
- {packageName}@
-
+
{packageName}@;
+}
diff --git a/src/lib/utils/generateComparisons.test.ts b/src/lib/utils/generateComparisons.test.ts
index ef97f5df..8244492a 100644
--- a/src/lib/utils/generateComparisons.test.ts
+++ b/src/lib/utils/generateComparisons.test.ts
@@ -3,14 +3,13 @@ import { generateComparisons } from "./generateComparisons";
describe("generateComparisons", () => {
it("returns empty array for package with 0 versions", () => {
- const result = generateComparisons([], {});
+ const result = generateComparisons([]);
expect(result).toEqual([]);
});
it("returns empty array for package with 1 version", () => {
const versions = ["1.0.0"];
- const versionMap = { "1.0.0": { time: "2020-01-01" } };
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
expect(result).toEqual([]);
});
@@ -33,29 +32,15 @@ describe("generateComparisons", () => {
"3.1.4",
"3.1.5",
];
- const versionMap: Record = {};
- versions.forEach((v, i) => {
- versionMap[v] = {
- time: `2020-01-${String(i + 1).padStart(2, "0")}`,
- };
- });
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
expect(result).toHaveLength(10);
});
it("identifies major bumps correctly", () => {
const versions = ["1.0.0", "1.9.4", "2.0.0", "2.5.0", "3.0.0", "3.1.0"];
- const versionMap: Record = {
- "1.0.0": { time: "2020-01-01" },
- "1.9.4": { time: "2020-06-01" },
- "2.0.0": { time: "2020-07-01" },
- "2.5.0": { time: "2020-12-01" },
- "3.0.0": { time: "2021-01-01" },
- "3.1.0": { time: "2021-02-01" },
- };
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
// Should include major bumps: 3.0.0 vs 2.5.0, 2.0.0 vs 1.9.4
const majorBumps = result.filter((c) => c.type === "major");
@@ -74,15 +59,8 @@ describe("generateComparisons", () => {
it("identifies minor bumps correctly", () => {
const versions = ["2.0.0", "2.0.12", "2.1.0", "2.1.3", "2.2.0"];
- const versionMap: Record = {
- "2.0.0": { time: "2020-01-01" },
- "2.0.12": { time: "2020-06-01" },
- "2.1.0": { time: "2020-07-01" },
- "2.1.3": { time: "2020-12-01" },
- "2.2.0": { time: "2021-01-01" },
- };
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
const minorBumps = result.filter((c) => c.type === "minor");
expect(minorBumps.length).toBeGreaterThan(0);
@@ -100,14 +78,8 @@ describe("generateComparisons", () => {
it("identifies patch bumps correctly", () => {
const versions = ["2.1.3", "2.1.4", "2.1.5", "2.1.6"];
- const versionMap: Record = {
- "2.1.3": { time: "2020-01-01" },
- "2.1.4": { time: "2020-02-01" },
- "2.1.5": { time: "2020-03-01" },
- "2.1.6": { time: "2020-04-01" },
- };
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
const patchBumps = result.filter((c) => c.type === "patch");
expect(patchBumps.length).toBeGreaterThan(0);
@@ -120,13 +92,8 @@ describe("generateComparisons", () => {
it("returns fewer than 10 comparisons for packages with few versions", () => {
const versions = ["1.0.0", "1.0.1", "1.0.2"];
- const versionMap: Record = {
- "1.0.0": { time: "2020-01-01" },
- "1.0.1": { time: "2020-02-01" },
- "1.0.2": { time: "2020-03-01" },
- };
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
expect(result.length).toBeLessThanOrEqual(2);
});
@@ -144,14 +111,8 @@ describe("generateComparisons", () => {
"10.0.0",
"11.0.0",
];
- const versionMap: Record = {};
- versions.forEach((v, i) => {
- versionMap[v] = {
- time: `2020-${String(i + 1).padStart(2, "0")}-01`,
- };
- });
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
// Should have 10 major bumps (since there are no minor/patch bumps)
expect(result).toHaveLength(10);
@@ -161,14 +122,8 @@ describe("generateComparisons", () => {
it("sorts comparisons by semver version (newest first)", () => {
const versions = ["1.0.0", "1.0.1", "2.0.0", "2.0.1"];
- const versionMap: Record = {
- "1.0.0": { time: "2020-01-01" },
- "1.0.1": { time: "2020-02-01" },
- "2.0.0": { time: "2020-03-01" },
- "2.0.1": { time: "2020-04-01" },
- };
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
// Should be sorted by semver version (newest first), not by publish date
for (let i = 0; i < result.length - 1; i++) {
@@ -190,14 +145,8 @@ describe("generateComparisons", () => {
"2.0.0",
"2.0.1",
];
- const versionMap: Record = {};
- versions.forEach((v, i) => {
- versionMap[v] = {
- time: `2020-01-${String(i + 1).padStart(2, "0")}`,
- };
- });
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
// Should not include any prerelease versions in comparisons
expect(result.length).toBeGreaterThan(0);
@@ -215,14 +164,8 @@ describe("generateComparisons", () => {
"19.2.4",
"19.2.3",
];
- const versionMap: Record = {};
- versions.forEach((v, i) => {
- versionMap[v] = {
- time: `2025-12-${String(i + 1).padStart(2, "0")}`,
- };
- });
- const result = generateComparisons(versions, versionMap);
+ const result = generateComparisons(versions);
// Should not include any patch comparisons between 19.3.0-canary versions
// since they all have the same major.minor.patch
diff --git a/src/lib/utils/generateComparisons.ts b/src/lib/utils/generateComparisons.ts
index cd3852cb..ede5a80f 100644
--- a/src/lib/utils/generateComparisons.ts
+++ b/src/lib/utils/generateComparisons.ts
@@ -14,10 +14,7 @@ export interface Comparison {
* - If any category has fewer than target, backfill from: Majors > Minors > Patches
* - Total must be 10 unless package has < 11 versions
*/
-export function generateComparisons(
- versions: string[],
- _versionMap: Record,
-): Comparison[] {
+export function generateComparisons(versions: string[]): Comparison[] {
// Filter out invalid versions and prereleases
const validVersions = versions.filter(
(v) => semver.valid(v) && !semver.prerelease(v),
From 8556f1de613a0483152a2d486317f0182b690862 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Feb 2026 14:28:21 +0000
Subject: [PATCH 16/17] Fix UI issues: reset next-env.d.ts and fix line breaks
in version display
- 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>
---
next-env.d.ts | 2 +-
src/app/[...parts]/_page/catalog/ComparisonList.tsx | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/next-env.d.ts b/next-env.d.ts
index 9edff1c7..c4b7818f 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-import "./.next/types/routes.d.ts";
+import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/src/app/[...parts]/_page/catalog/ComparisonList.tsx b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
index 86519fb2..158d357a 100644
--- a/src/app/[...parts]/_page/catalog/ComparisonList.tsx
+++ b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
@@ -64,7 +64,7 @@ export default function ComparisonList({
prefetch={false}
aria-label={`Compare ${fromSpec}...${toSpec} (${comparison.type} version change)`}
>
-
+
{comparison.type}
From 6bc3392f78691450b944052ea7fbd345b660882e Mon Sep 17 00:00:00 2001
From: Oscar Busk
Date: Sun, 8 Feb 2026 15:30:49 +0100
Subject: [PATCH 17/17] Make catalog page accomodate longer package names
---
src/app/[...parts]/_page/catalog/CatalogPage.tsx | 4 ++--
.../[...parts]/_page/catalog/ComparisonList.tsx | 15 ++++++++++++++-
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/app/[...parts]/_page/catalog/CatalogPage.tsx b/src/app/[...parts]/_page/catalog/CatalogPage.tsx
index 441fa4e6..0843243d 100644
--- a/src/app/[...parts]/_page/catalog/CatalogPage.tsx
+++ b/src/app/[...parts]/_page/catalog/CatalogPage.tsx
@@ -37,7 +37,7 @@ async function CatalogPageInner({ specs }: CatalogPageProps) {
return (
-
+
@@ -55,7 +55,7 @@ async function CatalogPageInner({ specs }: CatalogPageProps) {
function CatalogPageFallback() {
return (
-
+
diff --git a/src/app/[...parts]/_page/catalog/ComparisonList.tsx b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
index 158d357a..2112ed77 100644
--- a/src/app/[...parts]/_page/catalog/ComparisonList.tsx
+++ b/src/app/[...parts]/_page/catalog/ComparisonList.tsx
@@ -26,6 +26,12 @@ function getHighlightIndex(type: "major" | "minor" | "patch"): number {
}
}
+/**
+ * Threshold for omitting the package name in the "to" spec
+ * When package name is 24+ characters, we show "pkg@1.0.0...2.0.0" instead of "pkg@1.0.0...pkg@2.0.0"
+ */
+const PACKAGE_NAME_LENGTH_THRESHOLD = 24;
+
/**
* Right column showing the list of comparisons
*/
@@ -33,6 +39,9 @@ export default function ComparisonList({
packageName,
comparisons,
}: ComparisonListProps) {
+ const showSecondPackageName =
+ packageName.length < PACKAGE_NAME_LENGTH_THRESHOLD;
+
if (comparisons.length === 0) {
return (
@@ -73,7 +82,11 @@ export default function ComparisonList({
...
-
+ {showSecondPackageName ? (
+
+ ) : null}