-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat: allow regex for indexToken and routeToken #6354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughThis PR adds support for regex-style token matchers for Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Generator
participant ConfigLoader
participant TokenUtils
participant RouteDiscovery
User->>Generator: initialize with inline config
Generator->>ConfigLoader: load tsr.config.json (if present) and merge
ConfigLoader-->>Generator: merged Config with TokenMatcher tokens
Generator->>TokenUtils: createTokenRegex(token, type:'filename'|'segment')
TokenUtils-->>Generator: TokenRegexBundle (4 RegExp)
Generator->>RouteDiscovery: getRouteNodes(root, tokenRegexes)
RouteDiscovery->>RouteDiscovery: detect tokens using segment regexes
RouteDiscovery->>TokenUtils: unwrapBracketWrappedSegment if escaped
RouteDiscovery-->>Generator: route nodes / route tree
Generator-->>User: built route tree
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
|
View your CI Pipeline Execution ↗ for commit 029f14a
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this 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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/router-generator/src/filesystem/virtual/getRouteNodes.ts (1)
150-171: NormalizephysicalDirectoriesto absolute paths for consistent path matching in downstream checks.In nested virtual-inside-physical configurations, the
physicalDirectoriesarray accumulates paths with inconsistent bases. Whennode.directoryis relative tofullDirandphysicalDirectoriesfromgetRouteNodesPhysicalare relative toresolve(fullDir, node.directory), they create a mismatch. Later, ingenerator.ts, the checkthis.physicalDirectories.some((dir) => filePath.startsWith(dir))may fail if paths aren't aligned to the same scale. Normalizing to absolute paths ensures reliable matching across nesting levels.Proposed fix
if (node.type === 'physical') { const { routeNodes, physicalDirectories } = await getRouteNodesPhysical( { ...tsrConfig, routesDirectory: resolve(fullDir, node.directory), }, root, tokenRegexes, ) - allPhysicalDirectories.push(node.directory, ...physicalDirectories) + // Normalize to absolute paths for downstream `startsWith(...)` checks + allPhysicalDirectories.push( + resolve(fullDir, node.directory), + ...physicalDirectories.map((d) => resolve(fullDir, d)), + ) routeNodes.forEach((subtreeNode) => { subtreeNode.variableName = routePathToVariable( `${node.pathPrefix}/${removeExt(subtreeNode.filePath)}`, )
🧹 Nitpick comments (5)
packages/router-generator/src/config.ts (1)
208-231: Consider whether semantically equivalent tokens should be detected.The
areTokensEqualfunction compares tokens strictly by form (string vs RegExp vs JSON object). A user could bypass the equality check by specifying semantically equivalent tokens in different forms (e.g.,indexToken: "index"androuteToken: { regex: "^index$" }).This may be intentional—if so, no action needed. Otherwise, consider normalizing tokens to a common form before comparison.
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (2)
261-268: Escape special regex characters in segment before constructing RegExp.The
stripSegmentvariable comes from file path segments which could contain regex metacharacters (e.g.,$,.,(,)). While the static analysis ReDoS warning is low-risk since this is filesystem input, unescaped metacharacters could cause unexpected matching behavior.Proposed fix: escape regex metacharacters
+ const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + if (suffixToStrip || shouldStripRouteToken) { const stripSegment = suffixToStrip ?? lastRouteSegment - routePath = routePath.replace(new RegExp(`/${stripSegment}$`), '') + routePath = routePath.replace(new RegExp(`/${escapeRegex(stripSegment)}$`), '') originalRoutePath = originalRoutePath.replace( - new RegExp(`/${stripSegment}$`), + new RegExp(`/${escapeRegex(stripSegment)}$`), '', ) }Alternatively, use string methods like
endsWith+sliceto avoid regex entirely.
301-312: Same regex escaping concern applies here.The
updatedLastRouteSegmentandindexTokenCandidatevariables should also be escaped when used in RegExp constructors, or replaced with string-based suffix removal.Proposed fix
+ const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + routePath = routePath.replace( - new RegExp(`/${updatedLastRouteSegment}$`), + new RegExp(`/${escapeRegex(updatedLastRouteSegment)}$`), '/', ) || (isLayoutRoute ? '' : '/') originalRoutePath = originalRoutePath.replace( - new RegExp(`/${indexTokenCandidate}$`), + new RegExp(`/${escapeRegex(indexTokenCandidate)}$`), '/', ) || (isLayoutRoute ? '' : '/')packages/router-generator/tests/generator.test.ts (1)
51-62: Consider always passing the fixture folder asconfigDirectoryto keep tests hermetic.packages/router-generator/src/generator.ts (1)
195-242: Good split of filename-vs-segment regexes; ensure segment regexes aren’t stateful (g/y) since you call.test.(If
createTokenRegexsanitizesg/y, this is fully addressed.)
Optionally: once sanitized, consider swapping.match(...)to.test(...)to avoid allocations.Also applies to: 362-375, 394-401, 584-597
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
docs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/src/config.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/src/generator.tspackages/router-generator/src/utils.tspackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsonpackages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.jsonpackages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.jsonpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
🧰 Additional context used
📓 Path-based instructions (3)
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
Use relative links to
docs/folder format (e.g.,./guide/data-loading) for internal documentation references
Files:
docs/router/framework/react/routing/file-naming-conventions.mddocs/router/api/file-based-routing.md
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/src/config.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/src/utils.tspackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/src/config.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/src/utils.tspackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
🧠 Learnings (12)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
packages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsondocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/src/config.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/src/utils.tspackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
packages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsondocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/src/config.tsdocs/router/api/file-based-routing.mdpackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/src/utils.tspackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
packages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsondocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/src/config.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Applied to files:
packages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsondocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/src/config.tsdocs/router/api/file-based-routing.mdpackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.jsonpackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
docs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxdocs/router/api/file-based-routing.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.
Applied to files:
docs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/src/config.tsdocs/router/api/file-based-routing.mdpackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/src/utils.tspackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-09-28T21:41:45.233Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5284
File: e2e/react-start/basic/server.js:50-0
Timestamp: 2025-09-28T21:41:45.233Z
Learning: In Express v5, catch-all routes must use named wildcards. Use `/*splat` to match everything except root path, or `/{*splat}` (with braces) to match including root path. The old `*` syntax is not allowed and will cause "Missing parameter name" errors. This breaking change requires explicit naming of wildcard parameters.
Applied to files:
docs/router/framework/react/routing/file-naming-conventions.mddocs/router/api/file-based-routing.md
📚 Learning: 2025-10-14T18:59:33.990Z
Learnt from: FatahChan
Repo: TanStack/router PR: 5475
File: e2e/react-start/basic-prerendering/src/routes/redirect/$target/via-beforeLoad.tsx:8-0
Timestamp: 2025-10-14T18:59:33.990Z
Learning: In TanStack Router e2e test files, when a route parameter is validated at the route level (e.g., using zod in validateSearch or param validation), switch statements on that parameter do not require a default case, as the validation ensures only expected values will reach the switch.
Applied to files:
packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.ts
📚 Learning: 2025-09-22T00:56:49.237Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5182
File: e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx:3-5
Timestamp: 2025-09-22T00:56:49.237Z
Learning: In TanStack Router, underscores are intentionally stripped from route segments (e.g., `$baz_` becomes `baz` in generated types) but should be preserved in base path segments. This is the correct behavior as of the fix in PR #5182.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
📚 Learning: 2025-09-22T00:56:53.426Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5182
File: e2e/react-router/basic-file-based/tests/non-nested-paths.spec.ts:167-172
Timestamp: 2025-09-22T00:56:53.426Z
Learning: In TanStack Router, underscores are intentionally stripped from route segments during path parsing, but preserved in base path segments. This is the expected behavior implemented in PR #5182.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
📚 Learning: 2025-12-17T02:17:47.423Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:47.423Z
Learning: In packages/router-generator/src/generator.ts, enforce that pathless_layout routes with a cleanedPath must have a path property. This is required because child routes inherit the parent's path; without a path property, the full path will not resolve correctly at runtime. Update the route type/validation to require path for such routes and add tests ensuring that a pathless_layout with cleanedPath provides a valid fullPath resolution.
Applied to files:
packages/router-generator/src/generator.ts
🧬 Code graph analysis (8)
packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsx (9)
packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsx (1)
Route(3-10)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsx (1)
Route(3-5)
packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsx (8)
packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsx (1)
Route(3-5)
packages/router-generator/tests/generator.test.ts (1)
packages/router-generator/src/config.ts (1)
getConfig(89-170)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (2)
packages/router-generator/src/utils.ts (1)
unwrapBracketWrappedSegment(479-481)packages/router-generator/src/types.ts (1)
FsRouteType(24-34)
packages/router-generator/src/filesystem/virtual/getRouteNodes.ts (1)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (1)
TokenRegexBundle(27-30)
packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx (1)
packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx (1)
Route(3-5)
packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsx (9)
packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsx (1)
Route(3-10)packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsx (1)
Route(3-10)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsx (1)
Route(3-5)
packages/router-generator/src/utils.ts (1)
packages/router-generator/src/config.ts (1)
TokenMatcher(20-20)
🪛 ast-grep (0.40.4)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
[warning] 262-262: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${stripSegment}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 264-264: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${stripSegment}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 302-302: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${updatedLastRouteSegment}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 308-308: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${indexTokenCandidate}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
packages/router-generator/src/utils.ts
[warning] 438-438: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${escapeRegExp(token)}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 439-439: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp([./]${escapeRegExp(token)}[.])
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 444-444: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^(?:${token.source})$, token.flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 445-445: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp([./](?:${token.source})[.], token.flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 451-451: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^(?:${token.regex})$, token.flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 452-452: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp([./](?:${token.regex})[.], token.flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
🔇 Additional comments (26)
packages/router-generator/tests/generator/regex-tokens-json/tsr.config.json (1)
1-4: LGTM! Well-structured test fixture for regex token validation.The regex patterns correctly demonstrate the new feature, matching custom-named route files (e.g.,
home-page,main-layout) while preserving route behavior.packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsx (1)
1-5: LGTM! Standard route definition.The route file correctly demonstrates a regular route file that works alongside the regex token feature for testing purposes.
packages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.json (1)
1-5: LGTM! Valid test configuration.Standard virtual route config setup for testing purposes.
packages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.json (1)
1-5: LGTM! Valid test configuration.Standard virtual route config setup for testing default export behavior.
docs/router/api/file-based-routing.md (1)
104-170: Excellent documentation of the new regex token feature!The documentation is comprehensive and well-structured, covering:
- JSON and inline configuration formats for both
routeTokenandindexToken- Practical filename examples demonstrating matching behavior
- Important clarifications about entire segment matching
- Escaping guidance for edge cases
The examples and notes effectively guide users in adopting this feature for custom file naming patterns.
docs/router/framework/react/routing/file-naming-conventions.md (1)
7-18: LGTM! Clear documentation of regex pattern support.The updated table entries accurately describe the new capability for
indexTokenandrouteTokento accept both strings and regex patterns, with appropriate links to the API documentation for detailed configuration options.packages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsx (1)
1-5: LGTM! Clean test fixture for root route.This test file correctly defines a root route using
createFileRouteand will serve as an appropriate fixture for testing the regex token matching feature whereindex-page.tsxis matched by a customindexTokenpattern.packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsx (1)
1-5: LGTM! Correct index route definition.The route correctly uses
/dashboard/with a trailing slash to represent an index route under the dashboard path. This appropriately tests the customindexTokenpattern wherehome-pagereplaces the defaultindextoken.packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsx (1)
1-10: LGTM! Proper layout route structure.The layout route correctly imports and uses
Outletfor nested route rendering, with the path/dashboard(without trailing slash) appropriately representing a parent layout route. This effectively tests the customrouteTokenpattern wheremain-layoutreplaces the defaultroutetoken.packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsx (1)
1-5: LGTM! Clean leaf route definition.This route correctly defines a nested page under the dashboard path. The simple structure is appropriate for a test fixture validating the regex token matching functionality.
packages/router-generator/src/config.ts (3)
7-20: Well-structured token schema definitions.The schema correctly supports all three token forms: plain strings, RegExp instances, and JSON regex objects (for config file serialization). The type exports make the API clear for consumers.
40-41: Token configuration update looks good.The
indexTokenandrouteTokenfields now accept the flexibletokenMatcherSchema, with sensible string defaults maintaining backward compatibility.
102-111: Config merging order is correct.The inline config properly overrides file config values. Parsing once after merging ensures defaults are applied correctly without file values being overwritten by inline defaults.
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (2)
22-30: Clean interface for pre-compiled token regexes.The
TokenRegexBundleinterface properly encapsulates the pre-compiled regexes, avoiding repeated regex compilation during route crawling. Good design for performance.
282-313: Verify whether layout routes with names matching the index token pattern are tested.The test suite includes
regex-tokens-inlineandregex-tokens-jsontest cases that verify the generator with regex index and route tokens. These tests confirm that layout routes (e.g.,dashboard.main-layout) and index routes (e.g.,index-page,dashboard.home-page) are correctly generated. However, the specific edge case where a layout route's filename itself matches the index token pattern (e.g., a layout route named to match/[a-z]+-page/) is not explicitly covered by existing test snapshots. The current tests validate layout routes matching the routeToken pattern and index routes matching the indexToken pattern separately, but not the intersection of these conditions.packages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts (1)
1-104: Snapshot file - no review needed.Based on learnings, test snapshot files in the router-generator tests directory are fixtures used to verify the generator's output and should be preserved as-is.
packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsx (1)
1-10: Test fixture for regex token layout route.This test file correctly demonstrates the
main-layouttoken pattern matching for the/dashboardroute with an<Outlet />for nested routes. Aligns with theregex-tokens-jsonvariant.packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsx (1)
1-5: Test fixture for regex token index route.Correctly defines the root index route using the
index-pagenaming pattern that should be matched by the regexindexTokenconfiguration.packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx (1)
1-5: Standard root route definition.Follows the established pattern for root route files in the test suite.
packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsx (1)
1-5: Test fixture for dashboard index route.Correctly defines the dashboard index route at
/dashboard/using thehome-pagenaming pattern for regex token matching.packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx (1)
1-5: Looks good for a test fixture root route.packages/router-generator/tests/generator.test.ts (1)
161-167: Inline RegExp token fixture looks good.packages/router-generator/src/filesystem/virtual/getRouteNodes.ts (1)
42-88: TokenRegexBundle threading looks consistent.Also applies to: 129-159
packages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.ts (1)
1-121: Generated snapshot fixture — skipping review.packages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.ts (1)
1-121: Generated snapshot fixture — skipping review.packages/router-generator/src/utils.ts (1)
475-481: No action needed.isBracketWrappedSegmentandunwrapBracketWrappedSegmentare only used within a constrained context where route paths are split by/into individual segments, preventing compound strings like"[a][b]". All callers validate bracket wrapping before unwrapping.
ece084f to
029f14a
Compare
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In @packages/router-generator/tests/generator.test.ts:
- Around line 301-315: Update the test to use regexes that match
createTokenRegex's output for default string tokens by replacing the
non-capturing-group patterns passed to virtualGetRouteNodes with plain anchors —
use /^index$/ and /^route$/ (or generate them via createTokenRegex('index') and
createTokenRegex('route')) so the test aligns with how createTokenRegex produces
/^index$/ and /^route$/ for string tokens when invoking virtualGetRouteNodes.
🧹 Nitpick comments (2)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (2)
262-268: Escape regex special characters in path segments.The
stripSegmentvariable (derived from file paths) is used directly inRegExpconstructor without escaping. While the risk is low since these come from filesystem paths with anchored patterns, it's safer to escape special regex characters.🛡️ Proposed fix to escape regex special characters
Add an escape helper at the top of the file if not already imported:
+function escapeRegExpChars(s: string): string { + return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +}Then apply it to the segment:
if (suffixToStrip || shouldStripRouteToken) { const stripSegment = suffixToStrip ?? lastRouteSegment - routePath = routePath.replace(new RegExp(`/${stripSegment}$`), '') + routePath = routePath.replace(new RegExp(`/${escapeRegExpChars(stripSegment)}$`), '') originalRoutePath = originalRoutePath.replace( - new RegExp(`/${stripSegment}$`), + new RegExp(`/${escapeRegExpChars(stripSegment)}$`), '', ) }
301-312: Escape regex special characters in index token handling.Similar to the suffix stripping logic, the
updatedLastRouteSegmentandindexTokenCandidatevariables should be escaped before use inRegExpconstructor.🛡️ Proposed fix to escape regex special characters
routePath = routePath.replace( - new RegExp(`/${updatedLastRouteSegment}$`), + new RegExp(`/${escapeRegExpChars(updatedLastRouteSegment)}$`), '/', ) || (isLayoutRoute ? '' : '/') originalRoutePath = originalRoutePath.replace( - new RegExp(`/${indexTokenCandidate}$`), + new RegExp(`/${escapeRegExpChars(indexTokenCandidate)}$`), '/', ) || (isLayoutRoute ? '' : '/')
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
docs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/src/config.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/src/generator.tspackages/router-generator/src/utils.tspackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsxpackages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsonpackages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.jsonpackages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.jsonpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
🚧 Files skipped from review as they are similar to previous changes (10)
- packages/router-generator/tests/generator/virtual-config-file-named-export/tsr.config.json
- packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsx
- packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsx
- packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx
- packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsx
- packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsx
- packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.settings.tsx
- packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx
- packages/router-generator/tests/generator/virtual-config-file-default-export/tsr.config.json
- packages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
packages/router-generator/src/generator.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/src/utils.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
packages/router-generator/src/generator.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/src/utils.ts
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
Use relative links to
docs/folder format (e.g.,./guide/data-loading) for internal documentation references
Files:
docs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.md
🧠 Learnings (12)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
packages/router-generator/src/generator.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tsdocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsonpackages/router-generator/src/utils.ts
📚 Learning: 2025-12-17T02:17:47.423Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:47.423Z
Learning: In packages/router-generator/src/generator.ts, enforce that pathless_layout routes with a cleanedPath must have a path property. This is required because child routes inherit the parent's path; without a path property, the full path will not resolve correctly at runtime. Update the route type/validation to require path for such routes and add tests ensuring that a pathless_layout with cleanedPath provides a valid fullPath resolution.
Applied to files:
packages/router-generator/src/generator.ts
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
packages/router-generator/src/generator.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tsdocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsonpackages/router-generator/src/utils.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.
Applied to files:
packages/router-generator/src/generator.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tsdocs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/src/utils.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
packages/router-generator/src/generator.tspackages/router-generator/src/filesystem/physical/getRouteNodes.tsdocs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/tsr.config.jsonpackages/router-generator/src/utils.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.tsdocs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/src/filesystem/virtual/getRouteNodes.tspackages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsxpackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.tspackages/router-generator/src/utils.ts
📚 Learning: 2025-09-22T00:56:49.237Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5182
File: e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx:3-5
Timestamp: 2025-09-22T00:56:49.237Z
Learning: In TanStack Router, underscores are intentionally stripped from route segments (e.g., `$baz_` becomes `baz` in generated types) but should be preserved in base path segments. This is the correct behavior as of the fix in PR #5182.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.tspackages/router-generator/src/utils.ts
📚 Learning: 2025-09-22T00:56:53.426Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5182
File: e2e/react-router/basic-file-based/tests/non-nested-paths.spec.ts:167-172
Timestamp: 2025-09-22T00:56:53.426Z
Learning: In TanStack Router, underscores are intentionally stripped from route segments during path parsing, but preserved in base path segments. This is the expected behavior implemented in PR #5182.
Applied to files:
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
docs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.mdpackages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsxpackages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts
📚 Learning: 2025-09-28T21:41:45.233Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5284
File: e2e/react-start/basic/server.js:50-0
Timestamp: 2025-09-28T21:41:45.233Z
Learning: In Express v5, catch-all routes must use named wildcards. Use `/*splat` to match everything except root path, or `/{*splat}` (with braces) to match including root path. The old `*` syntax is not allowed and will cause "Missing parameter name" errors. This breaking change requires explicit naming of wildcard parameters.
Applied to files:
docs/router/api/file-based-routing.mddocs/router/framework/react/routing/file-naming-conventions.md
📚 Learning: 2025-10-14T18:59:33.990Z
Learnt from: FatahChan
Repo: TanStack/router PR: 5475
File: e2e/react-start/basic-prerendering/src/routes/redirect/$target/via-beforeLoad.tsx:8-0
Timestamp: 2025-10-14T18:59:33.990Z
Learning: In TanStack Router e2e test files, when a route parameter is validated at the route level (e.g., using zod in validateSearch or param validation), switch statements on that parameter do not require a default case, as the validation ensures only expected values will reach the switch.
Applied to files:
packages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.tspackages/router-generator/src/config.tspackages/router-generator/src/utils.ts
🧬 Code graph analysis (6)
packages/router-generator/src/generator.ts (1)
packages/router-generator/src/utils.ts (2)
createTokenRegex(429-483)multiSortBy(90-134)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (2)
packages/router-generator/src/utils.ts (1)
unwrapBracketWrappedSegment(489-491)packages/router-generator/src/types.ts (1)
FsRouteType(24-34)
packages/router-generator/src/filesystem/virtual/getRouteNodes.ts (1)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (1)
TokenRegexBundle(27-30)
packages/router-generator/tests/generator.test.ts (1)
packages/router-generator/src/config.ts (1)
getConfig(89-170)
packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsx (8)
packages/router-generator/tests/generator/regex-tokens-inline/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-inline/routes/dashboard.main-layout.tsx (1)
Route(3-10)packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/__root.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.home-page.tsx (1)
Route(3-5)packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.main-layout.tsx (1)
Route(3-10)packages/router-generator/tests/generator/regex-tokens-json/routes/index-page.tsx (1)
Route(3-5)
packages/router-generator/src/utils.ts (1)
packages/router-generator/src/config.ts (1)
TokenMatcher(20-20)
🪛 ast-grep (0.40.4)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
[warning] 262-262: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${stripSegment}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 264-264: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${stripSegment}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 302-302: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${updatedLastRouteSegment}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 308-308: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(/${indexTokenCandidate}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
packages/router-generator/src/utils.ts
[warning] 446-446: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${escapeRegExp(token)}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 447-447: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp([./]${escapeRegExp(token)}[.])
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 453-453: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^(?:${token.source})$, flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 454-454: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp([./](?:${token.source})[.], flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 461-461: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^(?:${token.regex})$, flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 462-462: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp([./](?:${token.regex})[.], flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
🔇 Additional comments (25)
packages/router-generator/tests/generator/regex-tokens-json/routeTree.snapshot.ts (1)
1-121: LGTM - Valid test fixture for JSON regex tokens feature.This snapshot correctly captures the expected generator output when using JSON-style regex tokens for
indexTokenandrouteToken. The route naming pattern (index-page,main-layout,home-page) demonstrates the regex token matching is working as intended, and the structure aligns with the standard TanStack Router generated file pattern.Based on learnings, test snapshot files in this directory are fixtures used to verify the generator's output and are intentionally preserved as-is.
packages/router-generator/tests/generator/regex-tokens-json/routes/dashboard.settings.tsx (1)
1-5: LGTM! Test fixture follows established pattern.This test route file correctly implements the file-based routing pattern for the regex-tokens-json test case. The route path '/dashboard/settings' appropriately maps from the filename 'dashboard.settings.tsx', and the implementation matches the structure of other test fixtures in this directory.
packages/router-generator/tests/generator/regex-tokens-json/tsr.config.json (1)
1-4: Test configuration is correct; patterns are automatically anchored by the generator.The configuration correctly uses the JSON format for regex tokens. The original concern about unanchored patterns is resolved by the generator's implementation: when processing regex tokens from the config object, the generator automatically wraps patterns with anchors based on context (line 462-463 in
packages/router-generator/src/utils.ts).For segment matching, patterns are wrapped as
^(?:${token.regex})$, ensuring exact matching. For filename matching, they're wrapped as[./](?:${token.regex})[.]. The test configuration is correct as-is—users provide clean patterns, and the generator handles the context-specific anchoring internally.docs/router/framework/react/routing/file-naming-conventions.md (1)
7-18: LGTM! Documentation accurately reflects the regex support feature.The table updates clearly communicate that both
indexTokenandrouteTokennow support strings and regex patterns, with appropriate references to the detailed API documentation.packages/router-generator/tests/generator/regex-tokens-inline/routes/index-page.tsx (1)
1-5: LGTM! Test route file follows standard patterns.The route file correctly uses
createFileRouteAPI and provides a simple component for testing regex token functionality.packages/router-generator/src/filesystem/physical/getRouteNodes.ts (2)
22-30: LGTM! Well-designed abstraction for token regex handling.The
TokenRegexBundleinterface provides a clean way to pass pre-compiled token regexes through the route discovery process, avoiding repeated regex compilation.
174-174: LGTM! Function signature correctly propagates token regexes.The updated signature ensures consistent token handling across route meta evaluation.
docs/router/api/file-based-routing.md (2)
104-131: Excellent documentation for regex pattern support!The section provides clear examples for both JSON config and inline code usage, with helpful notes about full-segment matching behavior. The examples are practical and easy to understand.
145-169: LGTM! Clear and comprehensive indexToken regex documentation.The documentation parallels the routeToken section effectively and includes important guidance on escaping regex tokens. This will help users understand the feature quickly.
packages/router-generator/src/utils.ts (3)
421-427: LGTM! Good defensive measure against stateful regex behavior.Removing the 'g' and 'y' flags prevents issues with
lastIndexstate when usingtest()orexec()methods.
485-491: LGTM! Clean helper functions for bracket escaping.These utilities provide a clear API for detecting and unwrapping bracket-escaped segments, supporting the new escaping mechanism.
429-483: LGTM! Comprehensive token regex creation with good error handling.The function handles all three token forms (string, RegExp, JSON object) with appropriate validation and error messages. String tokens are properly escaped via
escapeRegExp(), and the try-catch handles SyntaxErrors effectively.Note: User-provided regex patterns in config files could potentially cause ReDoS (Regular Expression Denial of Service) with complex patterns containing nested quantifiers or excessive backtracking—for example, patterns like
(a+)+bcan cause exponential backtracking. While this is a config-time concern (not runtime) and developers typically control config files, regex complexity is not validated here. If you want additional safety, libraries likesafe-regexorrecheckcan detect potentially problematic patterns, though this is optional since route generation happens at build time with developer-controlled configuration.packages/router-generator/tests/generator.test.ts (2)
44-64: LGTM: Config directory detection logic is well-structured.The setup now properly detects whether a
tsr.config.jsonexists in the test folder and passes the directory togetConfig, enabling tests to use file-based configurations. This aligns with the updatedgetConfigsignature that accepts an optionalconfigDirectoryparameter.
161-167: Good test case for inline RegExp tokens.The inline RegExp patterns for
indexToken(/[a-z]+-page/) androuteToken(/[a-z]+-layout/) effectively test the new regex token functionality, matching patterns like "index-page" or "protected-layout".packages/router-generator/src/config.ts (3)
7-20: Well-designed schema for flexible token matching.The
tokenMatcherSchemacorrectly supports three forms: plain strings,RegExpinstances, and JSON regex objects ({ regex, flags }). This enables both programmatic and JSON-based configuration. The type exports (TokenMatcherJson,TokenMatcher) provide good type safety for consumers.
102-111: Improved config merging preserves file-based defaults.The updated merge logic correctly spreads
fileConfigRawfirst, theninlineConfig, ensuring inline values override file values. Parsing the merged result once applies schema defaults only to unset fields, fixing the previous behavior where inline defaults could override file config values.
208-231: Consider normalizing mixed-type comparisons.The
areTokensEqualfunction returnsfalsefor mixed types (e.g., string vs RegExp with the same pattern). This is intentional but worth documenting. A string"index"andRegExp(/index/)would not be considered equal even though they match the same text.This behavior is reasonable since the types have different semantics (exact match vs pattern match), but if cross-type equivalence is ever needed, this would need updating.
packages/router-generator/src/filesystem/virtual/getRouteNodes.ts (2)
42-54: Token regex propagation is correctly implemented.The
tokenRegexesparameter is properly threaded through the virtual route node generation, ensuring consistent token matching behavior across both virtual and physical route discovery paths.
159-162: Good fix for physical directory accumulation.The change correctly accumulates both the direct physical directory (
resolve(fullDir, node.directory)) and any nested physical directories returned fromgetRouteNodesPhysical. This ensures the generator tracks all mounted physical directories for file relevance checks.packages/router-generator/src/generator.ts (4)
195-214: Excellent documentation for the dual regex strategy.The comment clearly explains why two regex types are needed:
- Filename regexes: Match tokens within full file paths (bounded by path separators/dots)
- Segment regexes: Match tokens against isolated route segments (exact match)
This distinction prevents false positives and ensures correct behavior in different contexts.
229-241: LGTM: Pre-compiled regexes in constructor.Creating all token regexes once in the constructor is efficient and ensures consistent regex instances are reused throughout route processing.
584-597: Smart optimization for config override scenario.The logic correctly reuses the pre-compiled
indexTokenSegmentRegexwhen the config hasn't been overridden, and only creates a new regex when a differentindexTokenis provided viaopts.config. This handles plugin scenarios that may override config while maintaining efficiency for the common case.
393-401: Sorting logic correctly uses filename-level regexes.The multiSortBy accessors now use
indexTokenFilenameRegexandrouteTokenFilenameRegexto detect tokens within file paths. This is the correct choice for path-based sorting since file paths contain dots and separators.packages/router-generator/tests/generator/virtual-physical-layout-and-index/routeTree.snapshot.ts (1)
1-104: Snapshot file - no review needed.Based on learnings, test snapshot files in the router-generator tests directory are fixtures used to verify the generator's output and should be preserved as-is.
packages/router-generator/tests/generator/regex-tokens-inline/routeTree.snapshot.ts (1)
1-121: New snapshot for regex-tokens-inline test.This snapshot file correctly demonstrates the generated route tree when using inline RegExp tokens. The structure shows proper handling of routes named with the
-pageand-layoutpatterns (e.g.,index-page,main-layout).Based on learnings, test snapshot files are fixtures and should be preserved as-is.
| it('physical() mount returns absolute physicalDirectories', async () => { | ||
| const folderName = 'virtual-physical-no-prefix' | ||
| const dir = makeFolderDir(folderName) | ||
| const config = await setupConfig(folderName) | ||
|
|
||
| const { physicalDirectories } = await virtualGetRouteNodes(config, dir, { | ||
| indexTokenSegmentRegex: /^(?:index)$/, | ||
| routeTokenSegmentRegex: /^(?:route)$/, | ||
| }) | ||
|
|
||
| expect(physicalDirectories.length).toBeGreaterThan(0) | ||
| physicalDirectories.forEach((physicalDir) => { | ||
| expect(path.isAbsolute(physicalDir)).toBe(true) | ||
| }) | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find createTokenRegex definition
rg -n "createTokenRegex" --type ts --type tsx -A5 packages/router-generator/src/Repository: TanStack/router
Length of output: 86
🏁 Script executed:
#!/bin/bash
# Check the test file for context
cat -n packages/router-generator/tests/generator.test.ts | sed -n '301,315p'Repository: TanStack/router
Length of output: 734
🏁 Script executed:
#!/bin/bash
# Also search for where indexTokenSegmentRegex and routeTokenSegmentRegex are used elsewhere
rg -n "indexTokenSegmentRegex|routeTokenSegmentRegex" --type ts --type tsx packages/router-generator/ | head -20Repository: TanStack/router
Length of output: 86
🏁 Script executed:
#!/bin/bash
# Search for createTokenRegex without file type restrictions
rg -n "createTokenRegex" packages/router-generator/src/ -A5Repository: TanStack/router
Length of output: 3507
🏁 Script executed:
#!/bin/bash
# List TypeScript/JS files in utils directory
fd . packages/router-generator/src/ -e ts -e js | head -20Repository: TanStack/router
Length of output: 860
🏁 Script executed:
#!/bin/bash
# Check what virtualGetRouteNodes expects as parameters
rg -n "virtualGetRouteNodes" packages/router-generator/ -B2 -A8 | head -50Repository: TanStack/router
Length of output: 3958
🏁 Script executed:
#!/bin/bash
# Get the full createTokenRegex implementation
cat -n packages/router-generator/src/utils.ts | sed -n '429,480p'Repository: TanStack/router
Length of output: 2174
🏁 Script executed:
#!/bin/bash
# Also check what the default config tokens are
rg -n "indexToken|routeToken" packages/router-generator/src/config.ts -B2 -A2 | head -40Repository: TanStack/router
Length of output: 671
🏁 Script executed:
#!/bin/bash
# Check if there's documentation or setup for this test
cat -n packages/router-generator/tests/generator.test.ts | sed -n '285,320p'Repository: TanStack/router
Length of output: 1416
🏁 Script executed:
#!/bin/bash
# Look for setupConfig function to understand test setup
rg -n "function setupConfig|const setupConfig" packages/router-generator/tests/ -A10Repository: TanStack/router
Length of output: 2108
🏁 Script executed:
#!/bin/bash
# Check if there are other tests using these regex patterns
rg -n "indexTokenSegmentRegex|routeTokenSegmentRegex" packages/router-generator/tests/ -B2 -A2Repository: TanStack/router
Length of output: 559
🏁 Script executed:
#!/bin/bash
# Check the virtualGetRouteNodes function signature and what it expects
cat -n packages/router-generator/src/filesystem/virtual/getRouteNodes.ts | head -50Repository: TanStack/router
Length of output: 1685
🏁 Script executed:
#!/bin/bash
# Also check if there's test documentation or comments explaining this test
cat -n packages/router-generator/tests/generator.test.ts | sed -n '295,310p'Repository: TanStack/router
Length of output: 623
🏁 Script executed:
#!/bin/bash
# Get more of the virtualGetRouteNodes signature and type definition
cat -n packages/router-generator/src/filesystem/virtual/getRouteNodes.ts | sed -n '42,70p'Repository: TanStack/router
Length of output: 1096
🏁 Script executed:
#!/bin/bash
# Look for TokenRegexBundle type definition
rg -n "type TokenRegexBundle" packages/router-generator/src/Repository: TanStack/router
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Check the physical getRouteNodes to understand the expected parameter structure
cat -n packages/router-generator/src/filesystem/physical/getRouteNodes.ts | head -100Repository: TanStack/router
Length of output: 3801
🏁 Script executed:
#!/bin/bash
# Check what config setupConfig produces for indexToken and routeToken
cat -n packages/router-generator/tests/generator.test.ts | sed -n '44,65p'Repository: TanStack/router
Length of output: 779
🏁 Script executed:
#!/bin/bash
# Check if the 'virtual-physical-no-prefix' test folder has a tsr.config.json
find packages/router-generator/tests/generator/virtual-physical-no-prefix -name "*.json" -o -name "*.ts" | head -20Repository: TanStack/router
Length of output: 313
🏁 Script executed:
#!/bin/bash
# Check the config for this test folder
cat packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.jsonRepository: TanStack/router
Length of output: 179
🏁 Script executed:
#!/bin/bash
# Also verify what getConfig does with defaults
cat -n packages/router-generator/src/config.ts | sed -n '1,80p'Repository: TanStack/router
Length of output: 3420
🏁 Script executed:
#!/bin/bash
# Let's verify the exact regex output createTokenRegex produces by checking escapeRegExp
rg -n "function escapeRegExp|const escapeRegExp" packages/router-generator/src/utils.ts -A5Repository: TanStack/router
Length of output: 271
Update hardcoded regex patterns to match createTokenRegex output for default string tokens.
The test passes hardcoded regex patterns with non-capturing groups (/^(?:index)$/ and /^(?:route)$/) to virtualGetRouteNodes. However, createTokenRegex with default string tokens "index" and "route" produces /^index$/ and /^route$/ without the non-capturing groups. Non-capturing groups are only added for RegExp token types, not string tokens. While these patterns are functionally equivalent, align them with the actual output of createTokenRegex for consistency.
🤖 Prompt for AI Agents
In @packages/router-generator/tests/generator.test.ts around lines 301 - 315,
Update the test to use regexes that match createTokenRegex's output for default
string tokens by replacing the non-capturing-group patterns passed to
virtualGetRouteNodes with plain anchors — use /^index$/ and /^route$/ (or
generate them via createTokenRegex('index') and createTokenRegex('route')) so
the test aligns with how createTokenRegex produces /^index$/ and /^route$/ for
string tokens when invoking virtualGetRouteNodes.
SeanCassiere
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Only question is whether we'll need to support that Regex.index=0 trick at some point 🤔. We can always fix forward is needed.
|
shouldnt be stateful, see #6354 (comment) |
closes #6350
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.