Skip to content

feat(router-generator): support higher-order wrappers around createFileRoute#7766

Open
dhleong wants to merge 1 commit into
TanStack:mainfrom
dhleong:feat/route-wrapper-generator-support
Open

feat(router-generator): support higher-order wrappers around createFileRoute#7766
dhleong wants to merge 1 commit into
TanStack:mainfrom
dhleong:feat/route-wrapper-generator-support

Conversation

@dhleong

@dhleong dhleong commented Jul 9, 2026

Copy link
Copy Markdown

The route-file transform previously required the exported Route binding to be exactly createFileRoute('/path')({...}), so a route wrapped by a higher-order handler (e.g. wrap('x')(createFileRoute('/path')({...}))) was silently left untouched — no route-id injection, no import management.

This change will recursively locate the single nested createFileRoute(path)(options) call within the exported Route init, regardless of any wrapping calls. The wrapper stays opaque to the generator; only the inner constructor call is rewritten. Malformed wrapped routes now surface the same helpful error.

This is proposed as a first step toward unblocking #7619

Summary by CodeRabbit

  • New Features

    • Route generation now works with route definitions wrapped in higher-order expressions, preserving wrapper code while updating the route call inside.
    • Lazy route handling is now supported even when the route constructor appears within nested wrappers.
  • Bug Fixes

    • Improved error detection for malformed wrapped route definitions.
    • Added clearer failures when a wrapped route call is missing required options or contains multiple route constructor calls.

…leRoute

The route-file transform previously required the exported `Route` binding
to be exactly `createFileRoute('/path')({...})`, so a route wrapped by a
higher-order handler (e.g. `wrap('x')(createFileRoute('/path')({...}))`)
was silently left untouched — no route-id injection, no import management.

Recursively locate the single nested `createFileRoute(path)(options)` call
within the exported `Route` init, regardless of any wrapping calls. The
wrapper stays opaque to the generator; only the inner constructor call is
rewritten. Malformed wrapped routes now surface the same helpful error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 85054867-4ada-442a-8296-4022044ab7bd

📥 Commits

Reviewing files that changed from the base of the PR and between a3e24c3 and 6620e35.

📒 Files selected for processing (2)
  • packages/router-generator/src/transform/transform.ts
  • packages/router-generator/tests/transform.test.ts

📝 Walkthrough

Walkthrough

The route-export analyzer in transform.ts now recursively searches wrapper expressions for nested createFileRoute/createLazyFileRoute calls instead of requiring direct initialization. New helper functions replace the prior direct-call detection, and new tests validate wrapped route id injection, lazy swapping, multiple wrappers, and error cases.

Changes

Higher-order Route Wrapper Support

Layer / File(s) Summary
Route-constructor detection helpers
packages/router-generator/src/transform/transform.ts
getRouteConstructorInit accepts wider node types; new findRouteConstructorInits and containsRouteConstructorCall recursively walk call-expression trees, replacing removed isDirectRouteConstructorCall.
Exported route call discovery
packages/router-generator/src/transform/transform.ts
findExportedRouteCalls traverses the full initializer expression to find nested route-constructor calls and distinguishes malformed calls from unsupported/absent ones using the new helpers.
Wrapper transform tests
packages/router-generator/tests/transform.test.ts
New "higher-order route wrappers" test suite covers route id injection, lazy swapping, nested wrappers, and error cases for missing options or multiple constructor calls.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Transform as transform()
  participant Finder as findExportedRouteCalls
  participant Walker as findRouteConstructorInits
  participant Checker as containsRouteConstructorCall

  Transform->>Finder: analyze exported binding initializer
  Finder->>Walker: traverse expression tree for route constructor inits
  Walker-->>Finder: matched inits (createFileRoute/createLazyFileRoute)
  alt no inits found
    Finder->>Checker: check for any constructor call in tree
    Checker-->>Finder: hasMalformedRouteCall or unsupported
  end
  Finder-->>Transform: calls list or error state
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: supporting higher-order wrappers around createFileRoute.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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