Skip to content

feat: add the new package timeline page to the command palette#2635

Merged
serhalp merged 3 commits into
mainfrom
serhalp/refactor/named-routes-in-cmd-palette-pkg-composable
May 10, 2026
Merged

feat: add the new package timeline page to the command palette#2635
serhalp merged 3 commits into
mainfrom
serhalp/refactor/named-routes-in-cmd-palette-pkg-composable

Conversation

@serhalp
Copy link
Copy Markdown
Member

@serhalp serhalp commented Apr 26, 2026

🔗 Linked issue

N/A

🧭 Context

The string placeholder shape used by useCommandPaletteVersionCommands made callers that already had named route helpers resolve routes to strings and then patch encoded placeholders back into place. This is brittle, especially for routes where vue-router encodes params differently from the URL shape users see.

We have a documented guideline that internal navigation should use route object syntax with named routes instead of strings. This shape was preventing us from respecting our own guideline.

📚 Description

Pass a versioned package route builder to useCommandPaletteVersionCommands instead of a string with a version placeholder.

Note

This PR was originally a pure refactor of useCommandPaletteVersionCommands and #2636 was stacked on it, but since that was accidentally merged into this, this PR now contains both!

The placeholder shape made callers that already had named-route helpers
resolve routes to strings and then patch encoded placeholders back into
place. That was brittle, especially for routes where Vue Router encodes
params differently from the URL shape users see.

We have a documented guideline that internal navigation should use
route object syntax with named routes instead of strings. This commit
allows callers to respect that guideline.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 26, 2026

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

Project Deployment Actions Updated (UTC)
docs.npmx.dev Ready Ready Preview, Comment May 10, 2026 1:57pm
npmx.dev Ready Ready Preview, Comment May 10, 2026 1:57pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
npmx-lunaria Ignored Ignored May 10, 2026 1:57pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 26, 2026

📝 Walkthrough

Walkthrough

Replaces command-palette URL-pattern strings with typed route-builder callbacks that return RouteLocationRaw across pages and the core composable. Adds a package-timeline command and central packageTimelineRoute helper; updates page wiring, header, composable signature, and tests to use route-returning functions.

Changes

Command-palette route builders & timeline

Layer / File(s) Summary
Composable signature / Data shape
app/composables/useCommandPaletteVersionCommands.ts
Changed parameter from a URL pattern ref to `routeForVersion?: MaybeRef<((version: string) => RouteLocationRaw)
Router helper
app/utils/router.ts
Added export function packageTimelineRoute(packageName: string, version: string): RouteLocationRaw to construct timeline route params (org optional, packageName, version).
Pages — version route builders
app/pages/diff/...v/[versionRange].vue, app/pages/package-code/.../v/[version]/[...filePath].vue, app/pages/package-docs/[...path].vue, app/pages/package/[[org]]/[name].vue
Replace computed URL-pattern strings with typed route-builder functions (e.g. fromVersionRoute, codeVersionRoute, docsVersionRoute, per-page builders) that return RouteLocationRaw using current route params and the requested version. Pass these functions into useCommandPaletteVersionCommands.
Package timeline page integration
app/pages/package-timeline/[[org]]/[packageName].vue
Integrates command-palette package-version support: loads versions via useCommandPalettePackageVersions, builds commandPalettePackageContext (resolvedVersion, latestVersion, versions list), registers package context and package commands, and wires useCommandPaletteVersionCommands to navigate to packageTimelineRoute(packageName.value, nextVersion) with onOpen loading.
Package commands
app/composables/useCommandPalettePackageCommands.ts
Added new package-timeline command entry that computes to via packageTimelineRoute(...), uses i18n labels/keywords, and marks active when route.name === 'timeline'.
Component header
app/components/Package/Header.vue
Replaced inline timeline route construction with packageTimelineRoute(props.pkg.name, props.resolvedVersion) call.
Tests / Harness
test/nuxt/composables/use-command-palette-commands.spec.ts
Updated test harness to provide versionRoute: (version) => RouteLocationRaw instead of URL-pattern string; adjusted assertions to inspect command to targets and verify package-timeline command to/params for scoped and unscoped packages.
sequenceDiagram
participant User
participant CommandPalette
participant RouteBuilder
participant Router
participant Page
User->>CommandPalette: invoke "switch version"
CommandPalette->>RouteBuilder: call routeForVersion(selectedVersion)
RouteBuilder->>Router: return RouteLocationRaw -> push
Router->>Page: navigate to version-specific page
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title describes adding a package timeline page to the command palette, which is partially related but does not capture the main refactoring effort of changing how route builders are accepted. Consider revising the title to emphasise the primary change: refactoring useCommandPaletteVersionCommands to accept a route builder callback instead of a string pattern.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly explains the rationale for replacing the string placeholder approach with a typed route builder callback, addressing brittleness in the prior design.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch serhalp/refactor/named-routes-in-cmd-palette-pkg-composable

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 26, 2026

Codecov Report

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

Files with missing lines Patch % Lines
[...[org]]/[packageName]/v/[version]/[...filePath].vue](https://app.codecov.io/gh/npmx-dev/npmx.dev/pull/2635?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=npmx-dev#diff-YXBwL3BhZ2VzL3BhY2thZ2UtY29kZS9bW29yZ11dL1twYWNrYWdlTmFtZV0vdi9bdmVyc2lvbl0vWy4uLmZpbGVQYXRoXS52dWU=) 0.00% 3 Missing ⚠️
app/pages/package/[[org]]/[name].vue 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@serhalp serhalp marked this pull request as ready for review April 27, 2026 00:16
Copy link
Copy Markdown
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 (3)
app/pages/package/[[org]]/[name].vue (1)

490-492: Optional: redundant with the composable's default fallback.

The composable already defaults to packageRoute(context.packageName, version) when no routeForVersion is supplied, so this callback duplicates that behaviour. You could omit the second argument entirely on this page and rely on the default, which would also let you drop the inline arrow.

Proposed simplification
-useCommandPaletteVersionCommands(commandPalettePackageContext, version =>
-  packageRoute(packageName.value, version),
-)
+useCommandPaletteVersionCommands(commandPalettePackageContext)

That said, keeping it explicit is fine if you prefer the call sites to be uniform across pages.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/package/`[[org]]/[name].vue around lines 490 - 492, The call to
useCommandPaletteVersionCommands currently passes an explicit callback
duplicating the composable's default; remove the second argument so the call
becomes useCommandPaletteVersionCommands(commandPalettePackageContext) and let
the composable use its built-in fallback (which constructs
packageRoute(context.packageName, version)), or if you want to keep it explicit
for consistency leave as-is; locate the call to useCommandPaletteVersionCommands
in this file and remove the inline arrow that returns
packageRoute(packageName.value, version) to simplify.
app/pages/package-docs/[...path].vue (1)

127-137: Nit: the destructuring is reconstructing the array it just split.

[firstSegment = name, ...remainingSegments] = name.split('/') followed by [firstSegment, ...remainingSegments, 'v', version] is equivalent to [...name.split('/'), 'v', version]. The destructuring appears to exist solely to satisfy the [string, ...string[]] non-empty-tuple shape without a cast. Consider either spreading directly with a cast (matching the existing pattern at lines 52 and 66 in the same file), or extracting a small helper to share the conversion. Functionally fine as-is.

Possible simplification
 function docsVersionRoute(version: string): RouteLocationRaw {
   const name = pkg.value?.name || packageName.value
-  const [firstSegment = name, ...remainingSegments] = name.split('/')
-
   return {
     name: 'docs',
     params: {
-      path: [firstSegment, ...remainingSegments, 'v', version],
+      path: [...name.split('/'), 'v', version] as [string, ...string[]],
     },
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/package-docs/`[...path].vue around lines 127 - 137, The
destructuring in docsVersionRoute (using [firstSegment = name,
...remainingSegments] = name.split('/')) reconstructs the same array and is
unnecessary; replace it by building params.path directly from the split result
using the same non-empty-tuple cast/pattern used elsewhere (see the file's
existing pattern around lines 52/66) or factor a small helper to convert
string.split('/') into a [string, ...string[]] tuple, then set params.path to
[...thatTuple, 'v', version]; update references to pkg and packageName as needed
to compute the base name before the split.
app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue (1)

90-99: Consider returning a named-route object for consistency with the PR objective.

The PR description notes that the motivation for accepting a route builder is to "use route object syntax with named routes". Here, codeVersionRoute still returns a path string via getCodeUrl, while sibling pages (docsVersionRoute, fromVersionRoute/diffRoute, and the package page) all return named-route objects. Aligning this caller would make the intent uniform and avoid relying on Vue Router's path parsing for params that may need encoding (e.g., scoped names, file paths with special characters).

Proposed refactor
 function codeVersionRoute(nextVersion: string): RouteLocationRaw {
-  return getCodeUrl({
-    org: route.params.org,
-    packageName: route.params.packageName,
-    version: nextVersion,
-    filePath: filePath.value,
-  })
+  return {
+    name: 'code',
+    params: {
+      org: route.params.org,
+      packageName: route.params.packageName,
+      version: nextVersion,
+      filePath: filePath.value ?? '',
+    },
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/package-code/`[[org]]/[packageName]/v/[version]/[...filePath].vue
around lines 90 - 99, codeVersionRoute currently returns a path string from
getCodeUrl but should return a named-route object like the other builders
(docsVersionRoute, fromVersionRoute/diffRoute) to preserve params and encoding;
change codeVersionRoute to return an object of the form { name:
'<code-route-name>', params: { org: route.params.org, packageName:
route.params.packageName, version: nextVersion, filePath: filePath.value } } (or
use the same route name constant used elsewhere) and pass that into
useCommandPaletteVersionCommands so params are preserved and routed via Vue
Router's named-route syntax instead of a path string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/pages/package-code/`[[org]]/[packageName]/v/[version]/[...filePath].vue:
- Around line 90-99: codeVersionRoute currently returns a path string from
getCodeUrl but should return a named-route object like the other builders
(docsVersionRoute, fromVersionRoute/diffRoute) to preserve params and encoding;
change codeVersionRoute to return an object of the form { name:
'<code-route-name>', params: { org: route.params.org, packageName:
route.params.packageName, version: nextVersion, filePath: filePath.value } } (or
use the same route name constant used elsewhere) and pass that into
useCommandPaletteVersionCommands so params are preserved and routed via Vue
Router's named-route syntax instead of a path string.

In `@app/pages/package-docs/`[...path].vue:
- Around line 127-137: The destructuring in docsVersionRoute (using
[firstSegment = name, ...remainingSegments] = name.split('/')) reconstructs the
same array and is unnecessary; replace it by building params.path directly from
the split result using the same non-empty-tuple cast/pattern used elsewhere (see
the file's existing pattern around lines 52/66) or factor a small helper to
convert string.split('/') into a [string, ...string[]] tuple, then set
params.path to [...thatTuple, 'v', version]; update references to pkg and
packageName as needed to compute the base name before the split.

In `@app/pages/package/`[[org]]/[name].vue:
- Around line 490-492: The call to useCommandPaletteVersionCommands currently
passes an explicit callback duplicating the composable's default; remove the
second argument so the call becomes
useCommandPaletteVersionCommands(commandPalettePackageContext) and let the
composable use its built-in fallback (which constructs
packageRoute(context.packageName, version)), or if you want to keep it explicit
for consistency leave as-is; locate the call to useCommandPaletteVersionCommands
in this file and remove the inline arrow that returns
packageRoute(packageName.value, version) to simplify.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 169b561f-bd1c-4767-a514-3083879efdd3

📥 Commits

Reviewing files that changed from the base of the PR and between 69351cf and 2de6a60.

📒 Files selected for processing (6)
  • app/composables/useCommandPaletteVersionCommands.ts
  • app/pages/diff/[[org]]/[packageName]/v/[versionRange].vue
  • app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
  • app/pages/package-docs/[...path].vue
  • app/pages/package/[[org]]/[name].vue
  • test/nuxt/composables/use-command-palette-commands.spec.ts

@serhalp serhalp added the needs review This PR is waiting for a review from a maintainer label Apr 27, 2026
@serhalp serhalp requested a review from ghostdevv April 28, 2026 19:29
@serhalp
Copy link
Copy Markdown
Member Author

serhalp commented May 9, 2026

ping ping bump bump 🙏🏼

@43081j 43081j added this pull request to the merge queue May 10, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 10, 2026
@serhalp serhalp changed the title refactor: accept versioned pkg route builder in useCommandPaletteVersionCommands feat: add the new package timeline page to the command palette May 10, 2026
@serhalp serhalp added this pull request to the merge queue May 10, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 10, 2026
@serhalp serhalp added this pull request to the merge queue May 10, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 10, 2026
@serhalp serhalp added this pull request to the merge queue May 10, 2026
Merged via the queue into main with commit 242acb3 May 10, 2026
37 of 38 checks passed
@serhalp serhalp deleted the serhalp/refactor/named-routes-in-cmd-palette-pkg-composable branch May 10, 2026 15:35
@github-actions github-actions Bot mentioned this pull request May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review This PR is waiting for a review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants