@tanstack/router-generator 1.167.1 → 1.167.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +4 -1
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/filesystem/virtual/getRouteNodes.cjs +15 -5
- package/dist/cjs/filesystem/virtual/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/generator.cjs +27 -7
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/types.d.cts +6 -0
- package/dist/cjs/utils.cjs +120 -38
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +8 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js +5 -2
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/dist/esm/filesystem/virtual/getRouteNodes.js +16 -6
- package/dist/esm/filesystem/virtual/getRouteNodes.js.map +1 -1
- package/dist/esm/generator.js +28 -8
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/types.d.ts +6 -0
- package/dist/esm/utils.d.ts +8 -1
- package/dist/esm/utils.js +115 -37
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/filesystem/physical/getRouteNodes.ts +13 -0
- package/src/filesystem/virtual/getRouteNodes.ts +32 -6
- package/src/generator.ts +67 -19
- package/src/types.ts +7 -0
- package/src/utils.ts +225 -23
package/src/generator.ts
CHANGED
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
buildRouteTreeConfig,
|
|
18
18
|
checkFileExists,
|
|
19
19
|
checkRouteFullPathUniqueness,
|
|
20
|
+
countRoutePathSegments,
|
|
21
|
+
countSlashSeparatedParts,
|
|
20
22
|
createRouteNodesByFullPath,
|
|
21
23
|
createRouteNodesById,
|
|
22
24
|
createRouteNodesByTo,
|
|
@@ -33,9 +35,8 @@ import {
|
|
|
33
35
|
removeExt,
|
|
34
36
|
removeGroups,
|
|
35
37
|
removeLastSegmentFromPath,
|
|
36
|
-
|
|
38
|
+
removeLayoutSegmentsAndUnderscoresWithEscape,
|
|
37
39
|
removeTrailingSlash,
|
|
38
|
-
removeUnderscoresWithEscape,
|
|
39
40
|
replaceBackslash,
|
|
40
41
|
trimPathLeft,
|
|
41
42
|
} from './utils'
|
|
@@ -51,6 +52,7 @@ import type {
|
|
|
51
52
|
HandleNodeAccumulator,
|
|
52
53
|
ImportDeclaration,
|
|
53
54
|
RouteNode,
|
|
55
|
+
RoutePathSegmentMetadata,
|
|
54
56
|
} from './types'
|
|
55
57
|
import type { Config } from './config'
|
|
56
58
|
import type { Logger } from './logger'
|
|
@@ -70,6 +72,32 @@ interface fs {
|
|
|
70
72
|
chown: (filePath: string, uid: number, gid: number) => Promise<void>
|
|
71
73
|
}
|
|
72
74
|
|
|
75
|
+
function getRoutePathSegmentMetadataForPath(
|
|
76
|
+
node: RouteNode,
|
|
77
|
+
routePath: string,
|
|
78
|
+
parentRoutePath?: string,
|
|
79
|
+
): Array<RoutePathSegmentMetadata | undefined> | undefined {
|
|
80
|
+
if (!node._routePathSegmentMetadata) return undefined
|
|
81
|
+
|
|
82
|
+
const segments = routePath.split('/')
|
|
83
|
+
const result = new Array<RoutePathSegmentMetadata | undefined>(
|
|
84
|
+
segments.length,
|
|
85
|
+
)
|
|
86
|
+
const parentSegmentCount = countRoutePathSegments(parentRoutePath)
|
|
87
|
+
let hasMetadata = false
|
|
88
|
+
let segmentCount = 0
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < segments.length; i++) {
|
|
91
|
+
if (!segments[i]) continue
|
|
92
|
+
const sourceIndex = parentSegmentCount + segmentCount + 1
|
|
93
|
+
result[i] = node._routePathSegmentMetadata[sourceIndex]
|
|
94
|
+
hasMetadata ||= !!result[i]
|
|
95
|
+
segmentCount++
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return hasMetadata ? result : undefined
|
|
99
|
+
}
|
|
100
|
+
|
|
73
101
|
const DefaultFileSystem: fs = {
|
|
74
102
|
stat: async (filePath) => {
|
|
75
103
|
const res = await fsp.stat(filePath, { bigint: true })
|
|
@@ -392,7 +420,10 @@ export class Generator {
|
|
|
392
420
|
|
|
393
421
|
const preRouteNodes = multiSortBy(beforeRouteNodes, [
|
|
394
422
|
(d) => (d.routePath === '/' ? -1 : 1),
|
|
395
|
-
(d) =>
|
|
423
|
+
(d) =>
|
|
424
|
+
d.routePath === undefined
|
|
425
|
+
? undefined
|
|
426
|
+
: countSlashSeparatedParts(d.routePath),
|
|
396
427
|
(d) => (d.filePath.match(this.indexTokenFilenameRegex) ? 1 : -1),
|
|
397
428
|
(d) => (d.filePath.match(Generator.componentPieceRegex) ? 1 : -1),
|
|
398
429
|
(d) => (d.filePath.match(this.routeTokenFilenameRegex) ? -1 : 1),
|
|
@@ -587,7 +618,10 @@ export class Generator {
|
|
|
587
618
|
|
|
588
619
|
const sortedRouteNodes = multiSortBy(acc.routeNodes, [
|
|
589
620
|
(d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),
|
|
590
|
-
(d) =>
|
|
621
|
+
(d) =>
|
|
622
|
+
d.routePath === undefined
|
|
623
|
+
? undefined
|
|
624
|
+
: countSlashSeparatedParts(d.routePath),
|
|
591
625
|
(d) => {
|
|
592
626
|
const segments = d.routePath?.split('/').filter(Boolean) ?? []
|
|
593
627
|
const last = segments[segments.length - 1] ?? ''
|
|
@@ -1430,29 +1464,39 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
1430
1464
|
node.path = determineNodePath(node)
|
|
1431
1465
|
|
|
1432
1466
|
const trimmedPath = trimPathLeft(node.path ?? '')
|
|
1433
|
-
const
|
|
1434
|
-
node.originalRoutePath?.
|
|
1435
|
-
node.parent
|
|
1436
|
-
|
|
1437
|
-
|
|
1467
|
+
const originalPath =
|
|
1468
|
+
node.originalRoutePath && node.parent?.originalRoutePath
|
|
1469
|
+
? node.originalRoutePath.replace(node.parent.originalRoutePath, '') ||
|
|
1470
|
+
'/'
|
|
1471
|
+
: node.originalRoutePath
|
|
1472
|
+
const routePathSegmentMetadata = getRoutePathSegmentMetadataForPath(
|
|
1473
|
+
node,
|
|
1474
|
+
node.path ?? '/',
|
|
1475
|
+
node.parent?.routePath,
|
|
1438
1476
|
)
|
|
1477
|
+
const trimmedOriginalPath = trimPathLeft(originalPath ?? '')
|
|
1439
1478
|
|
|
1440
1479
|
const split = trimmedPath.split('/')
|
|
1480
|
+
const pathSplit = (node.path ?? '').split('/')
|
|
1441
1481
|
const originalSplit = trimmedOriginalPath.split('/')
|
|
1442
1482
|
const lastRouteSegment = split[split.length - 1] ?? trimmedPath
|
|
1443
1483
|
const lastOriginalSegment =
|
|
1444
1484
|
originalSplit[originalSplit.length - 1] ?? trimmedOriginalPath
|
|
1485
|
+
const lastRouteSegmentMetadata =
|
|
1486
|
+
routePathSegmentMetadata?.[pathSplit.length - 1]
|
|
1445
1487
|
|
|
1446
1488
|
// A segment is non-path if it starts with underscore AND the underscore is not escaped
|
|
1447
1489
|
node.isNonPath =
|
|
1448
|
-
|
|
1490
|
+
(!lastRouteSegmentMetadata?.literalLeadingUnderscore &&
|
|
1491
|
+
isSegmentPathless(lastRouteSegment, lastOriginalSegment)) ||
|
|
1449
1492
|
split.every((part) => this.routeGroupPatternRegex.test(part))
|
|
1450
1493
|
|
|
1451
|
-
// Use
|
|
1494
|
+
// Use a single pass so layout removal does not desync escaped underscore checks.
|
|
1452
1495
|
node.cleanedPath = removeGroups(
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1496
|
+
removeLayoutSegmentsAndUnderscoresWithEscape(
|
|
1497
|
+
node.path,
|
|
1498
|
+
originalPath,
|
|
1499
|
+
routePathSegmentMetadata,
|
|
1456
1500
|
),
|
|
1457
1501
|
)
|
|
1458
1502
|
|
|
@@ -1530,13 +1574,17 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
1530
1574
|
candidate.originalRoutePath ?? '',
|
|
1531
1575
|
'',
|
|
1532
1576
|
) || '/'
|
|
1577
|
+
const routePathSegmentMetadataRelativeToParent =
|
|
1578
|
+
getRoutePathSegmentMetadataForPath(
|
|
1579
|
+
node,
|
|
1580
|
+
pathRelativeToParent,
|
|
1581
|
+
candidate.routePath,
|
|
1582
|
+
)
|
|
1533
1583
|
node.cleanedPath = removeGroups(
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
pathRelativeToParent,
|
|
1537
|
-
originalPathRelativeToParent,
|
|
1538
|
-
),
|
|
1584
|
+
removeLayoutSegmentsAndUnderscoresWithEscape(
|
|
1585
|
+
pathRelativeToParent,
|
|
1539
1586
|
originalPathRelativeToParent,
|
|
1587
|
+
routePathSegmentMetadataRelativeToParent,
|
|
1540
1588
|
),
|
|
1541
1589
|
)
|
|
1542
1590
|
break
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export type RoutePathSegmentMetadata = {
|
|
2
|
+
literalLeadingUnderscore?: boolean
|
|
3
|
+
literalTrailingUnderscore?: boolean
|
|
4
|
+
}
|
|
5
|
+
|
|
1
6
|
export type RouteNode = {
|
|
2
7
|
filePath: string
|
|
3
8
|
fullPath: string
|
|
@@ -20,6 +25,8 @@ export type RouteNode = {
|
|
|
20
25
|
* (e.g., when the parent is a virtual file-less route that gets filtered out).
|
|
21
26
|
*/
|
|
22
27
|
_virtualParentRoutePath?: string
|
|
28
|
+
/** Internal routePath segment metadata for escaped or explicit literal syntax. */
|
|
29
|
+
_routePathSegmentMetadata?: Array<RoutePathSegmentMetadata | undefined>
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
export interface GetRouteNodesResult {
|
package/src/utils.ts
CHANGED
|
@@ -4,7 +4,11 @@ import path from 'node:path'
|
|
|
4
4
|
import * as prettier from 'prettier'
|
|
5
5
|
import { rootPathId } from './filesystem/physical/rootPathId'
|
|
6
6
|
import type { Config, TokenMatcher } from './config'
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
ImportDeclaration,
|
|
9
|
+
RouteNode,
|
|
10
|
+
RoutePathSegmentMetadata,
|
|
11
|
+
} from './types'
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* Prefix map for O(1) parent route lookups.
|
|
@@ -244,6 +248,169 @@ export function hasEscapedTrailingUnderscore(originalSegment: string): boolean {
|
|
|
244
248
|
)
|
|
245
249
|
}
|
|
246
250
|
|
|
251
|
+
export function countRoutePathSegments(routePath?: string): number {
|
|
252
|
+
const path = routePath ?? ''
|
|
253
|
+
let count = 0
|
|
254
|
+
let inSegment = false
|
|
255
|
+
|
|
256
|
+
for (let i = 0; i < path.length; i++) {
|
|
257
|
+
if (path[i] === '/') {
|
|
258
|
+
inSegment = false
|
|
259
|
+
continue
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!inSegment) {
|
|
263
|
+
count++
|
|
264
|
+
inSegment = true
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return count
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function countSlashSeparatedParts(path: string): number {
|
|
272
|
+
let count = 1
|
|
273
|
+
|
|
274
|
+
for (let i = 0; i < path.length; i++) {
|
|
275
|
+
if (path[i] === '/') count++
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return count
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export function hasRoutePathSegmentMetadata(
|
|
282
|
+
metadata: RoutePathSegmentMetadata | undefined,
|
|
283
|
+
): metadata is RoutePathSegmentMetadata {
|
|
284
|
+
return !!(
|
|
285
|
+
metadata?.literalLeadingUnderscore || metadata?.literalTrailingUnderscore
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function mergeRoutePathSegmentMetadata(
|
|
290
|
+
current: RoutePathSegmentMetadata | undefined,
|
|
291
|
+
incoming: RoutePathSegmentMetadata | undefined,
|
|
292
|
+
): RoutePathSegmentMetadata | undefined {
|
|
293
|
+
const hasCurrent = hasRoutePathSegmentMetadata(current)
|
|
294
|
+
const hasIncoming = hasRoutePathSegmentMetadata(incoming)
|
|
295
|
+
|
|
296
|
+
if (!hasCurrent) return hasIncoming ? incoming : undefined
|
|
297
|
+
if (!hasIncoming) return current
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
literalLeadingUnderscore:
|
|
301
|
+
current.literalLeadingUnderscore || incoming.literalLeadingUnderscore,
|
|
302
|
+
literalTrailingUnderscore:
|
|
303
|
+
current.literalTrailingUnderscore || incoming.literalTrailingUnderscore,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export function createRoutePathSegmentMetadata(
|
|
308
|
+
routePath: string = '/',
|
|
309
|
+
originalPath?: string,
|
|
310
|
+
): Array<RoutePathSegmentMetadata | undefined> | undefined {
|
|
311
|
+
if (!originalPath) return undefined
|
|
312
|
+
|
|
313
|
+
const routeSegments = routePath.split('/')
|
|
314
|
+
const originalSegments = originalPath.split('/')
|
|
315
|
+
const metadata = new Array<RoutePathSegmentMetadata | undefined>(
|
|
316
|
+
routeSegments.length,
|
|
317
|
+
)
|
|
318
|
+
let hasMetadata = false
|
|
319
|
+
|
|
320
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
321
|
+
const segment = routeSegments[i]!
|
|
322
|
+
const originalSegment = originalSegments[i] || ''
|
|
323
|
+
const literalLeadingUnderscore =
|
|
324
|
+
segment.startsWith('_') && hasEscapedLeadingUnderscore(originalSegment)
|
|
325
|
+
const literalTrailingUnderscore =
|
|
326
|
+
segment.endsWith('_') && hasEscapedTrailingUnderscore(originalSegment)
|
|
327
|
+
|
|
328
|
+
if (!literalLeadingUnderscore && !literalTrailingUnderscore) continue
|
|
329
|
+
|
|
330
|
+
hasMetadata = true
|
|
331
|
+
metadata[i] = {
|
|
332
|
+
literalLeadingUnderscore: literalLeadingUnderscore || undefined,
|
|
333
|
+
literalTrailingUnderscore: literalTrailingUnderscore || undefined,
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return hasMetadata ? metadata : undefined
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function createLiteralRoutePathSegmentMetadata(
|
|
341
|
+
routePath: string,
|
|
342
|
+
parent?: RouteNode,
|
|
343
|
+
literalNewSegments = false,
|
|
344
|
+
): Array<RoutePathSegmentMetadata | undefined> | undefined {
|
|
345
|
+
const routeSegments = routePath.split('/')
|
|
346
|
+
const metadata = new Array<RoutePathSegmentMetadata | undefined>(
|
|
347
|
+
routeSegments.length,
|
|
348
|
+
)
|
|
349
|
+
const parentDepth = countRoutePathSegments(parent?.routePath)
|
|
350
|
+
let hasMetadata = false
|
|
351
|
+
let depth = 0
|
|
352
|
+
|
|
353
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
354
|
+
const segment = routeSegments[i]
|
|
355
|
+
metadata[i] = parent?._routePathSegmentMetadata?.[i]
|
|
356
|
+
hasMetadata ||= hasRoutePathSegmentMetadata(metadata[i])
|
|
357
|
+
|
|
358
|
+
if (!segment) continue
|
|
359
|
+
|
|
360
|
+
if (literalNewSegments && depth >= parentDepth) {
|
|
361
|
+
const literalLeadingUnderscore = segment.startsWith('_')
|
|
362
|
+
const literalTrailingUnderscore = segment.endsWith('_')
|
|
363
|
+
|
|
364
|
+
if (literalLeadingUnderscore || literalTrailingUnderscore) {
|
|
365
|
+
metadata[i] = mergeRoutePathSegmentMetadata(metadata[i], {
|
|
366
|
+
literalLeadingUnderscore: literalLeadingUnderscore || undefined,
|
|
367
|
+
literalTrailingUnderscore: literalTrailingUnderscore || undefined,
|
|
368
|
+
})
|
|
369
|
+
hasMetadata = true
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
depth++
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return hasMetadata ? metadata : undefined
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export function joinRoutePathSegmentMetadata(
|
|
380
|
+
routePath: string,
|
|
381
|
+
prefixPath: string,
|
|
382
|
+
prefixMetadata: Array<RoutePathSegmentMetadata | undefined> | undefined,
|
|
383
|
+
childMetadata: Array<RoutePathSegmentMetadata | undefined> | undefined,
|
|
384
|
+
): Array<RoutePathSegmentMetadata | undefined> | undefined {
|
|
385
|
+
const metadata = new Array<RoutePathSegmentMetadata | undefined>(
|
|
386
|
+
countSlashSeparatedParts(routePath),
|
|
387
|
+
)
|
|
388
|
+
let hasMetadata = false
|
|
389
|
+
|
|
390
|
+
if (prefixMetadata) {
|
|
391
|
+
for (let i = 0; i < prefixMetadata.length && i < metadata.length; i++) {
|
|
392
|
+
metadata[i] = prefixMetadata[i]
|
|
393
|
+
hasMetadata ||= hasRoutePathSegmentMetadata(metadata[i])
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const offset = countRoutePathSegments(prefixPath)
|
|
398
|
+
if (childMetadata) {
|
|
399
|
+
for (let i = 1; i < childMetadata.length; i++) {
|
|
400
|
+
const targetIndex = offset + i
|
|
401
|
+
if (targetIndex >= metadata.length) break
|
|
402
|
+
|
|
403
|
+
metadata[targetIndex] = mergeRoutePathSegmentMetadata(
|
|
404
|
+
metadata[targetIndex],
|
|
405
|
+
childMetadata[i],
|
|
406
|
+
)
|
|
407
|
+
hasMetadata ||= hasRoutePathSegmentMetadata(metadata[targetIndex])
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return hasMetadata ? metadata : undefined
|
|
412
|
+
}
|
|
413
|
+
|
|
247
414
|
const backslashRegex = /\\/g
|
|
248
415
|
|
|
249
416
|
export function replaceBackslash(s: string) {
|
|
@@ -314,6 +481,23 @@ export function removeUnderscores(s?: string) {
|
|
|
314
481
|
.replace(underscoreSlashRegex, '/')
|
|
315
482
|
}
|
|
316
483
|
|
|
484
|
+
function removeUnderscoresFromSegment(
|
|
485
|
+
segment: string,
|
|
486
|
+
metadata?: RoutePathSegmentMetadata,
|
|
487
|
+
): string {
|
|
488
|
+
let result = segment
|
|
489
|
+
|
|
490
|
+
if (result.startsWith('_') && !metadata?.literalLeadingUnderscore) {
|
|
491
|
+
result = result.slice(1)
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (result.endsWith('_') && !metadata?.literalTrailingUnderscore) {
|
|
495
|
+
result = result.slice(0, -1)
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return result
|
|
499
|
+
}
|
|
500
|
+
|
|
317
501
|
/**
|
|
318
502
|
* Removes underscores from a path, but preserves underscores that were escaped
|
|
319
503
|
* in the original path (indicated by [_] syntax).
|
|
@@ -330,30 +514,50 @@ export function removeUnderscoresWithEscape(
|
|
|
330
514
|
if (!originalPath) return removeUnderscores(routePath) ?? ''
|
|
331
515
|
|
|
332
516
|
const routeSegments = routePath.split('/')
|
|
333
|
-
const
|
|
517
|
+
const metadata = createRoutePathSegmentMetadata(routePath, originalPath)
|
|
518
|
+
const newSegments = new Array<string>(routeSegments.length)
|
|
334
519
|
|
|
335
|
-
|
|
336
|
-
|
|
520
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
521
|
+
newSegments[i] = removeUnderscoresFromSegment(
|
|
522
|
+
routeSegments[i]!,
|
|
523
|
+
metadata?.[i],
|
|
524
|
+
)
|
|
525
|
+
}
|
|
337
526
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
// Check if trailing underscore is escaped
|
|
341
|
-
const trailingEscaped = hasEscapedTrailingUnderscore(originalSegment)
|
|
527
|
+
return newSegments.join('/')
|
|
528
|
+
}
|
|
342
529
|
|
|
343
|
-
|
|
530
|
+
export function removeLayoutSegmentsAndUnderscoresWithEscape(
|
|
531
|
+
routePath: string = '/',
|
|
532
|
+
originalPath?: string,
|
|
533
|
+
routePathSegmentMetadata?: Array<RoutePathSegmentMetadata | undefined>,
|
|
534
|
+
): string {
|
|
535
|
+
if (!originalPath) {
|
|
536
|
+
return removeUnderscores(removeLayoutSegments(routePath)) ?? ''
|
|
537
|
+
}
|
|
344
538
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
539
|
+
const metadata =
|
|
540
|
+
routePathSegmentMetadata ??
|
|
541
|
+
createRoutePathSegmentMetadata(routePath, originalPath)
|
|
542
|
+
|
|
543
|
+
const routeSegments = routePath.split('/')
|
|
544
|
+
const originalSegments = originalPath.split('/')
|
|
545
|
+
const newSegments: Array<string> = []
|
|
349
546
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
547
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
548
|
+
const segment = routeSegments[i]!
|
|
549
|
+
const originalSegment = originalSegments[i] || ''
|
|
550
|
+
const segmentMetadata = metadata?.[i]
|
|
551
|
+
|
|
552
|
+
if (
|
|
553
|
+
!segmentMetadata?.literalLeadingUnderscore &&
|
|
554
|
+
isSegmentPathless(segment, originalSegment)
|
|
555
|
+
) {
|
|
556
|
+
continue
|
|
353
557
|
}
|
|
354
558
|
|
|
355
|
-
|
|
356
|
-
}
|
|
559
|
+
newSegments.push(removeUnderscoresFromSegment(segment, segmentMetadata))
|
|
560
|
+
}
|
|
357
561
|
|
|
358
562
|
return newSegments.join('/')
|
|
359
563
|
}
|
|
@@ -686,12 +890,10 @@ const inferPath = (routeNode: RouteNode): string => {
|
|
|
686
890
|
*/
|
|
687
891
|
export const inferFullPath = (routeNode: RouteNode): string => {
|
|
688
892
|
const fullPath = removeGroups(
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
routeNode.routePath,
|
|
692
|
-
routeNode.originalRoutePath,
|
|
693
|
-
),
|
|
893
|
+
removeLayoutSegmentsAndUnderscoresWithEscape(
|
|
894
|
+
routeNode.routePath,
|
|
694
895
|
routeNode.originalRoutePath,
|
|
896
|
+
routeNode._routePathSegmentMetadata,
|
|
695
897
|
),
|
|
696
898
|
)
|
|
697
899
|
|