Skip to content

fix(packages/core): emit sidebar keys for orphaned workspace children#74

Merged
zrosenbauer merged 5 commits intomainfrom
fix/workspaces
Mar 25, 2026
Merged

fix(packages/core): emit sidebar keys for orphaned workspace children#74
zrosenbauer merged 5 commits intomainfrom
fix/workspaces

Conversation

@zrosenbauer
Copy link
Copy Markdown
Member

Summary

  • Fixes multi-sidebar routing when workspace items (apps/packages) use paths outside the parent prefix (e.g. /libs/ai under parent /packages)
  • Rspress prefix matching could not find a sidebar key for those pages, causing the sidebar to silently disappear
  • Emits extra sidebar keys for each "orphaned" child link so pages at those paths resolve to the correct sidebar

Changes

  • packages/core/src/sync/sidebar/multi.ts — Added collectOrphanedChildLinks() helper and emit orphaned keys in buildMultiSidebar()
  • packages/core/src/sync/sidebar/multi.test.ts — New test file with 9 tests covering orphaned keys, aligned paths, mixed children, and edge cases

Testing

  • All 149 existing core tests pass
  • 9 new tests covering:
    • Orphaned child keys are created when paths diverge from parent prefix
    • No extra keys when children align with parent prefix
    • Mixed children (some aligned, some orphaned)
    • Sidebar content is shared between parent and orphaned keys
    • Empty standalone entries handled gracefully
    • Key sort order preserved

When workspace items (apps/packages) use paths outside the parent
prefix (e.g. `/libs/ai` under parent `/packages`), Rspress prefix
matching could not find a sidebar key and the sidebar silently
disappeared. Extra sidebar keys are now emitted for each orphaned
child link so pages at those paths resolve to the correct sidebar.

Co-Authored-By: Claude <noreply@anthropic.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 25, 2026

🦋 Changeset detected

Latest commit: 1dc727d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@zpress/core Patch
@zpress/cli Patch
@zpress/ui Patch
@zpress/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 25, 2026

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

Project Deployment Actions Updated (UTC)
oss-zpress Ready Ready Preview, Comment Mar 25, 2026 5:10am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

A Changesets entry was added to publish a patch for @zpress/core. buildMultiSidebar was updated with a new collectOrphanedChildLinks() helper to emit extra sidebar key variants for standalone sections when child links do not share the parent prefix. Two key variants (childLink and childLink/) are emitted pointing to the parent sidebar items. A new Vitest test file was added to exercise orphaned-key generation, key ordering, content mapping, behavior when standalone entries have no items, and that orphaned sidebar content begins with the parent landing link.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(packages/core): emit sidebar keys for orphaned workspace children' directly describes the main change: emitting sidebar keys for orphaned workspace child paths that fall outside parent prefixes.
Description check ✅ Passed The description comprehensively explains the issue (prefix matching failure for out-of-prefix child paths), the solution (emitting extra sidebar keys), changes made, and testing coverage—all directly related to the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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


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

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/sync/sidebar/multi.test.ts`:
- Line 187: The test uses the long-form generic array type for the sidebar
variable; change the type annotation on sidebar (const sidebar =
result['/libs/ai/'] as Array<{ text: string; link: string }>) to the shorthand
T[] form (i.e., use { text: string; link: string }[]), updating the cast on
result['/libs/ai/'] to the shorter array type.
- Around line 169-171: The test currently mutates via
[...lengths].sort(...)—replace that with an immutable sort using
Array.prototype.toSorted on the lengths array (e.g., use lengths.toSorted((a,b)
=> b - a)) and update the `sorted` assignment accordingly so `lengths` is not
mutated; refer to the `lengths` and `sorted` variables in multi.test.ts and keep
the existing expect(lengths).toEqual(sorted) assertion semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0734b4d2-952e-4da5-9e59-1c0d6717b4aa

📥 Commits

Reviewing files that changed from the base of the PR and between 0113fb1 and 899e1f6.

📒 Files selected for processing (3)
  • .changeset/fix-orphaned-workspace-sidebar.md
  • packages/core/src/sync/sidebar/multi.test.ts
  • packages/core/src/sync/sidebar/multi.ts

Use toSorted() instead of spread+sort and T[] syntax instead of Array<T>.

Co-Authored-By: Claude <noreply@anthropic.com>
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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/sync/sidebar/multi.test.ts`:
- Around line 84-85: Change the two assertions to check referential equality
rather than deep equality: assert that result['/libs/ai/'] and
result['/libs/db/'] are the exact same array instance as result['/packages/']
(use toBe instead of toEqual). This ensures the test verifies the orphaned keys
in the multi.ts implementation (the code that assigns the same sidebarItems
array reference) still returns the same array object, not just an equal copy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 71b7ab90-9e2a-446d-b368-999099b15498

📥 Commits

Reviewing files that changed from the base of the PR and between 899e1f6 and f077024.

📒 Files selected for processing (1)
  • packages/core/src/sync/sidebar/multi.test.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Zac Rosenbauer <zac@joggr.io>
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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/sync/sidebar/multi.test.ts`:
- Around line 186-190: The test dereferences sidebar[0] without asserting the
array is non-empty; add an explicit assertion that the computed sidebar from
buildMultiSidebar(entries, []) is not empty (e.g.,
expect(sidebar.length).toBeGreaterThan(0) or
expect(sidebar).not.toHaveLength(0)) immediately before the existing check so
failures clearly show missing/empty sidebar content rather than an out-of-bounds
access on sidebar[0].
- Around line 69-86: Update the test in multi.test.ts that calls
buildMultiSidebar to also assert that non-trailing orphaned keys reuse the same
sidebar reference: after the existing expect checks for result['/libs/ai/'] and
result['/libs/db/'] equaling result['/packages/'], add asserts that
result['/libs/ai'] and result['/libs/db'] are strictly equal to
result['/packages/'] as well so both trailing-slash and non-trailing-slash
orphan keys reuse the same sidebar object produced by buildMultiSidebar.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dccf606c-9409-4901-96e8-bc67bc20e467

📥 Commits

Reviewing files that changed from the base of the PR and between f077024 and 512e141.

📒 Files selected for processing (1)
  • packages/core/src/sync/sidebar/multi.test.ts

- Assert sidebar is non-empty before accessing sidebar[0]
- Assert both trailing-slash and non-trailing-slash orphaned keys
  match the parent sidebar content

Co-Authored-By: Claude <noreply@anthropic.com>
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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/sync/sidebar/multi.test.ts`:
- Around line 188-191: The test dereferences result['/libs/ai/'] into sidebar
and immediately accesses sidebar.length which can throw if the key is missing;
update the test around buildMultiSidebar(entries, [])/result to first assert the
key exists (e.g. expect(result['/libs/ai/']).toBeDefined() or expect('/libs/ai/'
in result).then narrow to the typed sidebar variable before asserting
expect(sidebar.length).toBeGreaterThan(0) so the failure is a clear assertion
rather than a runtime throw.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 544e15cd-4b74-4a1a-94d5-ea2e626894df

📥 Commits

Reviewing files that changed from the base of the PR and between 512e141 and 1dc727d.

📒 Files selected for processing (1)
  • packages/core/src/sync/sidebar/multi.test.ts

@zrosenbauer zrosenbauer merged commit e3b8c86 into main Mar 25, 2026
5 checks passed
@zrosenbauer zrosenbauer deleted the fix/workspaces branch March 25, 2026 05:17
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.

1 participant