@@ -15,7 +15,7 @@ import type {
15
15
VirtualRootRoute ,
16
16
VirtualRouteSubtreeConfig ,
17
17
} from '@tanstack/virtual-file-routes'
18
- import type { GetRouteNodesResult , RouteNode } from '../../types'
18
+ import type { FsRouteType , GetRouteNodesResult , RouteNode } from '../../types'
19
19
import type { Config } from '../../config'
20
20
21
21
const disallowedRouteGroupConfiguration = / \( ( [ ^ ) ] + ) \) .( t s | j s | t s x | j s x ) /
@@ -119,33 +119,29 @@ export async function getRouteNodes(
119
119
throw new Error ( errorMessage )
120
120
}
121
121
122
- const variableName = routePathToVariable ( routePath )
122
+ const meta = getRouteMeta ( routePath , config )
123
+ const variableName = meta . variableName
124
+ let routeType : FsRouteType = meta . fsRouteType
123
125
124
- const isLazy = routePath . endsWith ( '/lazy' )
125
-
126
- if ( isLazy ) {
126
+ if ( routeType === 'lazy' ) {
127
127
routePath = routePath . replace ( / \/ l a z y $ / , '' )
128
128
}
129
129
130
- const isRoute = routePath . endsWith ( `/${ config . routeToken } ` )
131
- const isComponent = routePath . endsWith ( '/component' )
132
- const isErrorComponent = routePath . endsWith ( '/errorComponent' )
133
- const isPendingComponent = routePath . endsWith ( '/pendingComponent' )
134
- const isLoader = routePath . endsWith ( '/loader' )
135
- const isAPIRoute = routePath . startsWith (
136
- `${ removeTrailingSlash ( config . apiBase ) } /` ,
137
- )
138
- const isLayout = determineRouteIsLayout ( routePath , config )
130
+ // this check needs to happen after the lazy route has been cleaned up
131
+ // since the routePath is used to determine if a route is pathless
132
+ if ( isValidPathlessLayoutRoute ( routePath , routeType , config ) ) {
133
+ routeType = 'pathless_layout'
134
+ }
139
135
140
136
; (
141
137
[
142
- [ isComponent , 'component' ] ,
143
- [ isErrorComponent , 'errorComponent' ] ,
144
- [ isPendingComponent , 'pendingComponent' ] ,
145
- [ isLoader , 'loader' ] ,
146
- ] as const
147
- ) . forEach ( ( [ isType , type ] ) => {
148
- if ( isType ) {
138
+ [ 'component' , 'component' ] ,
139
+ [ 'errorComponent' , 'errorComponent' ] ,
140
+ [ 'pendingComponent' , 'pendingComponent' ] ,
141
+ [ 'loader' , 'loader' ] ,
142
+ ] satisfies Array < [ FsRouteType , string ] >
143
+ ) . forEach ( ( [ matcher , type ] ) => {
144
+ if ( routeType === matcher ) {
149
145
logger . warn (
150
146
`WARNING: The \`.${ type } .tsx\` suffix used for the ${ filePath } file is deprecated. Use the new \`.lazy.tsx\` suffix instead.` ,
151
147
)
@@ -171,14 +167,7 @@ export async function getRouteNodes(
171
167
fullPath,
172
168
routePath,
173
169
variableName,
174
- isRoute,
175
- isComponent,
176
- isErrorComponent,
177
- isPendingComponent,
178
- isLoader,
179
- isLazy,
180
- isLayout,
181
- isAPIRoute,
170
+ _fsRouteType : routeType ,
182
171
} )
183
172
}
184
173
} ) ,
@@ -190,16 +179,84 @@ export async function getRouteNodes(
190
179
await recurse ( './' )
191
180
192
181
const rootRouteNode = routeNodes . find ( ( d ) => d . routePath === `/${ rootPathId } ` )
182
+ if ( rootRouteNode ) {
183
+ rootRouteNode . _fsRouteType = '__root'
184
+ }
185
+
193
186
return { rootRouteNode, routeNodes }
194
187
}
195
188
196
189
/**
197
- * Used to determine if a route is a layout route
190
+ * Determines the metadata for a given route path based on the provided configuration.
191
+ *
192
+ * @param routePath - The determined initial routePath.
193
+ * @param config - The user configuration object.
194
+ * @returns An object containing the type of the route and the variable name derived from the route path.
195
+ */
196
+ export function getRouteMeta (
197
+ routePath : string ,
198
+ config : Config ,
199
+ ) : {
200
+ // `__root` is can be more easily determined by filtering down to routePath === /${rootPathId}
201
+ // `pathless` is needs to determined after `lazy` has been cleaned up from the routePath
202
+ fsRouteType : Extract <
203
+ FsRouteType ,
204
+ | 'static'
205
+ | 'layout'
206
+ | 'api'
207
+ | 'lazy'
208
+ | 'loader'
209
+ | 'component'
210
+ | 'pendingComponent'
211
+ | 'errorComponent'
212
+ >
213
+ variableName : string
214
+ } {
215
+ let fsRouteType : FsRouteType = 'static'
216
+
217
+ if ( routePath . endsWith ( `/${ config . routeToken } ` ) ) {
218
+ // layout routes, i.e `/foo/route.tsx` or `/foo/_layout/route.tsx`
219
+ fsRouteType = 'layout'
220
+ } else if ( routePath . startsWith ( `${ removeTrailingSlash ( config . apiBase ) } /` ) ) {
221
+ // api routes, i.e. `/api/foo.ts`
222
+ fsRouteType = 'api'
223
+ } else if ( routePath . endsWith ( '/lazy' ) ) {
224
+ // lazy routes, i.e. `/foo.lazy.tsx`
225
+ fsRouteType = 'lazy'
226
+ } else if ( routePath . endsWith ( '/loader' ) ) {
227
+ // loader routes, i.e. `/foo.loader.tsx`
228
+ fsRouteType = 'loader'
229
+ } else if ( routePath . endsWith ( '/component' ) ) {
230
+ // component routes, i.e. `/foo.component.tsx`
231
+ fsRouteType = 'component'
232
+ } else if ( routePath . endsWith ( '/pendingComponent' ) ) {
233
+ // pending component routes, i.e. `/foo.pendingComponent.tsx`
234
+ fsRouteType = 'pendingComponent'
235
+ } else if ( routePath . endsWith ( '/errorComponent' ) ) {
236
+ // error component routes, i.e. `/foo.errorComponent.tsx`
237
+ fsRouteType = 'errorComponent'
238
+ }
239
+
240
+ const variableName = routePathToVariable ( routePath )
241
+
242
+ return { fsRouteType, variableName }
243
+ }
244
+
245
+ /**
246
+ * Used to validate if a route is a pathless layout route
198
247
* @param normalizedRoutePath Normalized route path, i.e `/foo/_layout/route.tsx` and `/foo._layout.route.tsx` to `/foo/_layout/route`
199
248
* @param config The `router-generator` configuration object
200
- * @returns Boolean indicating if the route is a layout route
249
+ * @returns Boolean indicating if the route is a pathless layout route
201
250
*/
202
- function determineRouteIsLayout ( normalizedRoutePath : string , config : Config ) {
251
+ function isValidPathlessLayoutRoute (
252
+ normalizedRoutePath : string ,
253
+ routeType : FsRouteType ,
254
+ config : Config ,
255
+ ) : boolean {
256
+ if ( routeType === 'lazy' ) {
257
+ return false
258
+ }
259
+
203
260
const segments = normalizedRoutePath . split ( '/' ) . filter ( Boolean )
204
261
205
262
if ( segments . length === 0 ) {
0 commit comments