@tanstack/router-generator 1.141.6 → 1.141.7
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/generator.cjs +87 -52
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/generator.d.cts +3 -0
- package/dist/cjs/utils.cjs +187 -79
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +37 -1
- package/dist/esm/generator.d.ts +3 -0
- package/dist/esm/generator.js +88 -53
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/utils.d.ts +37 -1
- package/dist/esm/utils.js +187 -79
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/generator.ts +102 -89
- package/src/utils.ts +266 -137
package/src/generator.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'
|
|
12
12
|
import { rootPathId } from './filesystem/physical/rootPathId'
|
|
13
13
|
import {
|
|
14
|
+
RoutePrefixMap,
|
|
14
15
|
buildFileRoutesByPathInterface,
|
|
15
16
|
buildImportString,
|
|
16
17
|
buildRouteTreeConfig,
|
|
@@ -37,7 +38,6 @@ import {
|
|
|
37
38
|
removeTrailingSlash,
|
|
38
39
|
removeUnderscores,
|
|
39
40
|
replaceBackslash,
|
|
40
|
-
resetRegex,
|
|
41
41
|
trimPathLeft,
|
|
42
42
|
} from './utils'
|
|
43
43
|
import { fillTemplate, getTargetTemplate } from './template'
|
|
@@ -188,9 +188,14 @@ export class Generator {
|
|
|
188
188
|
private runPromise: Promise<void> | undefined
|
|
189
189
|
private fileEventQueue: Array<GeneratorEvent> = []
|
|
190
190
|
private plugins: Array<GeneratorPlugin> = []
|
|
191
|
-
private static routeGroupPatternRegex = /\(.+\)/
|
|
191
|
+
private static routeGroupPatternRegex = /\(.+\)/
|
|
192
192
|
private physicalDirectories: Array<string> = []
|
|
193
193
|
|
|
194
|
+
private indexTokenRegex: RegExp
|
|
195
|
+
private routeTokenRegex: RegExp
|
|
196
|
+
private static componentPieceRegex =
|
|
197
|
+
/[./](component|errorComponent|notFoundComponent|pendingComponent|loader|lazy)[.]/
|
|
198
|
+
|
|
194
199
|
constructor(opts: { config: Config; root: string; fs?: fs }) {
|
|
195
200
|
this.config = opts.config
|
|
196
201
|
this.logger = logging({ disabled: this.config.disableLogging })
|
|
@@ -202,6 +207,9 @@ export class Generator {
|
|
|
202
207
|
this.routesDirectoryPath = this.getRoutesDirectoryPath()
|
|
203
208
|
this.plugins.push(...(opts.config.plugins || []))
|
|
204
209
|
|
|
210
|
+
this.indexTokenRegex = new RegExp(`[./]${this.config.indexToken}[.]`)
|
|
211
|
+
this.routeTokenRegex = new RegExp(`[./]${this.config.routeToken}[.]`)
|
|
212
|
+
|
|
205
213
|
for (const plugin of this.plugins) {
|
|
206
214
|
plugin.init?.({ generator: this })
|
|
207
215
|
}
|
|
@@ -346,20 +354,9 @@ export class Generator {
|
|
|
346
354
|
const preRouteNodes = multiSortBy(beforeRouteNodes, [
|
|
347
355
|
(d) => (d.routePath === '/' ? -1 : 1),
|
|
348
356
|
(d) => d.routePath?.split('/').length,
|
|
349
|
-
(d) =>
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
: -1,
|
|
353
|
-
(d) =>
|
|
354
|
-
d.filePath.match(
|
|
355
|
-
/[./](component|errorComponent|notFoundComponent|pendingComponent|loader|lazy)[.]/,
|
|
356
|
-
)
|
|
357
|
-
? 1
|
|
358
|
-
: -1,
|
|
359
|
-
(d) =>
|
|
360
|
-
d.filePath.match(new RegExp(`[./]${this.config.routeToken}[.]`))
|
|
361
|
-
? -1
|
|
362
|
-
: 1,
|
|
357
|
+
(d) => (d.filePath.match(this.indexTokenRegex) ? 1 : -1),
|
|
358
|
+
(d) => (d.filePath.match(Generator.componentPieceRegex) ? 1 : -1),
|
|
359
|
+
(d) => (d.filePath.match(this.routeTokenRegex) ? -1 : 1),
|
|
363
360
|
(d) => (d.routePath?.endsWith('/') ? -1 : 1),
|
|
364
361
|
(d) => d.routePath,
|
|
365
362
|
]).filter((d) => {
|
|
@@ -411,8 +408,10 @@ export class Generator {
|
|
|
411
408
|
routeNodesByPath: new Map(),
|
|
412
409
|
}
|
|
413
410
|
|
|
411
|
+
const prefixMap = new RoutePrefixMap(routeFileResult)
|
|
412
|
+
|
|
414
413
|
for (const node of routeFileResult) {
|
|
415
|
-
Generator.handleNode(node, acc, this.config)
|
|
414
|
+
Generator.handleNode(node, acc, prefixMap, this.config)
|
|
416
415
|
}
|
|
417
416
|
|
|
418
417
|
this.crawlingResult = { rootRouteNode, routeFileResult, acc }
|
|
@@ -549,44 +548,53 @@ export class Generator {
|
|
|
549
548
|
(d) => d,
|
|
550
549
|
])
|
|
551
550
|
|
|
552
|
-
const routeImports =
|
|
553
|
-
|
|
554
|
-
.flatMap((node) =>
|
|
555
|
-
getImportForRouteNode(
|
|
556
|
-
node,
|
|
557
|
-
config,
|
|
558
|
-
this.generatedRouteTreePath,
|
|
559
|
-
this.root,
|
|
560
|
-
),
|
|
561
|
-
)
|
|
551
|
+
const routeImports: Array<ImportDeclaration> = []
|
|
552
|
+
const virtualRouteNodes: Array<string> = []
|
|
562
553
|
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
554
|
+
for (const node of sortedRouteNodes) {
|
|
555
|
+
if (node.isVirtual) {
|
|
556
|
+
virtualRouteNodes.push(
|
|
557
|
+
`const ${node.variableName}RouteImport = createFileRoute('${node.routePath}')()`,
|
|
558
|
+
)
|
|
559
|
+
} else {
|
|
560
|
+
routeImports.push(
|
|
561
|
+
getImportForRouteNode(
|
|
562
|
+
node,
|
|
563
|
+
config,
|
|
564
|
+
this.generatedRouteTreePath,
|
|
565
|
+
this.root,
|
|
566
|
+
),
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
570
|
|
|
571
571
|
const imports: Array<ImportDeclaration> = []
|
|
572
|
-
if (
|
|
572
|
+
if (virtualRouteNodes.length > 0) {
|
|
573
573
|
imports.push({
|
|
574
574
|
specifiers: [{ imported: 'createFileRoute' }],
|
|
575
575
|
source: this.targetTemplate.fullPkg,
|
|
576
576
|
})
|
|
577
577
|
}
|
|
578
578
|
// Add lazyRouteComponent import if there are component pieces
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
579
|
+
let hasComponentPieces = false
|
|
580
|
+
let hasLoaderPieces = false
|
|
581
|
+
for (const node of sortedRouteNodes) {
|
|
582
|
+
const pieces = acc.routePiecesByPath[node.routePath!]
|
|
583
|
+
if (pieces) {
|
|
584
|
+
if (
|
|
585
|
+
pieces.component ||
|
|
586
|
+
pieces.errorComponent ||
|
|
587
|
+
pieces.notFoundComponent ||
|
|
588
|
+
pieces.pendingComponent
|
|
589
|
+
) {
|
|
590
|
+
hasComponentPieces = true
|
|
591
|
+
}
|
|
592
|
+
if (pieces.loader) {
|
|
593
|
+
hasLoaderPieces = true
|
|
594
|
+
}
|
|
595
|
+
if (hasComponentPieces && hasLoaderPieces) break
|
|
596
|
+
}
|
|
597
|
+
}
|
|
590
598
|
if (hasComponentPieces || hasLoaderPieces) {
|
|
591
599
|
const runtimeImport: ImportDeclaration = {
|
|
592
600
|
specifiers: [],
|
|
@@ -606,21 +614,23 @@ export class Generator {
|
|
|
606
614
|
source: this.targetTemplate.fullPkg,
|
|
607
615
|
importKind: 'type',
|
|
608
616
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
617
|
+
let needsCreateFileRoute = false
|
|
618
|
+
let needsCreateLazyFileRoute = false
|
|
619
|
+
for (const node of sortedRouteNodes) {
|
|
620
|
+
if (isRouteNodeValidForAugmentation(node)) {
|
|
621
|
+
if (node._fsRouteType !== 'lazy') {
|
|
622
|
+
needsCreateFileRoute = true
|
|
623
|
+
}
|
|
624
|
+
if (acc.routePiecesByPath[node.routePath!]?.lazy) {
|
|
625
|
+
needsCreateLazyFileRoute = true
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
if (needsCreateFileRoute && needsCreateLazyFileRoute) break
|
|
629
|
+
}
|
|
630
|
+
if (needsCreateFileRoute) {
|
|
615
631
|
typeImport.specifiers.push({ imported: 'CreateFileRoute' })
|
|
616
632
|
}
|
|
617
|
-
if (
|
|
618
|
-
sortedRouteNodes.some(
|
|
619
|
-
(node) =>
|
|
620
|
-
acc.routePiecesByPath[node.routePath!]?.lazy &&
|
|
621
|
-
isRouteNodeValidForAugmentation(node),
|
|
622
|
-
)
|
|
623
|
-
) {
|
|
633
|
+
if (needsCreateLazyFileRoute) {
|
|
624
634
|
typeImport.specifiers.push({ imported: 'CreateLazyFileRoute' })
|
|
625
635
|
}
|
|
626
636
|
|
|
@@ -636,15 +646,13 @@ export class Generator {
|
|
|
636
646
|
)
|
|
637
647
|
|
|
638
648
|
const createUpdateRoutes = sortedRouteNodes.map((node) => {
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
const notFoundComponentNode =
|
|
644
|
-
|
|
645
|
-
const
|
|
646
|
-
acc.routePiecesByPath[node.routePath!]?.pendingComponent
|
|
647
|
-
const lazyComponentNode = acc.routePiecesByPath[node.routePath!]?.lazy
|
|
649
|
+
const pieces = acc.routePiecesByPath[node.routePath!]
|
|
650
|
+
const loaderNode = pieces?.loader
|
|
651
|
+
const componentNode = pieces?.component
|
|
652
|
+
const errorComponentNode = pieces?.errorComponent
|
|
653
|
+
const notFoundComponentNode = pieces?.notFoundComponent
|
|
654
|
+
const pendingComponentNode = pieces?.pendingComponent
|
|
655
|
+
const lazyComponentNode = pieces?.lazy
|
|
648
656
|
|
|
649
657
|
return [
|
|
650
658
|
[
|
|
@@ -752,13 +760,11 @@ export class Generator {
|
|
|
752
760
|
|
|
753
761
|
// Generate update for root route if it has component pieces
|
|
754
762
|
const rootRoutePath = `/${rootPathId}`
|
|
755
|
-
const
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
const rootNotFoundComponentNode =
|
|
759
|
-
|
|
760
|
-
const rootPendingComponentNode =
|
|
761
|
-
acc.routePiecesByPath[rootRoutePath]?.pendingComponent
|
|
763
|
+
const rootPieces = acc.routePiecesByPath[rootRoutePath]
|
|
764
|
+
const rootComponentNode = rootPieces?.component
|
|
765
|
+
const rootErrorComponentNode = rootPieces?.errorComponent
|
|
766
|
+
const rootNotFoundComponentNode = rootPieces?.notFoundComponent
|
|
767
|
+
const rootPendingComponentNode = rootPieces?.pendingComponent
|
|
762
768
|
|
|
763
769
|
let rootRouteUpdate = ''
|
|
764
770
|
if (
|
|
@@ -816,16 +822,23 @@ export class Generator {
|
|
|
816
822
|
let fileRoutesByFullPath = ''
|
|
817
823
|
|
|
818
824
|
if (!config.disableTypes) {
|
|
825
|
+
const routeNodesByFullPath = createRouteNodesByFullPath(
|
|
826
|
+
acc.routeNodes,
|
|
827
|
+
config,
|
|
828
|
+
)
|
|
829
|
+
const routeNodesByTo = createRouteNodesByTo(acc.routeNodes, config)
|
|
830
|
+
const routeNodesById = createRouteNodesById(acc.routeNodes)
|
|
831
|
+
|
|
819
832
|
fileRoutesByFullPath = [
|
|
820
833
|
`export interface FileRoutesByFullPath {
|
|
821
|
-
${[...
|
|
834
|
+
${[...routeNodesByFullPath.entries()]
|
|
822
835
|
.filter(([fullPath]) => fullPath)
|
|
823
836
|
.map(([fullPath, routeNode]) => {
|
|
824
837
|
return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`
|
|
825
838
|
})}
|
|
826
839
|
}`,
|
|
827
840
|
`export interface FileRoutesByTo {
|
|
828
|
-
${[...
|
|
841
|
+
${[...routeNodesByTo.entries()]
|
|
829
842
|
.filter(([to]) => to)
|
|
830
843
|
.map(([to, routeNode]) => {
|
|
831
844
|
return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`
|
|
@@ -833,7 +846,7 @@ ${[...createRouteNodesByTo(acc.routeNodes, config).entries()]
|
|
|
833
846
|
}`,
|
|
834
847
|
`export interface FileRoutesById {
|
|
835
848
|
'${rootRouteId}': typeof rootRouteImport,
|
|
836
|
-
${[...
|
|
849
|
+
${[...routeNodesById.entries()].map(([id, routeNode]) => {
|
|
837
850
|
return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`
|
|
838
851
|
})}
|
|
839
852
|
}`,
|
|
@@ -841,7 +854,7 @@ ${[...createRouteNodesById(acc.routeNodes).entries()].map(([id, routeNode]) => {
|
|
|
841
854
|
fileRoutesByFullPath: FileRoutesByFullPath
|
|
842
855
|
fullPaths: ${
|
|
843
856
|
acc.routeNodes.length > 0
|
|
844
|
-
? [...
|
|
857
|
+
? [...routeNodesByFullPath.keys()]
|
|
845
858
|
.filter((fullPath) => fullPath)
|
|
846
859
|
.map((fullPath) => `'${fullPath}'`)
|
|
847
860
|
.join('|')
|
|
@@ -850,13 +863,13 @@ fullPaths: ${
|
|
|
850
863
|
fileRoutesByTo: FileRoutesByTo
|
|
851
864
|
to: ${
|
|
852
865
|
acc.routeNodes.length > 0
|
|
853
|
-
? [...
|
|
866
|
+
? [...routeNodesByTo.keys()]
|
|
854
867
|
.filter((to) => to)
|
|
855
868
|
.map((to) => `'${to}'`)
|
|
856
869
|
.join('|')
|
|
857
870
|
: 'never'
|
|
858
871
|
}
|
|
859
|
-
id: ${[`'${rootRouteId}'`, ...[...
|
|
872
|
+
id: ${[`'${rootRouteId}'`, ...[...routeNodesById.keys()].map((id) => `'${id}'`)].join('|')}
|
|
860
873
|
fileRoutesById: FileRoutesById
|
|
861
874
|
}`,
|
|
862
875
|
`export interface RootRouteChildren {
|
|
@@ -1344,18 +1357,14 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
1344
1357
|
private static handleNode(
|
|
1345
1358
|
node: RouteNode,
|
|
1346
1359
|
acc: HandleNodeAccumulator,
|
|
1360
|
+
prefixMap: RoutePrefixMap,
|
|
1347
1361
|
config?: Config,
|
|
1348
1362
|
) {
|
|
1349
|
-
// Do not remove this as we need to set the lastIndex to 0 as it
|
|
1350
|
-
// is necessary to reset the regex's index when using the global flag
|
|
1351
|
-
// otherwise it might not match the next time it's used
|
|
1352
1363
|
const useExperimentalNonNestedRoutes =
|
|
1353
1364
|
config?.experimental?.nonNestedRoutes ?? false
|
|
1354
1365
|
|
|
1355
|
-
resetRegex(this.routeGroupPatternRegex)
|
|
1356
|
-
|
|
1357
1366
|
const parentRoute = hasParentRoute(
|
|
1358
|
-
|
|
1367
|
+
prefixMap,
|
|
1359
1368
|
node,
|
|
1360
1369
|
node.routePath,
|
|
1361
1370
|
node.originalRoutePath,
|
|
@@ -1425,6 +1434,7 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
1425
1434
|
_fsRouteType: 'static',
|
|
1426
1435
|
},
|
|
1427
1436
|
acc,
|
|
1437
|
+
prefixMap,
|
|
1428
1438
|
config,
|
|
1429
1439
|
)
|
|
1430
1440
|
}
|
|
@@ -1447,9 +1457,12 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
1447
1457
|
const candidate = acc.routeNodesByPath.get(searchPath)
|
|
1448
1458
|
if (candidate && !candidate.isVirtual && candidate.path !== '/') {
|
|
1449
1459
|
node.parent = candidate
|
|
1450
|
-
node.path =
|
|
1460
|
+
node.path =
|
|
1461
|
+
node.routePath?.replace(candidate.routePath ?? '', '') || '/'
|
|
1462
|
+
const pathRelativeToParent =
|
|
1463
|
+
immediateParentPath.replace(candidate.routePath ?? '', '') || '/'
|
|
1451
1464
|
node.cleanedPath = removeGroups(
|
|
1452
|
-
removeUnderscores(removeLayoutSegments(
|
|
1465
|
+
removeUnderscores(removeLayoutSegments(pathRelativeToParent)) ?? '',
|
|
1453
1466
|
)
|
|
1454
1467
|
break
|
|
1455
1468
|
}
|