@tanstack/router-generator 1.64.0 → 1.69.1
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/virtual/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/generator.cjs +51 -27
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/esm/filesystem/virtual/getRouteNodes.js.map +1 -1
- package/dist/esm/generator.js +51 -27
- package/dist/esm/generator.js.map +1 -1
- package/package.json +1 -1
- package/src/filesystem/virtual/getRouteNodes.ts +1 -1
- package/src/generator.ts +60 -38
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport type {
|
|
1
|
+
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport type { VirtualRouteNode } from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nfunction ensureLeadingUnderScore(id: string) {\n if (id.startsWith('_')) {\n return id\n }\n return `_${id}`\n}\n\nfunction flattenTree(node: RouteNode): Array<RouteNode> {\n const result = [node]\n\n if (node.children) {\n for (const child of node.children) {\n result.push(...flattenTree(child))\n }\n }\n delete node.children\n\n return result\n}\n\nexport async function getRouteNodes(\n tsrConfig: Config,\n): Promise<GetRouteNodesResult> {\n const fullDir = resolve(tsrConfig.routesDirectory)\n if (tsrConfig.virtualRouteConfig === undefined) {\n throw new Error(`virtualRouteConfig is undefined`)\n }\n const children = await getRouteNodesRecursive(\n tsrConfig,\n fullDir,\n tsrConfig.virtualRouteConfig.children,\n )\n const allNodes = flattenTree({\n children,\n filePath: tsrConfig.virtualRouteConfig.file,\n fullPath: join(fullDir, tsrConfig.virtualRouteConfig.file),\n variableName: 'rootRoute',\n routePath: '/',\n isRoot: true,\n })\n\n const rootRouteNode = allNodes[0]\n const routeNodes = allNodes.slice(1)\n\n return { rootRouteNode, routeNodes }\n}\n\nexport async function getRouteNodesRecursive(\n tsrConfig: Config,\n fullDir: string,\n nodes?: Array<VirtualRouteNode>,\n parent?: RouteNode,\n): Promise<Array<RouteNode>> {\n if (nodes === undefined) {\n return []\n }\n const children = await Promise.all(\n nodes.map(async (node) => {\n if (node.type === 'physical') {\n const { routeNodes } = await getRouteNodesPhysical({\n ...tsrConfig,\n routesDirectory: resolve(fullDir, node.directory),\n })\n routeNodes.forEach((subtreeNode) => {\n subtreeNode.variableName = routePathToVariable(\n `${node.pathPrefix}/${removeExt(subtreeNode.filePath)}`,\n )\n subtreeNode.routePath = `${parent?.routePath ?? ''}${node.pathPrefix}${subtreeNode.routePath}`\n subtreeNode.filePath = `${node.directory}/${subtreeNode.filePath}`\n })\n return routeNodes\n }\n\n function getFile(file: string) {\n const filePath = file.split('/').join(path.sep)\n const variableName = routePathToVariable(removeExt(filePath))\n const fullPath = join(fullDir, filePath)\n return { filePath, variableName, fullPath }\n }\n const parentRoutePath = removeTrailingSlash(parent?.routePath ?? '/')\n const isLayout = node.type === 'layout'\n switch (node.type) {\n case 'index': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n const routePath = `${parentRoutePath}/`\n return {\n filePath,\n fullPath,\n variableName,\n routePath,\n isLayout,\n } satisfies RouteNode\n }\n\n case 'route': {\n const lastSegment = node.path\n let routeNode: RouteNode\n\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n if (node.file) {\n const { filePath, variableName, fullPath } = getFile(node.file)\n routeNode = {\n filePath,\n fullPath,\n variableName,\n routePath,\n isLayout,\n }\n } else {\n routeNode = {\n filePath: '',\n fullPath: '',\n variableName: '',\n routePath,\n isLayout,\n isVirtual: true,\n }\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n }\n return routeNode\n }\n case 'layout': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n\n if (node.id !== undefined) {\n node.id = ensureLeadingUnderScore(node.id)\n } else {\n const baseName = path.basename(filePath)\n const fileNameWithoutExt = path.parse(baseName).name\n node.id = ensureLeadingUnderScore(fileNameWithoutExt)\n }\n const lastSegment = node.id\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n\n const routeNode: RouteNode = {\n fullPath,\n isLayout,\n filePath,\n variableName,\n routePath,\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n }\n return routeNode\n }\n }\n }),\n )\n return children.flat()\n}\n"],"names":["resolve","join","getRouteNodesPhysical","routePathToVariable","removeExt","removeTrailingSlash","removeLeadingSlash","children"],"mappings":"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"}
|
package/dist/cjs/generator.cjs
CHANGED
|
@@ -255,8 +255,15 @@ export const Route = createRootRoute({
|
|
|
255
255
|
for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {
|
|
256
256
|
await handleNode(node);
|
|
257
257
|
}
|
|
258
|
+
checkRouteFullPathUniqueness(
|
|
259
|
+
preRouteNodes.filter(
|
|
260
|
+
(d) => !d.isAPIRoute && d.children === void 0 && d.isLazy !== true
|
|
261
|
+
),
|
|
262
|
+
config
|
|
263
|
+
);
|
|
258
264
|
const startAPIRouteNodes = checkStartAPIRoutes(
|
|
259
|
-
preRouteNodes.filter((d) => d.isAPIRoute)
|
|
265
|
+
preRouteNodes.filter((d) => d.isAPIRoute),
|
|
266
|
+
config
|
|
260
267
|
);
|
|
261
268
|
const handleAPINode = async (node) => {
|
|
262
269
|
var _a;
|
|
@@ -452,11 +459,9 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
452
459
|
interface FileRoutesByPath {
|
|
453
460
|
${routeNodes.map((routeNode) => {
|
|
454
461
|
var _a, _b;
|
|
455
|
-
const
|
|
456
|
-
routeNode.routePath
|
|
457
|
-
);
|
|
462
|
+
const filePathId = getFilePathIdFromPath(routeNode.routePath);
|
|
458
463
|
return `'${filePathId}': {
|
|
459
|
-
id: '${
|
|
464
|
+
id: '${filePathId}'
|
|
460
465
|
path: '${inferPath(routeNode)}'
|
|
461
466
|
fullPath: '${inferFullPath(routeNode)}'
|
|
462
467
|
preLoaderRoute: typeof ${routeNode.variableName}Import
|
|
@@ -509,21 +514,19 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
509
514
|
const routesManifest = {
|
|
510
515
|
__root__: {
|
|
511
516
|
filePath: rootRouteNode.filePath,
|
|
512
|
-
children: routeTree.map(
|
|
513
|
-
(d) => getFilePathIdAndRouteIdFromPath(d.routePath)[1]
|
|
514
|
-
)
|
|
517
|
+
children: routeTree.map((d) => getFilePathIdFromPath(d.routePath))
|
|
515
518
|
},
|
|
516
519
|
...Object.fromEntries(
|
|
517
520
|
routeNodes.map((d) => {
|
|
518
521
|
var _a, _b;
|
|
519
|
-
const
|
|
522
|
+
const filePathId = getFilePathIdFromPath(d.routePath);
|
|
520
523
|
return [
|
|
521
|
-
|
|
524
|
+
filePathId,
|
|
522
525
|
{
|
|
523
526
|
filePath: d.filePath,
|
|
524
|
-
parent: ((_a = d.parent) == null ? void 0 : _a.routePath) ?
|
|
527
|
+
parent: ((_a = d.parent) == null ? void 0 : _a.routePath) ? getFilePathIdFromPath(d.parent.routePath) : void 0,
|
|
525
528
|
children: (_b = d.children) == null ? void 0 : _b.map(
|
|
526
|
-
(childRoute) =>
|
|
529
|
+
(childRoute) => getFilePathIdFromPath(childRoute.routePath)
|
|
527
530
|
)
|
|
528
531
|
}
|
|
529
532
|
];
|
|
@@ -634,7 +637,7 @@ const createRouteNodesByTo = (routeNodes) => {
|
|
|
634
637
|
const createRouteNodesById = (routeNodes) => {
|
|
635
638
|
return new Map(
|
|
636
639
|
routeNodes.map((routeNode) => {
|
|
637
|
-
const
|
|
640
|
+
const id = getFilePathIdFromPath(routeNode.routePath);
|
|
638
641
|
return [id, routeNode];
|
|
639
642
|
})
|
|
640
643
|
);
|
|
@@ -661,12 +664,38 @@ const dedupeBranchesAndIndexRoutes = (routes) => {
|
|
|
661
664
|
return true;
|
|
662
665
|
});
|
|
663
666
|
};
|
|
664
|
-
function
|
|
667
|
+
function getFilePathIdFromPath(pathname) {
|
|
665
668
|
const filePathId = removeTrailingUnderscores(pathname);
|
|
666
|
-
|
|
667
|
-
|
|
669
|
+
return filePathId ?? "";
|
|
670
|
+
}
|
|
671
|
+
function checkUnique(routes, key) {
|
|
672
|
+
const keys = routes.map((d) => d[key]);
|
|
673
|
+
const uniqueKeys = new Set(keys);
|
|
674
|
+
if (keys.length !== uniqueKeys.size) {
|
|
675
|
+
const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i);
|
|
676
|
+
const conflictingFiles = routes.filter(
|
|
677
|
+
(d) => duplicateKeys.includes(d[key])
|
|
678
|
+
);
|
|
679
|
+
return conflictingFiles;
|
|
680
|
+
}
|
|
681
|
+
return void 0;
|
|
682
|
+
}
|
|
683
|
+
function checkRouteFullPathUniqueness(_routes, config) {
|
|
684
|
+
const routes = _routes.map((d) => {
|
|
685
|
+
const inferredFullPath = inferFullPath(d);
|
|
686
|
+
return { ...d, inferredFullPath };
|
|
687
|
+
});
|
|
688
|
+
const conflictingFiles = checkUnique(routes, "inferredFullPath");
|
|
689
|
+
if (conflictingFiles !== void 0) {
|
|
690
|
+
const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? "s" : ""}: ${conflictingFiles.map((p) => `"${p.inferredFullPath}"`).join(", ")}.
|
|
691
|
+
Please ensure each route has a unique full path.
|
|
692
|
+
Conflicting files:
|
|
693
|
+
${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join("\n ")}
|
|
694
|
+
`;
|
|
695
|
+
throw new Error(errorMessage);
|
|
696
|
+
}
|
|
668
697
|
}
|
|
669
|
-
function checkStartAPIRoutes(_routes) {
|
|
698
|
+
function checkStartAPIRoutes(_routes, config) {
|
|
670
699
|
if (_routes.length === 0) {
|
|
671
700
|
return [];
|
|
672
701
|
}
|
|
@@ -674,17 +703,12 @@ function checkStartAPIRoutes(_routes) {
|
|
|
674
703
|
const routePath = utils.removeTrailingSlash(d.routePath ?? "");
|
|
675
704
|
return { ...d, routePath };
|
|
676
705
|
});
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
(d, i) => routePaths.indexOf(d) !== i
|
|
682
|
-
);
|
|
683
|
-
const conflictingFiles = routes.filter((d) => duplicateRoutePaths.includes(d.routePath)).map((d) => `${d.fullPath}`);
|
|
684
|
-
const errorMessage = `Conflicting configuration paths was for found for the following API route${duplicateRoutePaths.length > 1 ? "s" : ""}: ${duplicateRoutePaths.map((p) => `"${p}"`).join(", ")}.
|
|
685
|
-
Please ensure each API route has a unique route path.
|
|
706
|
+
const conflictingFiles = checkUnique(routes, "routePath");
|
|
707
|
+
if (conflictingFiles !== void 0) {
|
|
708
|
+
const errorMessage = `Conflicting configuration paths were found for the following API route${conflictingFiles.length > 1 ? "s" : ""}: ${conflictingFiles.map((p) => `"${p}"`).join(", ")}.
|
|
709
|
+
Please ensure each API route has a unique route path.
|
|
686
710
|
Conflicting files:
|
|
687
|
-
${conflictingFiles.join("\n ")}
|
|
711
|
+
${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join("\n ")}
|
|
688
712
|
`;
|
|
689
713
|
throw new Error(errorMessage);
|
|
690
714
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.cjs","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fs from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport * as prettier from 'prettier'\nimport {\n determineInitialRoutePath,\n logging,\n multiSortBy,\n removeExt,\n removeTrailingSlash,\n removeUnderscores,\n replaceBackslash,\n routePathToVariable,\n trimPathLeft,\n writeIfDifferent,\n} from './utils'\nimport { getRouteNodes as physicalGetRouteNodes } from './filesystem/physical/getRouteNodes'\nimport { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport type { GetRouteNodesResult, RouteNode } from './types'\nimport type { Config } from './config'\n\nlet latestTask = 0\nconst routeGroupPatternRegex = /\\(.+\\)/g\nconst possiblyNestedRouteGroupPatternRegex = /\\([^/]+\\)\\/?/g\n\nlet isFirst = false\nlet skipMessage = false\n\ntype RouteSubNode = {\n component?: RouteNode\n errorComponent?: RouteNode\n pendingComponent?: RouteNode\n loader?: RouteNode\n lazy?: RouteNode\n}\n\nexport async function generator(config: Config) {\n const logger = logging({ disabled: config.disableLogging })\n logger.log('')\n\n if (!isFirst) {\n logger.log('♻️ Generating routes...')\n isFirst = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n logger.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n\n const TYPES_DISABLED = config.disableTypes\n\n const prettierOptions: prettier.Options = {\n semi: config.semicolons,\n singleQuote: config.quoteStyle === 'single',\n parser: 'typescript',\n }\n\n let getRouteNodesResult: GetRouteNodesResult\n\n if (config.virtualRouteConfig) {\n getRouteNodesResult = await virtualGetRouteNodes(config)\n } else {\n getRouteNodesResult = await physicalGetRouteNodes(config)\n }\n\n const { rootRouteNode, routeNodes: beforeRouteNodes } = getRouteNodesResult\n if (rootRouteNode === undefined) {\n let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`\n if (!config.virtualRouteConfig) {\n errorMessage += `\\nMake sure that you add a \"${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\" file to your routes directory.\\nAdd the file in: \"${config.routesDirectory}/${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\"`\n }\n throw new Error(errorMessage)\n }\n\n const preRouteNodes = multiSortBy(beforeRouteNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.indexToken}[.]`)) ? 1 : -1,\n (d) =>\n d.filePath.match(\n /[./](component|errorComponent|pendingComponent|loader|lazy)[.]/,\n )\n ? 1\n : -1,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.routeToken}[.]`)) ? -1 : 1,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => ![`/${rootPathId}`].includes(d.routePath || ''))\n\n const routeTree: Array<RouteNode> = []\n const routePiecesByPath: Record<string, RouteSubNode> = {}\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n const routeNodes: Array<RouteNode> = []\n\n // the handleRootNode function is not being collapsed into the handleNode function\n // because it requires only a subset of the logic that the handleNode function requires\n // and it's easier to read and maintain this way\n const handleRootNode = async (node?: RouteNode) => {\n if (!node) {\n // currently this is not being handled, but it could be in the future\n // for example to handle a virtual root route\n return\n }\n\n // from here on, we are only handling the root node that's present in the file system\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n if (!routeCode) {\n const replaced = `import * as React from 'react';\nimport { Outlet, createRootRoute } from '@tanstack/react-router';\n\nexport const Route = createRootRoute({\n component: () => (\n <React.Fragment>\n <div>Hello \"${rootPathId}\"!</div>\n <Outlet />\n </React.Fragment>\n ),\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n }\n }\n\n await handleRootNode(rootRouteNode)\n\n const handleNode = async (node: RouteNode) => {\n let parentRoute = hasParentRoute(routeNodes, node, node.routePath)\n\n // if the parent route is a virtual parent route, we need to find the real parent route\n if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {\n // only if this sub-parent route returns a valid parent route, we use it, if not leave it as it\n const possibleParentRoute = hasParentRoute(\n parentRoute.children,\n node,\n node.routePath,\n )\n if (possibleParentRoute) {\n parentRoute = possibleParentRoute\n }\n }\n\n if (parentRoute) node.parent = parentRoute\n\n node.path = determineNodePath(node)\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath.split('/')\n const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n\n node.isNonPath =\n lastRouteSegment.startsWith('_') ||\n routeGroupPatternRegex.test(lastRouteSegment)\n\n node.cleanedPath = removeGroups(\n removeUnderscores(removeLayoutSegments(node.path)) ?? '',\n )\n\n // Ensure the boilerplate for the route exists, which can be skipped for virtual parent routes and virtual routes\n if (!node.isVirtualParentRoute && !node.isVirtual) {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n let replaced = routeCode\n\n if (!routeCode) {\n if (node.isLazy) {\n replaced = [\n `import { createLazyFileRoute } from '@tanstack/react-router'`,\n `export const Route = createLazyFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n } else if (\n node.isRoute ||\n (!node.isComponent &&\n !node.isErrorComponent &&\n !node.isPendingComponent &&\n !node.isLoader)\n ) {\n replaced = [\n `import { createFileRoute } from '@tanstack/react-router'`,\n `export const Route = createFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n }\n } else {\n replaced = routeCode\n .replace(\n /(FileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3) => `${p1}${escapedRoutePath}${p3}`,\n )\n .replace(\n /(import\\s*\\{.*)(create(Lazy)?FileRoute)(.*\\}\\s*from\\s*['\"]@tanstack\\/react-router['\"])/gs,\n (match, p1, p2, p3, p4) =>\n `${p1}${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p4}`,\n )\n .replace(\n /create(Lazy)?FileRoute(\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3, p4) =>\n `${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p2}${escapedRoutePath}${p4}`,\n )\n }\n\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n replaced,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n\n if (\n !node.isVirtual &&\n (node.isLoader ||\n node.isComponent ||\n node.isErrorComponent ||\n node.isPendingComponent ||\n node.isLazy)\n ) {\n routePiecesByPath[node.routePath!] =\n routePiecesByPath[node.routePath!] || {}\n\n routePiecesByPath[node.routePath!]![\n node.isLazy\n ? 'lazy'\n : node.isLoader\n ? 'loader'\n : node.isErrorComponent\n ? 'errorComponent'\n : node.isPendingComponent\n ? 'pendingComponent'\n : 'component'\n ] = node\n\n const anchorRoute = routeNodes.find((d) => d.routePath === node.routePath)\n\n if (!anchorRoute) {\n await handleNode({\n ...node,\n isVirtual: true,\n isLazy: false,\n isLoader: false,\n isComponent: false,\n isErrorComponent: false,\n isPendingComponent: false,\n })\n }\n return\n }\n\n const cleanedPathIsEmpty = (node.cleanedPath || '').length === 0\n const nonPathRoute = node.isRoute && node.isNonPath\n node.isVirtualParentRequired =\n node.isLayout || nonPathRoute ? !cleanedPathIsEmpty : false\n if (!node.isVirtual && node.isVirtualParentRequired) {\n const parentRoutePath = removeLastSegmentFromPath(node.routePath) || '/'\n const parentVariableName = routePathToVariable(parentRoutePath)\n\n const anchorRoute = routeNodes.find(\n (d) => d.routePath === parentRoutePath,\n )\n\n if (!anchorRoute) {\n const parentNode = {\n ...node,\n path: removeLastSegmentFromPath(node.path) || '/',\n filePath: removeLastSegmentFromPath(node.filePath) || '/',\n fullPath: removeLastSegmentFromPath(node.fullPath) || '/',\n routePath: parentRoutePath,\n variableName: parentVariableName,\n isVirtual: true,\n isLayout: false,\n isVirtualParentRoute: true,\n isVirtualParentRequired: false,\n }\n\n parentNode.children = parentNode.children ?? []\n parentNode.children.push(node)\n\n node.parent = parentNode\n\n if (node.isLayout) {\n // since `node.path` is used as the `id` on the route definition, we need to update it\n node.path = determineNodePath(node)\n }\n\n await handleNode(parentNode)\n } else {\n anchorRoute.children = anchorRoute.children ?? []\n anchorRoute.children.push(node)\n\n node.parent = anchorRoute\n }\n }\n\n if (node.parent) {\n if (!node.isVirtualParentRequired) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n }\n } else {\n routeTree.push(node)\n }\n\n routeNodes.push(node)\n }\n\n for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {\n await handleNode(node)\n }\n\n const startAPIRouteNodes: Array<RouteNode> = checkStartAPIRoutes(\n preRouteNodes.filter((d) => d.isAPIRoute),\n )\n\n const handleAPINode = async (node: RouteNode) => {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n if (!routeCode) {\n const replaced = `import { json } from '@tanstack/start'\nimport { createAPIFileRoute } from '@tanstack/start/api'\n\nexport const Route = createAPIFileRoute('${escapedRoutePath}')({\n GET: ({ request, params }) => {\n return json({ message: 'Hello ${escapedRoutePath}' })\n },\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n } else {\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n routeCode.replace(\n /(createAPIFileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (_, p1, __, p3) => `${p1}${escapedRoutePath}${p3}`,\n ),\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n }\n\n for (const node of startAPIRouteNodes) {\n await handleAPINode(node)\n }\n\n function buildRouteTreeConfig(nodes: Array<RouteNode>, depth = 1): string {\n const children = nodes.map((node) => {\n if (node.isRoot) {\n return\n }\n\n if (node.isLayout && !node.children?.length) {\n return\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = buildRouteTreeConfig(node.children, depth + 1)\n\n const childrenDeclaration = TYPES_DISABLED\n ? ''\n : `interface ${route}Children {\n ${node.children.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const children = `const ${route}Children${TYPES_DISABLED ? '' : `: ${route}Children`} = {\n ${node.children.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const routeWithChildren = `const ${route}WithChildren = ${route}._addFileChildren(${route}Children)`\n\n return [\n childConfigs,\n childrenDeclaration,\n children,\n routeWithChildren,\n ].join('\\n\\n')\n }\n\n return undefined\n })\n\n return children.filter(Boolean).join('\\n\\n')\n }\n\n const routeConfigChildrenText = buildRouteTreeConfig(routeTree)\n\n const sortedRouteNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(config.indexToken) ? -1 : 1),\n (d) => d,\n ])\n\n const imports = Object.entries({\n createFileRoute: sortedRouteNodes.some((d) => d.isVirtual),\n lazyFn: sortedRouteNodes.some(\n (node) => routePiecesByPath[node.routePath!]?.loader,\n ),\n lazyRouteComponent: sortedRouteNodes.some(\n (node) =>\n routePiecesByPath[node.routePath!]?.component ||\n routePiecesByPath[node.routePath!]?.errorComponent ||\n routePiecesByPath[node.routePath!]?.pendingComponent,\n ),\n })\n .filter((d) => d[1])\n .map((d) => d[0])\n\n const virtualRouteNodes = sortedRouteNodes.filter((d) => d.isVirtual)\n\n function getImportPath(node: RouteNode) {\n return replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n config.addExtensions,\n ),\n )\n }\n const routeImports = [\n ...config.routeTreeFileHeader,\n '// This file is auto-generated by TanStack Router',\n imports.length\n ? `import { ${imports.join(', ')} } from '@tanstack/react-router'\\n`\n : '',\n '// Import Routes',\n [\n `import { Route as rootRoute } from './${getImportPath(rootRouteNode)}'`,\n ...sortedRouteNodes\n .filter((d) => !d.isVirtual)\n .map((node) => {\n return `import { Route as ${\n node.variableName\n }Import } from './${getImportPath(node)}'`\n }),\n ].join('\\n'),\n virtualRouteNodes.length ? '// Create Virtual Routes' : '',\n virtualRouteNodes\n .map((node) => {\n return `const ${\n node.variableName\n }Import = createFileRoute('${removeTrailingUnderscores(\n node.routePath,\n )}')()`\n })\n .join('\\n'),\n '// Create/Update Routes',\n sortedRouteNodes\n .map((node) => {\n const loaderNode = routePiecesByPath[node.routePath!]?.loader\n const componentNode = routePiecesByPath[node.routePath!]?.component\n const errorComponentNode =\n routePiecesByPath[node.routePath!]?.errorComponent\n const pendingComponentNode =\n routePiecesByPath[node.routePath!]?.pendingComponent\n const lazyComponentNode = routePiecesByPath[node.routePath!]?.lazy\n\n return [\n `const ${node.variableName}Route = ${node.variableName}Import.update({\n ${[\n node.isNonPath\n ? `id: '${node.path}'`\n : `path: '${node.cleanedPath}'`,\n `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,\n ]\n .filter(Boolean)\n .join(',')}\n }${TYPES_DISABLED ? '' : 'as any'})`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n config.addExtensions,\n ),\n )}'), 'loader') })`\n : '',\n componentNode || errorComponentNode || pendingComponentNode\n ? `.update({\n ${(\n [\n ['component', componentNode],\n ['errorComponent', errorComponentNode],\n ['pendingComponent', pendingComponentNode],\n ] as const\n )\n .filter((d) => d[1])\n .map((d) => {\n return `${\n d[0]\n }: lazyRouteComponent(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, d[1]!.filePath),\n ),\n config.addExtensions,\n ),\n )}'), '${d[0]}')`\n })\n .join('\\n,')}\n })`\n : '',\n lazyComponentNode\n ? `.lazy(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n lazyComponentNode.filePath,\n ),\n ),\n config.addExtensions,\n ),\n )}').then((d) => d.Route))`\n : '',\n ].join('')\n })\n .join('\\n\\n'),\n ...(TYPES_DISABLED\n ? []\n : [\n '// Populate the FileRoutesByPath interface',\n `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n const [filePathId, routeId] = getFilePathIdAndRouteIdFromPath(\n routeNode.routePath,\n )\n\n return `'${filePathId}': {\n id: '${routeId}'\n path: '${inferPath(routeNode)}'\n fullPath: '${inferFullPath(routeNode)}'\n preLoaderRoute: typeof ${routeNode.variableName}Import\n parentRoute: typeof ${\n routeNode.isVirtualParentRequired\n ? `${routeNode.parent?.variableName}Route`\n : routeNode.parent?.variableName\n ? `${routeNode.parent.variableName}Import`\n : 'rootRoute'\n }\n }`\n })\n .join('\\n')}\n }\n}`,\n ]),\n '// Create and export the route tree',\n routeConfigChildrenText,\n ...(TYPES_DISABLED\n ? []\n : [\n `export interface FileRoutesByFullPath {\n ${[...createRouteNodesByFullPath(routeNodes).entries()].map(\n ([fullPath, routeNode]) => {\n return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n },\n )}\n}`,\n `export interface FileRoutesByTo {\n ${[...createRouteNodesByTo(routeNodes).entries()].map(([to, routeNode]) => {\n return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesById {\n '__root__': typeof rootRoute,\n ${[...createRouteNodesById(routeNodes).entries()].map(([id, routeNode]) => {\n return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRouteTypes {\n fileRoutesByFullPath: FileRoutesByFullPath\n fullPaths: ${routeNodes.length > 0 ? [...createRouteNodesByFullPath(routeNodes).keys()].map((fullPath) => `'${fullPath}'`).join('|') : 'never'}\n fileRoutesByTo: FileRoutesByTo\n to: ${routeNodes.length > 0 ? [...createRouteNodesByTo(routeNodes).keys()].map((to) => `'${to}'`).join('|') : 'never'}\n id: ${[`'__root__'`, ...[...createRouteNodesById(routeNodes).keys()].map((id) => `'${id}'`)].join('|')}\n fileRoutesById: FileRoutesById\n}`,\n `export interface RootRouteChildren {\n ${routeTree.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n ]),\n `const rootRouteChildren${TYPES_DISABLED ? '' : ': RootRouteChildren'} = {\n ${routeTree.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n `export const routeTree = rootRoute._addFileChildren(rootRouteChildren)${TYPES_DISABLED ? '' : '._addFileTypes<FileRouteTypes>()'}`,\n ...config.routeTreeFileFooter,\n ]\n .filter(Boolean)\n .join('\\n\\n')\n\n const createRouteManifest = () => {\n const routesManifest = {\n __root__: {\n filePath: rootRouteNode.filePath,\n children: routeTree.map(\n (d) => getFilePathIdAndRouteIdFromPath(d.routePath)[1],\n ),\n },\n ...Object.fromEntries(\n routeNodes.map((d) => {\n const [_, routeId] = getFilePathIdAndRouteIdFromPath(d.routePath)\n\n return [\n routeId,\n {\n filePath: d.filePath,\n parent: d.parent?.routePath\n ? getFilePathIdAndRouteIdFromPath(d.parent.routePath)[1]\n : undefined,\n children: d.children?.map(\n (childRoute) =>\n getFilePathIdAndRouteIdFromPath(childRoute.routePath)[1],\n ),\n },\n ]\n }),\n ),\n }\n\n return JSON.stringify(\n {\n routes: routesManifest,\n },\n null,\n 2,\n )\n }\n\n const routeConfigFileContent = config.disableManifestGeneration\n ? routeImports\n : [\n routeImports,\n '\\n',\n '/* ROUTE_MANIFEST_START',\n createRouteManifest(),\n 'ROUTE_MANIFEST_END */',\n ].join('\\n')\n\n if (!checkLatest()) return\n\n const existingRouteTreeContent = await fsp\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return ''\n }\n\n throw err\n })\n\n if (!checkLatest()) return\n\n // Ensure the directory exists\n await fsp.mkdir(path.dirname(path.resolve(config.generatedRouteTree)), {\n recursive: true,\n })\n\n if (!checkLatest()) return\n\n // Write the route tree file, if it has changed\n const routeTreeWriteResult = await writeIfDifferent(\n path.resolve(config.generatedRouteTree),\n prettierOptions,\n existingRouteTreeContent,\n routeConfigFileContent,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${config.generatedRouteTree}`)\n },\n },\n )\n if (routeTreeWriteResult && !checkLatest()) {\n return\n }\n\n logger.log(\n `✅ Processed ${routeNodes.length === 1 ? 'route' : 'routes'} in ${\n Date.now() - start\n }ms`,\n )\n}\n\nfunction spaces(d: number): string {\n return Array.from({ length: d })\n .map(() => ' ')\n .join('')\n}\n\nfunction removeTrailingUnderscores(s?: string) {\n return s?.replaceAll(/(_$)/gi, '').replaceAll(/(_\\/)/gi, '/')\n}\n\nfunction removeGroups(s: string) {\n return s.replace(possiblyNestedRouteGroupPatternRegex, '')\n}\n\n/**\n * The `node.path` is used as the `id` in the route definition.\n * This function checks if the given node has a parent and if so, it determines the correct path for the given node.\n * @param node - The node to determine the path for.\n * @returns The correct path for the given node.\n */\nfunction determineNodePath(node: RouteNode) {\n return (node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath ?? '', '') || '/'\n : node.routePath)\n}\n\n/**\n * Removes the last segment from a given path. Segments are considered to be separated by a '/'.\n *\n * @param {string} routePath - The path from which to remove the last segment. Defaults to '/'.\n * @returns {string} The path with the last segment removed.\n * @example\n * removeLastSegmentFromPath('/workspace/_auth/foo') // '/workspace/_auth'\n */\nexport function removeLastSegmentFromPath(routePath: string = '/'): string {\n const segments = routePath.split('/')\n segments.pop() // Remove the last segment\n return segments.join('/')\n}\n\n/**\n * Removes all segments from a given path that start with an underscore ('_').\n *\n * @param {string} routePath - The path from which to remove segments. Defaults to '/'.\n * @returns {string} The path with all underscore-prefixed segments removed.\n * @example\n * removeLayoutSegments('/workspace/_auth/foo') // '/workspace/foo'\n */\nfunction removeLayoutSegments(routePath: string = '/'): string {\n const segments = routePath.split('/')\n const newSegments = segments.filter((segment) => !segment.startsWith('_'))\n return newSegments.join('/')\n}\n\nexport function hasParentRoute(\n routes: Array<RouteNode>,\n node: RouteNode,\n routePathToCheck: string | undefined,\n): RouteNode | null {\n if (!routePathToCheck || routePathToCheck === '/') {\n return null\n }\n\n const sortedNodes = multiSortBy(routes, [\n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue\n\n if (\n routePathToCheck.startsWith(`${route.routePath}/`) &&\n route.routePath !== routePathToCheck\n ) {\n return route\n }\n }\n\n const segments = routePathToCheck.split('/')\n segments.pop() // Remove the last segment\n const parentRoutePath = segments.join('/')\n\n return hasParentRoute(routes, node, parentRoutePath)\n}\n\n/**\n * Gets the final variable name for a route\n */\nexport const getResolvedRouteNodeVariableName = (\n routeNode: RouteNode,\n): string => {\n return routeNode.children?.length\n ? `${routeNode.variableName}RouteWithChildren`\n : `${routeNode.variableName}Route`\n}\n\n/**\n * Creates a map from fullPath to routeNode\n */\nexport const createRouteNodesByFullPath = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => [inferFullPath(routeNode), routeNode]),\n )\n}\n\n/**\n * Create a map from 'to' to a routeNode\n */\nexport const createRouteNodesByTo = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n dedupeBranchesAndIndexRoutes(routeNodes).map((routeNode) => [\n inferTo(routeNode),\n routeNode,\n ]),\n )\n}\n\n/**\n * Create a map from 'id' to a routeNode\n */\nexport const createRouteNodesById = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => {\n const [_, id] = getFilePathIdAndRouteIdFromPath(routeNode.routePath)\n return [id, routeNode]\n }),\n )\n}\n\n/**\n * Infers the full path for use by TS\n */\nexport const inferFullPath = (routeNode: RouteNode): string => {\n const fullPath = removeGroups(\n removeUnderscores(removeLayoutSegments(routeNode.routePath)) ?? '',\n )\n\n return routeNode.cleanedPath === '/' ? fullPath : fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Infers the path for use by TS\n */\nexport const inferPath = (routeNode: RouteNode): string => {\n return routeNode.cleanedPath === '/'\n ? routeNode.cleanedPath\n : (routeNode.cleanedPath?.replace(/\\/$/, '') ?? '')\n}\n\n/**\n * Infers to path\n */\nexport const inferTo = (routeNode: RouteNode): string => {\n const fullPath = inferFullPath(routeNode)\n\n if (fullPath === '/') return fullPath\n\n return fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Dedupes branches and index routes\n */\nexport const dedupeBranchesAndIndexRoutes = (\n routes: Array<RouteNode>,\n): Array<RouteNode> => {\n return routes.filter((route) => {\n if (route.children?.find((child) => child.cleanedPath === '/')) return false\n return true\n })\n}\n\nfunction getFilePathIdAndRouteIdFromPath(pathname?: string) {\n const filePathId = removeTrailingUnderscores(pathname)\n const id = removeGroups(filePathId ?? '')\n\n return [filePathId, id] as const\n}\n\nfunction checkStartAPIRoutes(_routes: Array<RouteNode>) {\n if (_routes.length === 0) {\n return []\n }\n\n // Make sure these are valid URLs\n // Route Groups and Layout Routes aren't being removed since\n // you may want to have an API route that starts with an underscore\n // or be wrapped in parentheses\n const routes = _routes.map((d) => {\n const routePath = removeTrailingSlash(d.routePath ?? '')\n return { ...d, routePath }\n })\n\n // Check no two API routes have the same routePath\n // if they do, throw an error with the conflicting filePaths\n const routePaths = routes.map((d) => d.routePath)\n const uniqueRoutePaths = new Set(routePaths)\n if (routePaths.length !== uniqueRoutePaths.size) {\n const duplicateRoutePaths = routePaths.filter(\n (d, i) => routePaths.indexOf(d) !== i,\n )\n const conflictingFiles = routes\n .filter((d) => duplicateRoutePaths.includes(d.routePath))\n .map((d) => `${d.fullPath}`)\n const errorMessage = `Conflicting configuration paths was for found for the following API route${duplicateRoutePaths.length > 1 ? 's' : ''}: ${duplicateRoutePaths\n .map((p) => `\"${p}\"`)\n .join(', ')}.\nPlease ensure each API route has a unique route path.\nConflicting files: \\n ${conflictingFiles.join('\\n ')}\\n`\n throw new Error(errorMessage)\n }\n\n return routes\n}\n\nexport type StartAPIRoutePathSegment = {\n value: string\n type: 'path' | 'param' | 'splat'\n}\n\n/**\n * This function takes in a path in the format accepted by TanStack Router\n * and returns an array of path segments that can be used to generate\n * the pathname of the TanStack Start API route.\n *\n * @param src\n * @returns\n */\nexport function startAPIRouteSegmentsFromTSRFilePath(\n src: string,\n config: Config,\n): Array<StartAPIRoutePathSegment> {\n const routePath = determineInitialRoutePath(src)\n\n const parts = routePath\n .replaceAll('.', '/')\n .split('/')\n .filter((p) => !!p && p !== config.indexToken)\n const segments: Array<StartAPIRoutePathSegment> = parts.map((part) => {\n if (part.startsWith('$')) {\n if (part === '$') {\n return { value: part, type: 'splat' }\n }\n\n part.replaceAll('$', '')\n return { value: part, type: 'param' }\n }\n\n return { value: part, type: 'path' }\n })\n\n return segments\n}\n"],"names":["logging","virtualGetRouteNodes","physicalGetRouteNodes","rootPathId","multiSortBy","fs","prettier","trimPathLeft","removeUnderscores","writeIfDifferent","routePathToVariable","children","replaceBackslash","removeExt","fsp","removeTrailingSlash","determineInitialRoutePath"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAI,aAAa;AACjB,MAAM,yBAAyB;AAC/B,MAAM,uCAAuC;AAE7C,IAAI,UAAU;AACd,IAAI,cAAc;AAUlB,eAAsB,UAAU,QAAgB;AAC9C,QAAM,SAASA,MAAAA,QAAQ,EAAE,UAAU,OAAO,gBAAgB;AAC1D,SAAO,IAAI,EAAE;AAEb,MAAI,CAAC,SAAS;AACZ,WAAO,IAAI,0BAA0B;AAC3B,cAAA;AAAA,aACD,aAAa;AACR,kBAAA;AAAA,EAAA,OACT;AACL,WAAO,IAAI,4BAA4B;AAAA,EACzC;AAEA,QAAM,SAAS,aAAa;AACf,eAAA;AAEb,QAAM,cAAc,MAAM;AACxB,QAAI,eAAe,QAAQ;AACX,oBAAA;AACP,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EAAA;AAGH,QAAA,QAAQ,KAAK;AAEnB,QAAM,iBAAiB,OAAO;AAE9B,QAAM,kBAAoC;AAAA,IACxC,MAAM,OAAO;AAAA,IACb,aAAa,OAAO,eAAe;AAAA,IACnC,QAAQ;AAAA,EAAA;AAGN,MAAA;AAEJ,MAAI,OAAO,oBAAoB;AACP,0BAAA,MAAMC,4BAAqB,MAAM;AAAA,EAAA,OAClD;AACiB,0BAAA,MAAMC,8BAAsB,MAAM;AAAA,EAC1D;AAEA,QAAM,EAAE,eAAe,YAAY,iBAAA,IAAqB;AACxD,MAAI,kBAAkB,QAAW;AAC/B,QAAI,eAAe;AACf,QAAA,CAAC,OAAO,oBAAoB;AACd,sBAAA;AAAA,4BAA+BC,WAAAA,UAAU,IAAI,OAAO,eAAe,OAAO,KAAK;AAAA,oBAAuD,OAAO,eAAe,IAAIA,qBAAU,IAAI,OAAO,eAAe,OAAO,KAAK;AAAA,IAClO;AACM,UAAA,IAAI,MAAM,YAAY;AAAA,EAC9B;AAEM,QAAA,gBAAgBC,kBAAY,kBAAkB;AAAA,IAClD,CAAC,MAAO,EAAE,cAAc,MAAM,KAAK;AAAA,IACnC,CAAC,MAAM;;AAAA,qBAAE,cAAF,mBAAa,MAAM,KAAK;AAAA;AAAA,IAC/B,CAAC,MACC,EAAE,SAAS,MAAM,IAAI,OAAO,OAAO,OAAO,UAAU,KAAK,CAAC,IAAI,IAAI;AAAA,IACpE,CAAC,MACC,EAAE,SAAS;AAAA,MACT;AAAA,IAAA,IAEE,IACA;AAAA,IACN,CAAC,MACC,EAAE,SAAS,MAAM,IAAI,OAAO,OAAO,OAAO,UAAU,KAAK,CAAC,IAAI,KAAK;AAAA,IACrE,CAAC,MAAO;;AAAA,sBAAE,cAAF,mBAAa,SAAS,QAAO,KAAK;AAAA;AAAA,IAC1C,CAAC,MAAM,EAAE;AAAA,EACV,CAAA,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAID,WAAAA,UAAU,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AAEhE,QAAM,YAA8B,CAAA;AACpC,QAAM,oBAAkD,CAAA;AAIxD,QAAM,aAA+B,CAAA;AAK/B,QAAA,iBAAiB,OAAO,SAAqB;AACjD,QAAI,CAAC,MAAM;AAGT;AAAA,IACF;AAGA,UAAM,YAAYE,cAAG,aAAa,KAAK,UAAU,OAAO;AAExD,QAAI,CAAC,WAAW;AACd,YAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAMHF,qBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQxB,aAAO,IAAI,eAAe,KAAK,QAAQ,EAAE;AACtCE,oBAAA;AAAA,QACD,KAAK;AAAA,QACL,MAAMC,oBAAS,OAAO,UAAU,eAAe;AAAA,MAAA;AAAA,IAEnD;AAAA,EAAA;AAGF,QAAM,eAAe,aAAa;AAE5B,QAAA,aAAa,OAAO,SAAoB;;AAC5C,QAAI,cAAc,eAAe,YAAY,MAAM,KAAK,SAAS;AAGjE,SAAI,2CAAa,2BAAwB,iBAAY,aAAZ,mBAAsB,SAAQ;AAErE,YAAM,sBAAsB;AAAA,QAC1B,YAAY;AAAA,QACZ;AAAA,QACA,KAAK;AAAA,MAAA;AAEP,UAAI,qBAAqB;AACT,sBAAA;AAAA,MAChB;AAAA,IACF;AAEI,QAAA,kBAAkB,SAAS;AAE1B,SAAA,OAAO,kBAAkB,IAAI;AAElC,UAAM,cAAcC,MAAA,aAAa,KAAK,QAAQ,EAAE;AAE1C,UAAA,QAAQ,YAAY,MAAM,GAAG;AACnC,UAAM,mBAAmB,MAAM,MAAM,SAAS,CAAC,KAAK;AAEpD,SAAK,YACH,iBAAiB,WAAW,GAAG,KAC/B,uBAAuB,KAAK,gBAAgB;AAE9C,SAAK,cAAc;AAAA,MACjBC,MAAAA,kBAAkB,qBAAqB,KAAK,IAAI,CAAC,KAAK;AAAA,IAAA;AAIxD,QAAI,CAAC,KAAK,wBAAwB,CAAC,KAAK,WAAW;AACjD,YAAM,YAAYH,cAAG,aAAa,KAAK,UAAU,OAAO;AAExD,YAAM,mBAAmB;AAAA,UACvB,UAAK,cAAL,mBAAgB,WAAW,KAAK,UAAS;AAAA,MAAA;AAG3C,UAAI,WAAW;AAEf,UAAI,CAAC,WAAW;AACd,YAAI,KAAK,QAAQ;AACJ,qBAAA;AAAA,YACT;AAAA,YACA,6CAA6C,gBAAgB;AAAA,gCACzC,gBAAgB;AAAA;AAAA,UAAA,EAEpC,KAAK,MAAM;AAAA,QAEb,WAAA,KAAK,WACJ,CAAC,KAAK,eACL,CAAC,KAAK,oBACN,CAAC,KAAK,sBACN,CAAC,KAAK,UACR;AACW,qBAAA;AAAA,YACT;AAAA,YACA,yCAAyC,gBAAgB;AAAA,gCACrC,gBAAgB;AAAA;AAAA,UAAA,EAEpC,KAAK,MAAM;AAAA,QACf;AAAA,MAAA,OACK;AACL,mBAAW,UACR;AAAA,UACC;AAAA,UACA,CAAC,OAAO,IAAI,IAAI,OAAO,GAAG,EAAE,GAAG,gBAAgB,GAAG,EAAE;AAAA,QAAA,EAErD;AAAA,UACC;AAAA,UACA,CAAC,OAAO,IAAI,IAAI,IAAI,OAClB,GAAG,EAAE,GAAG,KAAK,SAAS,wBAAwB,iBAAiB,GAAG,EAAE;AAAA,QAAA,EAEvE;AAAA,UACC;AAAA,UACA,CAAC,OAAO,IAAI,IAAI,IAAI,OAClB,GAAG,KAAK,SAAS,wBAAwB,iBAAiB,GAAG,EAAE,GAAG,gBAAgB,GAAG,EAAE;AAAA,QAAA;AAAA,MAE/F;AAEM,YAAAI,MAAA;AAAA,QACJ,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,UACE,aAAa,MAAM;AACjB,mBAAO,IAAI,eAAe,KAAK,QAAQ,EAAE;AAAA,UAC3C;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AAEA,QACE,CAAC,KAAK,cACL,KAAK,YACJ,KAAK,eACL,KAAK,oBACL,KAAK,sBACL,KAAK,SACP;AACA,wBAAkB,KAAK,SAAU,IAC/B,kBAAkB,KAAK,SAAU,KAAK;AAExC,wBAAkB,KAAK,SAAU,EAC/B,KAAK,SACD,SACA,KAAK,WACH,WACA,KAAK,mBACH,mBACA,KAAK,qBACH,qBACA,WACZ,IAAI;AAEE,YAAA,cAAc,WAAW,KAAK,CAAC,MAAM,EAAE,cAAc,KAAK,SAAS;AAEzE,UAAI,CAAC,aAAa;AAChB,cAAM,WAAW;AAAA,UACf,GAAG;AAAA,UACH,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,aAAa;AAAA,UACb,kBAAkB;AAAA,UAClB,oBAAoB;AAAA,QAAA,CACrB;AAAA,MACH;AACA;AAAA,IACF;AAEA,UAAM,sBAAsB,KAAK,eAAe,IAAI,WAAW;AACzD,UAAA,eAAe,KAAK,WAAW,KAAK;AAC1C,SAAK,0BACH,KAAK,YAAY,eAAe,CAAC,qBAAqB;AACxD,QAAI,CAAC,KAAK,aAAa,KAAK,yBAAyB;AACnD,YAAM,kBAAkB,0BAA0B,KAAK,SAAS,KAAK;AAC/D,YAAA,qBAAqBC,0BAAoB,eAAe;AAE9D,YAAM,cAAc,WAAW;AAAA,QAC7B,CAAC,MAAM,EAAE,cAAc;AAAA,MAAA;AAGzB,UAAI,CAAC,aAAa;AAChB,cAAM,aAAa;AAAA,UACjB,GAAG;AAAA,UACH,MAAM,0BAA0B,KAAK,IAAI,KAAK;AAAA,UAC9C,UAAU,0BAA0B,KAAK,QAAQ,KAAK;AAAA,UACtD,UAAU,0BAA0B,KAAK,QAAQ,KAAK;AAAA,UACtD,WAAW;AAAA,UACX,cAAc;AAAA,UACd,WAAW;AAAA,UACX,UAAU;AAAA,UACV,sBAAsB;AAAA,UACtB,yBAAyB;AAAA,QAAA;AAGhB,mBAAA,WAAW,WAAW,YAAY,CAAA;AAClC,mBAAA,SAAS,KAAK,IAAI;AAE7B,aAAK,SAAS;AAEd,YAAI,KAAK,UAAU;AAEZ,eAAA,OAAO,kBAAkB,IAAI;AAAA,QACpC;AAEA,cAAM,WAAW,UAAU;AAAA,MAAA,OACtB;AACO,oBAAA,WAAW,YAAY,YAAY,CAAA;AACnC,oBAAA,SAAS,KAAK,IAAI;AAE9B,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ;AACX,UAAA,CAAC,KAAK,yBAAyB;AACjC,aAAK,OAAO,WAAW,KAAK,OAAO,YAAY;AAC1C,aAAA,OAAO,SAAS,KAAK,IAAI;AAAA,MAChC;AAAA,IAAA,OACK;AACL,gBAAU,KAAK,IAAI;AAAA,IACrB;AAEA,eAAW,KAAK,IAAI;AAAA,EAAA;AAGX,aAAA,QAAQ,cAAc,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG;AAC7D,UAAM,WAAW,IAAI;AAAA,EACvB;AAEA,QAAM,qBAAuC;AAAA,IAC3C,cAAc,OAAO,CAAC,MAAM,EAAE,UAAU;AAAA,EAAA;AAGpC,QAAA,gBAAgB,OAAO,SAAoB;;AAC/C,UAAM,YAAYL,cAAG,aAAa,KAAK,UAAU,OAAO;AAExD,UAAM,mBAAmB;AAAA,QACvB,UAAK,cAAL,mBAAgB,WAAW,KAAK,UAAS;AAAA,IAAA;AAG3C,QAAI,CAAC,WAAW;AACd,YAAM,WAAW;AAAA;AAAA;AAAA,2CAGoB,gBAAgB;AAAA;AAAA,oCAEvB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAM9C,aAAO,IAAI,eAAe,KAAK,QAAQ,EAAE;AACtCA,oBAAA;AAAA,QACD,KAAK;AAAA,QACL,MAAMC,oBAAS,OAAO,UAAU,eAAe;AAAA,MAAA;AAAA,IACjD,OACK;AACC,YAAAG,MAAA;AAAA,QACJ,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,UAAU;AAAA,UACR;AAAA,UACA,CAAC,GAAG,IAAI,IAAI,OAAO,GAAG,EAAE,GAAG,gBAAgB,GAAG,EAAE;AAAA,QAClD;AAAA,QACA;AAAA,UACE,aAAa,MAAM;AACjB,mBAAO,IAAI,eAAe,KAAK,QAAQ,EAAE;AAAA,UAC3C;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGF,aAAW,QAAQ,oBAAoB;AACrC,UAAM,cAAc,IAAI;AAAA,EAC1B;AAES,WAAA,qBAAqB,OAAyB,QAAQ,GAAW;AACxE,UAAM,WAAW,MAAM,IAAI,CAAC,SAAS;;AACnC,UAAI,KAAK,QAAQ;AACf;AAAA,MACF;AAEA,UAAI,KAAK,YAAY,GAAC,UAAK,aAAL,mBAAe,SAAQ;AAC3C;AAAA,MACF;AAEM,YAAA,QAAQ,GAAG,KAAK,YAAY;AAE9B,WAAA,UAAK,aAAL,mBAAe,QAAQ;AACzB,cAAM,eAAe,qBAAqB,KAAK,UAAU,QAAQ,CAAC;AAElE,cAAM,sBAAsB,iBACxB,KACA,aAAa,KAAK;AAAA,IAC1B,KAAK,SAAS,IAAI,CAAC,UAAU,GAAG,MAAM,YAAY,iBAAiB,iCAAiC,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAG7GE,cAAAA,YAAW,SAAS,KAAK,WAAW,iBAAiB,KAAK,KAAK,KAAK,UAAU;AAAA,IACxF,KAAK,SAAS,IAAI,CAAC,UAAU,GAAG,MAAM,YAAY,UAAU,iCAAiC,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAG5G,cAAM,oBAAoB,SAAS,KAAK,kBAAkB,KAAK,qBAAqB,KAAK;AAElF,eAAA;AAAA,UACL;AAAA,UACA;AAAA,UACAA;AAAAA,UACA;AAAA,QAAA,EACA,KAAK,MAAM;AAAA,MACf;AAEO,aAAA;AAAA,IAAA,CACR;AAED,WAAO,SAAS,OAAO,OAAO,EAAE,KAAK,MAAM;AAAA,EAC7C;AAEM,QAAA,0BAA0B,qBAAqB,SAAS;AAExD,QAAA,mBAAmBP,kBAAY,YAAY;AAAA,IAC/C,CAAC,MAAO;;AAAA,sBAAE,cAAF,mBAAa,SAAS,IAAID,WAAAA,UAAU,OAAM,KAAK;AAAA;AAAA,IACvD,CAAC,MAAM;;AAAA,qBAAE,cAAF,mBAAa,MAAM,KAAK;AAAA;AAAA,IAC/B,CAAC;;AAAO,sBAAE,cAAF,mBAAa,SAAS,OAAO,eAAc,KAAK;AAAA;AAAA,IACxD,CAAC,MAAM;AAAA,EAAA,CACR;AAEK,QAAA,UAAU,OAAO,QAAQ;AAAA,IAC7B,iBAAiB,iBAAiB,KAAK,CAAC,MAAM,EAAE,SAAS;AAAA,IACzD,QAAQ,iBAAiB;AAAA,MACvB,CAAC,SAAA;;AAAS,uCAAkB,KAAK,SAAU,MAAjC,mBAAoC;AAAA;AAAA,IAChD;AAAA,IACA,oBAAoB,iBAAiB;AAAA,MACnC,CAAC,SACC;;AAAA,wCAAkB,KAAK,SAAU,MAAjC,mBAAoC,gBACpC,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC,qBACpC,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC;AAAA;AAAA,IACxC;AAAA,EACD,CAAA,EACE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAClB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAElB,QAAM,oBAAoB,iBAAiB,OAAO,CAAC,MAAM,EAAE,SAAS;AAEpE,WAAS,cAAc,MAAiB;AAC/B,WAAAS,MAAA;AAAA,MACLC,MAAA;AAAA,QACE,KAAK;AAAA,UACH,KAAK,QAAQ,OAAO,kBAAkB;AAAA,UACtC,KAAK,QAAQ,OAAO,iBAAiB,KAAK,QAAQ;AAAA,QACpD;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IAAA;AAAA,EAEJ;AACA,QAAM,eAAe;AAAA,IACnB,GAAG,OAAO;AAAA,IACV;AAAA,IACA,QAAQ,SACJ,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IAC9B;AAAA,IACJ;AAAA,IACA;AAAA,MACE,yCAAyC,cAAc,aAAa,CAAC;AAAA,MACrE,GAAG,iBACA,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAC1B,IAAI,CAAC,SAAS;AACb,eAAO,qBACL,KAAK,YACP,oBAAoB,cAAc,IAAI,CAAC;AAAA,MAAA,CACxC;AAAA,IAAA,EACH,KAAK,IAAI;AAAA,IACX,kBAAkB,SAAS,6BAA6B;AAAA,IACxD,kBACG,IAAI,CAAC,SAAS;AACN,aAAA,SACL,KAAK,YACP,6BAA6B;AAAA,QAC3B,KAAK;AAAA,MACN,CAAA;AAAA,IAAA,CACF,EACA,KAAK,IAAI;AAAA,IACZ;AAAA,IACA,iBACG,IAAI,CAAC,SAAS;;AACb,YAAM,cAAa,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC;AACvD,YAAM,iBAAgB,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC;AAC1D,YAAM,sBACJ,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC;AACtC,YAAM,wBACJ,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC;AACtC,YAAM,qBAAoB,uBAAkB,KAAK,SAAU,MAAjC,mBAAoC;AAEvD,aAAA;AAAA,QACL,SAAS,KAAK,YAAY,WAAW,KAAK,YAAY;AAAA,YACpD;AAAA,UACA,KAAK,YACD,QAAQ,KAAK,IAAI,MACjB,UAAU,KAAK,WAAW;AAAA,UAC9B,2BAAyB,UAAK,WAAL,mBAAa,iBAAgB,MAAM;AAAA,UAE3D,OAAO,OAAO,EACd,KAAK,GAAG,CAAC;AAAA,WACX,iBAAiB,KAAK,QAAQ;AAAA,QAC/B,aACI,kDAAkDD,MAAA;AAAA,UAChDC,MAAA;AAAA,YACE,KAAK;AAAA,cACH,KAAK,QAAQ,OAAO,kBAAkB;AAAA,cACtC,KAAK,QAAQ,OAAO,iBAAiB,WAAW,QAAQ;AAAA,YAC1D;AAAA,YACA,OAAO;AAAA,UACT;AAAA,QAAA,CACD,qBACD;AAAA,QACJ,iBAAiB,sBAAsB,uBACnC;AAAA,gBAEE;AAAA,UACE,CAAC,aAAa,aAAa;AAAA,UAC3B,CAAC,kBAAkB,kBAAkB;AAAA,UACrC,CAAC,oBAAoB,oBAAoB;AAAA,QAAA,EAG1C,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAClB,IAAI,CAAC,MAAM;AACV,iBAAO,GACL,EAAE,CAAC,CACL,wCAAwCD,MAAA;AAAA,YACtCC,MAAA;AAAA,cACE,KAAK;AAAA,gBACH,KAAK,QAAQ,OAAO,kBAAkB;AAAA,gBACtC,KAAK,QAAQ,OAAO,iBAAiB,EAAE,CAAC,EAAG,QAAQ;AAAA,cACrD;AAAA,cACA,OAAO;AAAA,YACT;AAAA,UACD,CAAA,QAAQ,EAAE,CAAC,CAAC;AAAA,QAAA,CACd,EACA,KAAK,KAAK,CAAC;AAAA,kBAEd;AAAA,QACJ,oBACI,yBAAyBD,MAAA;AAAA,UACvBC,MAAA;AAAA,YACE,KAAK;AAAA,cACH,KAAK,QAAQ,OAAO,kBAAkB;AAAA,cACtC,KAAK;AAAA,gBACH,OAAO;AAAA,gBACP,kBAAkB;AAAA,cACpB;AAAA,YACF;AAAA,YACA,OAAO;AAAA,UACT;AAAA,QAAA,CACD,6BACD;AAAA,MAAA,EACJ,KAAK,EAAE;AAAA,IAAA,CACV,EACA,KAAK,MAAM;AAAA,IACd,GAAI,iBACA,CAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA;AAAA,MAEJ,WACC,IAAI,CAAC,cAAc;;AACZ,cAAA,CAAC,YAAY,OAAO,IAAI;AAAA,UAC5B,UAAU;AAAA,QAAA;AAGZ,eAAO,IAAI,UAAU;AAAA,iBACZ,OAAO;AAAA,mBACL,UAAU,SAAS,CAAC;AAAA,uBAChB,cAAc,SAAS,CAAC;AAAA,mCACZ,UAAU,YAAY;AAAA,gCAE7C,UAAU,0BACN,IAAG,eAAU,WAAV,mBAAkB,YAAY,YACjC,eAAU,WAAV,mBAAkB,gBAChB,GAAG,UAAU,OAAO,YAAY,WAChC,WACR;AAAA;AAAA,MAAA,CAEH,EACA,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,IAGT;AAAA,IACJ;AAAA,IACA;AAAA,IACA,GAAI,iBACA,CAAA,IACA;AAAA,MACE;AAAA,IACN,CAAC,GAAG,2BAA2B,UAAU,EAAE,QAAA,CAAS,EAAE;AAAA,QACtD,CAAC,CAAC,UAAU,SAAS,MAAM;AACzB,iBAAO,IAAI,QAAQ,aAAa,iCAAiC,SAAS,CAAC;AAAA,QAC7E;AAAA,MAAA,CACD;AAAA;AAAA,MAEO;AAAA,IACN,CAAC,GAAG,qBAAqB,UAAU,EAAE,QAAA,CAAS,EAAE,IAAI,CAAC,CAAC,IAAI,SAAS,MAAM;AACzE,eAAO,IAAI,EAAE,aAAa,iCAAiC,SAAS,CAAC;AAAA,MAAA,CACtE,CAAC;AAAA;AAAA,MAEM;AAAA;AAAA,IAEN,CAAC,GAAG,qBAAqB,UAAU,EAAE,QAAA,CAAS,EAAE,IAAI,CAAC,CAAC,IAAI,SAAS,MAAM;AACzE,eAAO,IAAI,EAAE,aAAa,iCAAiC,SAAS,CAAC;AAAA,MAAA,CACtE,CAAC;AAAA;AAAA,MAEM;AAAA;AAAA,eAEK,WAAW,SAAS,IAAI,CAAC,GAAG,2BAA2B,UAAU,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,aAAa,IAAI,QAAQ,GAAG,EAAE,KAAK,GAAG,IAAI,OAAO;AAAA;AAAA,QAExI,WAAW,SAAS,IAAI,CAAC,GAAG,qBAAqB,UAAU,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,IAAI,OAAO;AAAA,QAC/G,CAAC,cAAc,GAAG,CAAC,GAAG,qBAAqB,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA;AAAA,MAG9F;AAAA,IACN,UAAU,IAAI,CAAC,UAAU,GAAG,MAAM,YAAY,iBAAiB,iCAAiC,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA,IAE/G;AAAA,IACJ,0BAA0B,iBAAiB,KAAK,qBAAqB;AAAA,IACrE,UAAU,IAAI,CAAC,UAAU,GAAG,MAAM,YAAY,UAAU,iCAAiC,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA,IAE5G,yEAAyE,iBAAiB,KAAK,kCAAkC;AAAA,IACjI,GAAG,OAAO;AAAA,EAET,EAAA,OAAO,OAAO,EACd,KAAK,MAAM;AAEd,QAAM,sBAAsB,MAAM;AAChC,UAAM,iBAAiB;AAAA,MACrB,UAAU;AAAA,QACR,UAAU,cAAc;AAAA,QACxB,UAAU,UAAU;AAAA,UAClB,CAAC,MAAM,gCAAgC,EAAE,SAAS,EAAE,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,MACA,GAAG,OAAO;AAAA,QACR,WAAW,IAAI,CAAC,MAAM;;AACpB,gBAAM,CAAC,GAAG,OAAO,IAAI,gCAAgC,EAAE,SAAS;AAEzD,iBAAA;AAAA,YACL;AAAA,YACA;AAAA,cACE,UAAU,EAAE;AAAA,cACZ,UAAQ,OAAE,WAAF,mBAAU,aACd,gCAAgC,EAAE,OAAO,SAAS,EAAE,CAAC,IACrD;AAAA,cACJ,WAAU,OAAE,aAAF,mBAAY;AAAA,gBACpB,CAAC,eACC,gCAAgC,WAAW,SAAS,EAAE,CAAC;AAAA;AAAA,YAE7D;AAAA,UAAA;AAAA,QACF,CACD;AAAA,MACH;AAAA,IAAA;AAGF,WAAO,KAAK;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAGI,QAAA,yBAAyB,OAAO,4BAClC,eACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,IACpB;AAAA,EAAA,EACA,KAAK,IAAI;AAEX,MAAA,CAAC,cAAe;AAEpB,QAAM,2BAA2B,MAAMC,eACpC,SAAS,KAAK,QAAQ,OAAO,kBAAkB,GAAG,OAAO,EACzD,MAAM,CAAC,QAAQ;AACV,QAAA,IAAI,SAAS,UAAU;AAClB,aAAA;AAAA,IACT;AAEM,UAAA;AAAA,EAAA,CACP;AAEC,MAAA,CAAC,cAAe;AAGd,QAAAA,eAAI,MAAM,KAAK,QAAQ,KAAK,QAAQ,OAAO,kBAAkB,CAAC,GAAG;AAAA,IACrE,WAAW;AAAA,EAAA,CACZ;AAEG,MAAA,CAAC,cAAe;AAGpB,QAAM,uBAAuB,MAAML,MAAA;AAAA,IACjC,KAAK,QAAQ,OAAO,kBAAkB;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAa,MAAM;AACjB,eAAO,IAAI,eAAe,OAAO,kBAAkB,EAAE;AAAA,MACvD;AAAA,IACF;AAAA,EAAA;AAEE,MAAA,wBAAwB,CAAC,eAAe;AAC1C;AAAA,EACF;AAEO,SAAA;AAAA,IACL,eAAe,WAAW,WAAW,IAAI,UAAU,QAAQ,OACzD,KAAK,QAAQ,KACf;AAAA,EAAA;AAEJ;AAQA,SAAS,0BAA0B,GAAY;AAC7C,SAAO,uBAAG,WAAW,UAAU,IAAI,WAAW,WAAW;AAC3D;AAEA,SAAS,aAAa,GAAW;AACxB,SAAA,EAAE,QAAQ,sCAAsC,EAAE;AAC3D;AAQA,SAAS,kBAAkB,MAAiB;;AAC1C,SAAQ,KAAK,OAAO,KAAK,WACrB,UAAK,cAAL,mBAAgB,QAAQ,KAAK,OAAO,aAAa,IAAI,QAAO,MAC5D,KAAK;AACX;AAUgB,SAAA,0BAA0B,YAAoB,KAAa;AACnE,QAAA,WAAW,UAAU,MAAM,GAAG;AACpC,WAAS,IAAI;AACN,SAAA,SAAS,KAAK,GAAG;AAC1B;AAUA,SAAS,qBAAqB,YAAoB,KAAa;AACvD,QAAA,WAAW,UAAU,MAAM,GAAG;AAC9B,QAAA,cAAc,SAAS,OAAO,CAAC,YAAY,CAAC,QAAQ,WAAW,GAAG,CAAC;AAClE,SAAA,YAAY,KAAK,GAAG;AAC7B;AAEgB,SAAA,eACd,QACA,MACA,kBACkB;AACd,MAAA,CAAC,oBAAoB,qBAAqB,KAAK;AAC1C,WAAA;AAAA,EACT;AAEM,QAAA,cAAcL,kBAAY,QAAQ;AAAA,IACtC,CAAC,MAAM,EAAE,UAAW,SAAS;AAAA,IAC7B,CAAC,MAAM,EAAE;AAAA,EAAA,CACV,EAAE,OAAO,CAAC,MAAM,EAAE,cAAc,IAAID,qBAAU,EAAE;AAEjD,aAAW,SAAS,aAAa;AAC3B,QAAA,MAAM,cAAc,IAAK;AAG3B,QAAA,iBAAiB,WAAW,GAAG,MAAM,SAAS,GAAG,KACjD,MAAM,cAAc,kBACpB;AACO,aAAA;AAAA,IACT;AAAA,EACF;AAEM,QAAA,WAAW,iBAAiB,MAAM,GAAG;AAC3C,WAAS,IAAI;AACP,QAAA,kBAAkB,SAAS,KAAK,GAAG;AAElC,SAAA,eAAe,QAAQ,MAAM,eAAe;AACrD;AAKa,MAAA,mCAAmC,CAC9C,cACW;;AACJ,WAAA,eAAU,aAAV,mBAAoB,UACvB,GAAG,UAAU,YAAY,sBACzB,GAAG,UAAU,YAAY;AAC/B;AAKa,MAAA,6BAA6B,CACxC,eAC2B;AAC3B,SAAO,IAAI;AAAA,IACT,WAAW,IAAI,CAAC,cAAc,CAAC,cAAc,SAAS,GAAG,SAAS,CAAC;AAAA,EAAA;AAEvE;AAKa,MAAA,uBAAuB,CAClC,eAC2B;AAC3B,SAAO,IAAI;AAAA,IACT,6BAA6B,UAAU,EAAE,IAAI,CAAC,cAAc;AAAA,MAC1D,QAAQ,SAAS;AAAA,MACjB;AAAA,IAAA,CACD;AAAA,EAAA;AAEL;AAKa,MAAA,uBAAuB,CAClC,eAC2B;AAC3B,SAAO,IAAI;AAAA,IACT,WAAW,IAAI,CAAC,cAAc;AAC5B,YAAM,CAAC,GAAG,EAAE,IAAI,gCAAgC,UAAU,SAAS;AAC5D,aAAA,CAAC,IAAI,SAAS;AAAA,IAAA,CACtB;AAAA,EAAA;AAEL;AAKa,MAAA,gBAAgB,CAAC,cAAiC;AAC7D,QAAM,WAAW;AAAA,IACfK,MAAAA,kBAAkB,qBAAqB,UAAU,SAAS,CAAC,KAAK;AAAA,EAAA;AAGlE,SAAO,UAAU,gBAAgB,MAAM,WAAW,SAAS,QAAQ,OAAO,EAAE;AAC9E;AAKa,MAAA,YAAY,CAAC,cAAiC;;AAClD,SAAA,UAAU,gBAAgB,MAC7B,UAAU,gBACT,eAAU,gBAAV,mBAAuB,QAAQ,OAAO,QAAO;AACpD;AAKa,MAAA,UAAU,CAAC,cAAiC;AACjD,QAAA,WAAW,cAAc,SAAS;AAEpC,MAAA,aAAa,IAAY,QAAA;AAEtB,SAAA,SAAS,QAAQ,OAAO,EAAE;AACnC;AAKa,MAAA,+BAA+B,CAC1C,WACqB;AACd,SAAA,OAAO,OAAO,CAAC,UAAU;;AAC1B,SAAA,WAAM,aAAN,mBAAgB,KAAK,CAAC,UAAU,MAAM,gBAAgB,KAAa,QAAA;AAChE,WAAA;AAAA,EAAA,CACR;AACH;AAEA,SAAS,gCAAgC,UAAmB;AACpD,QAAA,aAAa,0BAA0B,QAAQ;AAC/C,QAAA,KAAK,aAAa,cAAc,EAAE;AAEjC,SAAA,CAAC,YAAY,EAAE;AACxB;AAEA,SAAS,oBAAoB,SAA2B;AAClD,MAAA,QAAQ,WAAW,GAAG;AACxB,WAAO;EACT;AAMA,QAAM,SAAS,QAAQ,IAAI,CAAC,MAAM;AAChC,UAAM,YAAYO,MAAA,oBAAoB,EAAE,aAAa,EAAE;AAChD,WAAA,EAAE,GAAG,GAAG;EAAU,CAC1B;AAID,QAAM,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS;AAC1C,QAAA,mBAAmB,IAAI,IAAI,UAAU;AACvC,MAAA,WAAW,WAAW,iBAAiB,MAAM;AAC/C,UAAM,sBAAsB,WAAW;AAAA,MACrC,CAAC,GAAG,MAAM,WAAW,QAAQ,CAAC,MAAM;AAAA,IAAA;AAEtC,UAAM,mBAAmB,OACtB,OAAO,CAAC,MAAM,oBAAoB,SAAS,EAAE,SAAS,CAAC,EACvD,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE;AAC7B,UAAM,eAAe,4EAA4E,oBAAoB,SAAS,IAAI,MAAM,EAAE,KAAK,oBAC5I,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EACnB,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,GAEO,iBAAiB,KAAK,KAAK,CAAC;AAAA;AAC1C,UAAA,IAAI,MAAM,YAAY;AAAA,EAC9B;AAEO,SAAA;AACT;AAegB,SAAA,qCACd,KACA,QACiC;AAC3B,QAAA,YAAYC,gCAA0B,GAAG;AAE/C,QAAM,QAAQ,UACX,WAAW,KAAK,GAAG,EACnB,MAAM,GAAG,EACT,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,MAAM,OAAO,UAAU;AAC/C,QAAM,WAA4C,MAAM,IAAI,CAAC,SAAS;AAChE,QAAA,KAAK,WAAW,GAAG,GAAG;AACxB,UAAI,SAAS,KAAK;AAChB,eAAO,EAAE,OAAO,MAAM,MAAM,QAAQ;AAAA,MACtC;AAEK,WAAA,WAAW,KAAK,EAAE;AACvB,aAAO,EAAE,OAAO,MAAM,MAAM,QAAQ;AAAA,IACtC;AAEA,WAAO,EAAE,OAAO,MAAM,MAAM,OAAO;AAAA,EAAA,CACpC;AAEM,SAAA;AACT;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"generator.cjs","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fs from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport * as prettier from 'prettier'\nimport {\n determineInitialRoutePath,\n logging,\n multiSortBy,\n removeExt,\n removeTrailingSlash,\n removeUnderscores,\n replaceBackslash,\n routePathToVariable,\n trimPathLeft,\n writeIfDifferent,\n} from './utils'\nimport { getRouteNodes as physicalGetRouteNodes } from './filesystem/physical/getRouteNodes'\nimport { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport type { GetRouteNodesResult, RouteNode } from './types'\nimport type { Config } from './config'\n\nlet latestTask = 0\nconst routeGroupPatternRegex = /\\(.+\\)/g\nconst possiblyNestedRouteGroupPatternRegex = /\\([^/]+\\)\\/?/g\n\nlet isFirst = false\nlet skipMessage = false\n\ntype RouteSubNode = {\n component?: RouteNode\n errorComponent?: RouteNode\n pendingComponent?: RouteNode\n loader?: RouteNode\n lazy?: RouteNode\n}\n\nexport async function generator(config: Config) {\n const logger = logging({ disabled: config.disableLogging })\n logger.log('')\n\n if (!isFirst) {\n logger.log('♻️ Generating routes...')\n isFirst = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n logger.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n\n const TYPES_DISABLED = config.disableTypes\n\n const prettierOptions: prettier.Options = {\n semi: config.semicolons,\n singleQuote: config.quoteStyle === 'single',\n parser: 'typescript',\n }\n\n let getRouteNodesResult: GetRouteNodesResult\n\n if (config.virtualRouteConfig) {\n getRouteNodesResult = await virtualGetRouteNodes(config)\n } else {\n getRouteNodesResult = await physicalGetRouteNodes(config)\n }\n\n const { rootRouteNode, routeNodes: beforeRouteNodes } = getRouteNodesResult\n if (rootRouteNode === undefined) {\n let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`\n if (!config.virtualRouteConfig) {\n errorMessage += `\\nMake sure that you add a \"${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\" file to your routes directory.\\nAdd the file in: \"${config.routesDirectory}/${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\"`\n }\n throw new Error(errorMessage)\n }\n\n const preRouteNodes = multiSortBy(beforeRouteNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.indexToken}[.]`)) ? 1 : -1,\n (d) =>\n d.filePath.match(\n /[./](component|errorComponent|pendingComponent|loader|lazy)[.]/,\n )\n ? 1\n : -1,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.routeToken}[.]`)) ? -1 : 1,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => ![`/${rootPathId}`].includes(d.routePath || ''))\n\n const routeTree: Array<RouteNode> = []\n const routePiecesByPath: Record<string, RouteSubNode> = {}\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n const routeNodes: Array<RouteNode> = []\n\n // the handleRootNode function is not being collapsed into the handleNode function\n // because it requires only a subset of the logic that the handleNode function requires\n // and it's easier to read and maintain this way\n const handleRootNode = async (node?: RouteNode) => {\n if (!node) {\n // currently this is not being handled, but it could be in the future\n // for example to handle a virtual root route\n return\n }\n\n // from here on, we are only handling the root node that's present in the file system\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n if (!routeCode) {\n const replaced = `import * as React from 'react';\nimport { Outlet, createRootRoute } from '@tanstack/react-router';\n\nexport const Route = createRootRoute({\n component: () => (\n <React.Fragment>\n <div>Hello \"${rootPathId}\"!</div>\n <Outlet />\n </React.Fragment>\n ),\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n }\n }\n\n await handleRootNode(rootRouteNode)\n\n const handleNode = async (node: RouteNode) => {\n let parentRoute = hasParentRoute(routeNodes, node, node.routePath)\n\n // if the parent route is a virtual parent route, we need to find the real parent route\n if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {\n // only if this sub-parent route returns a valid parent route, we use it, if not leave it as it\n const possibleParentRoute = hasParentRoute(\n parentRoute.children,\n node,\n node.routePath,\n )\n if (possibleParentRoute) {\n parentRoute = possibleParentRoute\n }\n }\n\n if (parentRoute) node.parent = parentRoute\n\n node.path = determineNodePath(node)\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath.split('/')\n const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n\n node.isNonPath =\n lastRouteSegment.startsWith('_') ||\n routeGroupPatternRegex.test(lastRouteSegment)\n\n node.cleanedPath = removeGroups(\n removeUnderscores(removeLayoutSegments(node.path)) ?? '',\n )\n\n // Ensure the boilerplate for the route exists, which can be skipped for virtual parent routes and virtual routes\n if (!node.isVirtualParentRoute && !node.isVirtual) {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n let replaced = routeCode\n\n if (!routeCode) {\n if (node.isLazy) {\n replaced = [\n `import { createLazyFileRoute } from '@tanstack/react-router'`,\n `export const Route = createLazyFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n } else if (\n node.isRoute ||\n (!node.isComponent &&\n !node.isErrorComponent &&\n !node.isPendingComponent &&\n !node.isLoader)\n ) {\n replaced = [\n `import { createFileRoute } from '@tanstack/react-router'`,\n `export const Route = createFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n }\n } else {\n replaced = routeCode\n .replace(\n /(FileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3) => `${p1}${escapedRoutePath}${p3}`,\n )\n .replace(\n /(import\\s*\\{.*)(create(Lazy)?FileRoute)(.*\\}\\s*from\\s*['\"]@tanstack\\/react-router['\"])/gs,\n (match, p1, p2, p3, p4) =>\n `${p1}${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p4}`,\n )\n .replace(\n /create(Lazy)?FileRoute(\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3, p4) =>\n `${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p2}${escapedRoutePath}${p4}`,\n )\n }\n\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n replaced,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n\n if (\n !node.isVirtual &&\n (node.isLoader ||\n node.isComponent ||\n node.isErrorComponent ||\n node.isPendingComponent ||\n node.isLazy)\n ) {\n routePiecesByPath[node.routePath!] =\n routePiecesByPath[node.routePath!] || {}\n\n routePiecesByPath[node.routePath!]![\n node.isLazy\n ? 'lazy'\n : node.isLoader\n ? 'loader'\n : node.isErrorComponent\n ? 'errorComponent'\n : node.isPendingComponent\n ? 'pendingComponent'\n : 'component'\n ] = node\n\n const anchorRoute = routeNodes.find((d) => d.routePath === node.routePath)\n\n if (!anchorRoute) {\n await handleNode({\n ...node,\n isVirtual: true,\n isLazy: false,\n isLoader: false,\n isComponent: false,\n isErrorComponent: false,\n isPendingComponent: false,\n })\n }\n return\n }\n\n const cleanedPathIsEmpty = (node.cleanedPath || '').length === 0\n const nonPathRoute = node.isRoute && node.isNonPath\n node.isVirtualParentRequired =\n node.isLayout || nonPathRoute ? !cleanedPathIsEmpty : false\n if (!node.isVirtual && node.isVirtualParentRequired) {\n const parentRoutePath = removeLastSegmentFromPath(node.routePath) || '/'\n const parentVariableName = routePathToVariable(parentRoutePath)\n\n const anchorRoute = routeNodes.find(\n (d) => d.routePath === parentRoutePath,\n )\n\n if (!anchorRoute) {\n const parentNode = {\n ...node,\n path: removeLastSegmentFromPath(node.path) || '/',\n filePath: removeLastSegmentFromPath(node.filePath) || '/',\n fullPath: removeLastSegmentFromPath(node.fullPath) || '/',\n routePath: parentRoutePath,\n variableName: parentVariableName,\n isVirtual: true,\n isLayout: false,\n isVirtualParentRoute: true,\n isVirtualParentRequired: false,\n }\n\n parentNode.children = parentNode.children ?? []\n parentNode.children.push(node)\n\n node.parent = parentNode\n\n if (node.isLayout) {\n // since `node.path` is used as the `id` on the route definition, we need to update it\n node.path = determineNodePath(node)\n }\n\n await handleNode(parentNode)\n } else {\n anchorRoute.children = anchorRoute.children ?? []\n anchorRoute.children.push(node)\n\n node.parent = anchorRoute\n }\n }\n\n if (node.parent) {\n if (!node.isVirtualParentRequired) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n }\n } else {\n routeTree.push(node)\n }\n\n routeNodes.push(node)\n }\n\n for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {\n await handleNode(node)\n }\n checkRouteFullPathUniqueness(\n preRouteNodes.filter(\n (d) => !d.isAPIRoute && d.children === undefined && d.isLazy !== true,\n ),\n config,\n )\n\n const startAPIRouteNodes: Array<RouteNode> = checkStartAPIRoutes(\n preRouteNodes.filter((d) => d.isAPIRoute),\n config,\n )\n\n const handleAPINode = async (node: RouteNode) => {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n if (!routeCode) {\n const replaced = `import { json } from '@tanstack/start'\nimport { createAPIFileRoute } from '@tanstack/start/api'\n\nexport const Route = createAPIFileRoute('${escapedRoutePath}')({\n GET: ({ request, params }) => {\n return json({ message: 'Hello ${escapedRoutePath}' })\n },\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n } else {\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n routeCode.replace(\n /(createAPIFileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (_, p1, __, p3) => `${p1}${escapedRoutePath}${p3}`,\n ),\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n }\n\n for (const node of startAPIRouteNodes) {\n await handleAPINode(node)\n }\n\n function buildRouteTreeConfig(nodes: Array<RouteNode>, depth = 1): string {\n const children = nodes.map((node) => {\n if (node.isRoot) {\n return\n }\n\n if (node.isLayout && !node.children?.length) {\n return\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = buildRouteTreeConfig(node.children, depth + 1)\n\n const childrenDeclaration = TYPES_DISABLED\n ? ''\n : `interface ${route}Children {\n ${node.children.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const children = `const ${route}Children${TYPES_DISABLED ? '' : `: ${route}Children`} = {\n ${node.children.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const routeWithChildren = `const ${route}WithChildren = ${route}._addFileChildren(${route}Children)`\n\n return [\n childConfigs,\n childrenDeclaration,\n children,\n routeWithChildren,\n ].join('\\n\\n')\n }\n\n return undefined\n })\n\n return children.filter(Boolean).join('\\n\\n')\n }\n\n const routeConfigChildrenText = buildRouteTreeConfig(routeTree)\n\n const sortedRouteNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(config.indexToken) ? -1 : 1),\n (d) => d,\n ])\n\n const imports = Object.entries({\n createFileRoute: sortedRouteNodes.some((d) => d.isVirtual),\n lazyFn: sortedRouteNodes.some(\n (node) => routePiecesByPath[node.routePath!]?.loader,\n ),\n lazyRouteComponent: sortedRouteNodes.some(\n (node) =>\n routePiecesByPath[node.routePath!]?.component ||\n routePiecesByPath[node.routePath!]?.errorComponent ||\n routePiecesByPath[node.routePath!]?.pendingComponent,\n ),\n })\n .filter((d) => d[1])\n .map((d) => d[0])\n\n const virtualRouteNodes = sortedRouteNodes.filter((d) => d.isVirtual)\n\n function getImportPath(node: RouteNode) {\n return replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n config.addExtensions,\n ),\n )\n }\n const routeImports = [\n ...config.routeTreeFileHeader,\n '// This file is auto-generated by TanStack Router',\n imports.length\n ? `import { ${imports.join(', ')} } from '@tanstack/react-router'\\n`\n : '',\n '// Import Routes',\n [\n `import { Route as rootRoute } from './${getImportPath(rootRouteNode)}'`,\n ...sortedRouteNodes\n .filter((d) => !d.isVirtual)\n .map((node) => {\n return `import { Route as ${\n node.variableName\n }Import } from './${getImportPath(node)}'`\n }),\n ].join('\\n'),\n virtualRouteNodes.length ? '// Create Virtual Routes' : '',\n virtualRouteNodes\n .map((node) => {\n return `const ${\n node.variableName\n }Import = createFileRoute('${removeTrailingUnderscores(\n node.routePath,\n )}')()`\n })\n .join('\\n'),\n '// Create/Update Routes',\n sortedRouteNodes\n .map((node) => {\n const loaderNode = routePiecesByPath[node.routePath!]?.loader\n const componentNode = routePiecesByPath[node.routePath!]?.component\n const errorComponentNode =\n routePiecesByPath[node.routePath!]?.errorComponent\n const pendingComponentNode =\n routePiecesByPath[node.routePath!]?.pendingComponent\n const lazyComponentNode = routePiecesByPath[node.routePath!]?.lazy\n\n return [\n `const ${node.variableName}Route = ${node.variableName}Import.update({\n ${[\n node.isNonPath\n ? `id: '${node.path}'`\n : `path: '${node.cleanedPath}'`,\n `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,\n ]\n .filter(Boolean)\n .join(',')}\n }${TYPES_DISABLED ? '' : 'as any'})`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n config.addExtensions,\n ),\n )}'), 'loader') })`\n : '',\n componentNode || errorComponentNode || pendingComponentNode\n ? `.update({\n ${(\n [\n ['component', componentNode],\n ['errorComponent', errorComponentNode],\n ['pendingComponent', pendingComponentNode],\n ] as const\n )\n .filter((d) => d[1])\n .map((d) => {\n return `${\n d[0]\n }: lazyRouteComponent(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, d[1]!.filePath),\n ),\n config.addExtensions,\n ),\n )}'), '${d[0]}')`\n })\n .join('\\n,')}\n })`\n : '',\n lazyComponentNode\n ? `.lazy(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n lazyComponentNode.filePath,\n ),\n ),\n config.addExtensions,\n ),\n )}').then((d) => d.Route))`\n : '',\n ].join('')\n })\n .join('\\n\\n'),\n ...(TYPES_DISABLED\n ? []\n : [\n '// Populate the FileRoutesByPath interface',\n `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n const filePathId = getFilePathIdFromPath(routeNode.routePath)\n\n return `'${filePathId}': {\n id: '${filePathId}'\n path: '${inferPath(routeNode)}'\n fullPath: '${inferFullPath(routeNode)}'\n preLoaderRoute: typeof ${routeNode.variableName}Import\n parentRoute: typeof ${\n routeNode.isVirtualParentRequired\n ? `${routeNode.parent?.variableName}Route`\n : routeNode.parent?.variableName\n ? `${routeNode.parent.variableName}Import`\n : 'rootRoute'\n }\n }`\n })\n .join('\\n')}\n }\n}`,\n ]),\n '// Create and export the route tree',\n routeConfigChildrenText,\n ...(TYPES_DISABLED\n ? []\n : [\n `export interface FileRoutesByFullPath {\n ${[...createRouteNodesByFullPath(routeNodes).entries()].map(\n ([fullPath, routeNode]) => {\n return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n },\n )}\n}`,\n `export interface FileRoutesByTo {\n ${[...createRouteNodesByTo(routeNodes).entries()].map(([to, routeNode]) => {\n return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesById {\n '__root__': typeof rootRoute,\n ${[...createRouteNodesById(routeNodes).entries()].map(([id, routeNode]) => {\n return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRouteTypes {\n fileRoutesByFullPath: FileRoutesByFullPath\n fullPaths: ${routeNodes.length > 0 ? [...createRouteNodesByFullPath(routeNodes).keys()].map((fullPath) => `'${fullPath}'`).join('|') : 'never'}\n fileRoutesByTo: FileRoutesByTo\n to: ${routeNodes.length > 0 ? [...createRouteNodesByTo(routeNodes).keys()].map((to) => `'${to}'`).join('|') : 'never'}\n id: ${[`'__root__'`, ...[...createRouteNodesById(routeNodes).keys()].map((id) => `'${id}'`)].join('|')}\n fileRoutesById: FileRoutesById\n}`,\n `export interface RootRouteChildren {\n ${routeTree.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n ]),\n `const rootRouteChildren${TYPES_DISABLED ? '' : ': RootRouteChildren'} = {\n ${routeTree.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n `export const routeTree = rootRoute._addFileChildren(rootRouteChildren)${TYPES_DISABLED ? '' : '._addFileTypes<FileRouteTypes>()'}`,\n ...config.routeTreeFileFooter,\n ]\n .filter(Boolean)\n .join('\\n\\n')\n\n const createRouteManifest = () => {\n const routesManifest = {\n __root__: {\n filePath: rootRouteNode.filePath,\n children: routeTree.map((d) => getFilePathIdFromPath(d.routePath)),\n },\n ...Object.fromEntries(\n routeNodes.map((d) => {\n const filePathId = getFilePathIdFromPath(d.routePath)\n\n return [\n filePathId,\n {\n filePath: d.filePath,\n parent: d.parent?.routePath\n ? getFilePathIdFromPath(d.parent.routePath)\n : undefined,\n children: d.children?.map((childRoute) =>\n getFilePathIdFromPath(childRoute.routePath),\n ),\n },\n ]\n }),\n ),\n }\n\n return JSON.stringify(\n {\n routes: routesManifest,\n },\n null,\n 2,\n )\n }\n\n const routeConfigFileContent = config.disableManifestGeneration\n ? routeImports\n : [\n routeImports,\n '\\n',\n '/* ROUTE_MANIFEST_START',\n createRouteManifest(),\n 'ROUTE_MANIFEST_END */',\n ].join('\\n')\n\n if (!checkLatest()) return\n\n const existingRouteTreeContent = await fsp\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return ''\n }\n\n throw err\n })\n\n if (!checkLatest()) return\n\n // Ensure the directory exists\n await fsp.mkdir(path.dirname(path.resolve(config.generatedRouteTree)), {\n recursive: true,\n })\n\n if (!checkLatest()) return\n\n // Write the route tree file, if it has changed\n const routeTreeWriteResult = await writeIfDifferent(\n path.resolve(config.generatedRouteTree),\n prettierOptions,\n existingRouteTreeContent,\n routeConfigFileContent,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${config.generatedRouteTree}`)\n },\n },\n )\n if (routeTreeWriteResult && !checkLatest()) {\n return\n }\n\n logger.log(\n `✅ Processed ${routeNodes.length === 1 ? 'route' : 'routes'} in ${\n Date.now() - start\n }ms`,\n )\n}\n\nfunction removeTrailingUnderscores(s?: string) {\n return s?.replaceAll(/(_$)/gi, '').replaceAll(/(_\\/)/gi, '/')\n}\n\nfunction removeGroups(s: string) {\n return s.replace(possiblyNestedRouteGroupPatternRegex, '')\n}\n\n/**\n * The `node.path` is used as the `id` in the route definition.\n * This function checks if the given node has a parent and if so, it determines the correct path for the given node.\n * @param node - The node to determine the path for.\n * @returns The correct path for the given node.\n */\nfunction determineNodePath(node: RouteNode) {\n return (node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath ?? '', '') || '/'\n : node.routePath)\n}\n\n/**\n * Removes the last segment from a given path. Segments are considered to be separated by a '/'.\n *\n * @param {string} routePath - The path from which to remove the last segment. Defaults to '/'.\n * @returns {string} The path with the last segment removed.\n * @example\n * removeLastSegmentFromPath('/workspace/_auth/foo') // '/workspace/_auth'\n */\nexport function removeLastSegmentFromPath(routePath: string = '/'): string {\n const segments = routePath.split('/')\n segments.pop() // Remove the last segment\n return segments.join('/')\n}\n\n/**\n * Removes all segments from a given path that start with an underscore ('_').\n *\n * @param {string} routePath - The path from which to remove segments. Defaults to '/'.\n * @returns {string} The path with all underscore-prefixed segments removed.\n * @example\n * removeLayoutSegments('/workspace/_auth/foo') // '/workspace/foo'\n */\nfunction removeLayoutSegments(routePath: string = '/'): string {\n const segments = routePath.split('/')\n const newSegments = segments.filter((segment) => !segment.startsWith('_'))\n return newSegments.join('/')\n}\n\nexport function hasParentRoute(\n routes: Array<RouteNode>,\n node: RouteNode,\n routePathToCheck: string | undefined,\n): RouteNode | null {\n if (!routePathToCheck || routePathToCheck === '/') {\n return null\n }\n\n const sortedNodes = multiSortBy(routes, [\n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue\n\n if (\n routePathToCheck.startsWith(`${route.routePath}/`) &&\n route.routePath !== routePathToCheck\n ) {\n return route\n }\n }\n\n const segments = routePathToCheck.split('/')\n segments.pop() // Remove the last segment\n const parentRoutePath = segments.join('/')\n\n return hasParentRoute(routes, node, parentRoutePath)\n}\n\n/**\n * Gets the final variable name for a route\n */\nexport const getResolvedRouteNodeVariableName = (\n routeNode: RouteNode,\n): string => {\n return routeNode.children?.length\n ? `${routeNode.variableName}RouteWithChildren`\n : `${routeNode.variableName}Route`\n}\n\n/**\n * Creates a map from fullPath to routeNode\n */\nexport const createRouteNodesByFullPath = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => [inferFullPath(routeNode), routeNode]),\n )\n}\n\n/**\n * Create a map from 'to' to a routeNode\n */\nexport const createRouteNodesByTo = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n dedupeBranchesAndIndexRoutes(routeNodes).map((routeNode) => [\n inferTo(routeNode),\n routeNode,\n ]),\n )\n}\n\n/**\n * Create a map from 'id' to a routeNode\n */\nexport const createRouteNodesById = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => {\n const id = getFilePathIdFromPath(routeNode.routePath)\n return [id, routeNode]\n }),\n )\n}\n\n/**\n * Infers the full path for use by TS\n */\nexport const inferFullPath = (routeNode: RouteNode): string => {\n const fullPath = removeGroups(\n removeUnderscores(removeLayoutSegments(routeNode.routePath)) ?? '',\n )\n\n return routeNode.cleanedPath === '/' ? fullPath : fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Infers the path for use by TS\n */\nexport const inferPath = (routeNode: RouteNode): string => {\n return routeNode.cleanedPath === '/'\n ? routeNode.cleanedPath\n : (routeNode.cleanedPath?.replace(/\\/$/, '') ?? '')\n}\n\n/**\n * Infers to path\n */\nexport const inferTo = (routeNode: RouteNode): string => {\n const fullPath = inferFullPath(routeNode)\n\n if (fullPath === '/') return fullPath\n\n return fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Dedupes branches and index routes\n */\nexport const dedupeBranchesAndIndexRoutes = (\n routes: Array<RouteNode>,\n): Array<RouteNode> => {\n return routes.filter((route) => {\n if (route.children?.find((child) => child.cleanedPath === '/')) return false\n return true\n })\n}\n\nfunction getFilePathIdFromPath(pathname?: string) {\n const filePathId = removeTrailingUnderscores(pathname)\n return filePathId ?? ''\n}\n\nfunction checkUnique<TElement>(routes: Array<TElement>, key: keyof TElement) {\n // Check no two routes have the same `key`\n // if they do, throw an error with the conflicting filePaths\n const keys = routes.map((d) => d[key])\n const uniqueKeys = new Set(keys)\n if (keys.length !== uniqueKeys.size) {\n const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i)\n const conflictingFiles = routes.filter((d) =>\n duplicateKeys.includes(d[key]),\n )\n return conflictingFiles\n }\n return undefined\n}\n\nfunction checkRouteFullPathUniqueness(\n _routes: Array<RouteNode>,\n config: Config,\n) {\n const routes = _routes.map((d) => {\n const inferredFullPath = inferFullPath(d)\n return { ...d, inferredFullPath }\n })\n\n const conflictingFiles = checkUnique(routes, 'inferredFullPath')\n\n if (conflictingFiles !== undefined) {\n const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles\n .map((p) => `\"${p.inferredFullPath}\"`)\n .join(', ')}.\nPlease ensure each route has a unique full path.\nConflicting files: \\n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\\n ')}\\n`\n throw new Error(errorMessage)\n }\n}\n\nfunction checkStartAPIRoutes(_routes: Array<RouteNode>, config: Config) {\n if (_routes.length === 0) {\n return []\n }\n\n // Make sure these are valid URLs\n // Route Groups and Layout Routes aren't being removed since\n // you may want to have an API route that starts with an underscore\n // or be wrapped in parentheses\n const routes = _routes.map((d) => {\n const routePath = removeTrailingSlash(d.routePath ?? '')\n return { ...d, routePath }\n })\n\n const conflictingFiles = checkUnique(routes, 'routePath')\n\n if (conflictingFiles !== undefined) {\n const errorMessage = `Conflicting configuration paths were found for the following API route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles\n .map((p) => `\"${p}\"`)\n .join(', ')}.\n Please ensure each API route has a unique route path.\nConflicting files: \\n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\\n ')}\\n`\n throw new Error(errorMessage)\n }\n\n return routes\n}\n\nexport type StartAPIRoutePathSegment = {\n value: string\n type: 'path' | 'param' | 'splat'\n}\n\n/**\n * This function takes in a path in the format accepted by TanStack Router\n * and returns an array of path segments that can be used to generate\n * the pathname of the TanStack Start API route.\n *\n * @param src\n * @returns\n */\nexport function startAPIRouteSegmentsFromTSRFilePath(\n src: string,\n config: Config,\n): Array<StartAPIRoutePathSegment> {\n const routePath = determineInitialRoutePath(src)\n\n const parts = routePath\n .replaceAll('.', '/')\n .split('/')\n .filter((p) => !!p && p !== config.indexToken)\n const segments: Array<StartAPIRoutePathSegment> = parts.map((part) => {\n if (part.startsWith('$')) {\n if (part === '$') {\n return { value: part, type: 'splat' }\n }\n\n part.replaceAll('$', '')\n return { value: part, type: 'param' }\n }\n\n return { value: part, type: 'path' }\n })\n\n return segments\n}\n"],"names":["logging","virtualGetRouteNodes","physicalGetRouteNodes","rootPathId","multiSortBy","fs","prettier","trimPathLeft","removeUnderscores","writeIfDifferent","routePathToVariable","children","replaceBackslash","removeExt","fsp","removeTrailingSlash","determineInitialRoutePath"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport type {
|
|
1
|
+
{"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport type { VirtualRouteNode } from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nfunction ensureLeadingUnderScore(id: string) {\n if (id.startsWith('_')) {\n return id\n }\n return `_${id}`\n}\n\nfunction flattenTree(node: RouteNode): Array<RouteNode> {\n const result = [node]\n\n if (node.children) {\n for (const child of node.children) {\n result.push(...flattenTree(child))\n }\n }\n delete node.children\n\n return result\n}\n\nexport async function getRouteNodes(\n tsrConfig: Config,\n): Promise<GetRouteNodesResult> {\n const fullDir = resolve(tsrConfig.routesDirectory)\n if (tsrConfig.virtualRouteConfig === undefined) {\n throw new Error(`virtualRouteConfig is undefined`)\n }\n const children = await getRouteNodesRecursive(\n tsrConfig,\n fullDir,\n tsrConfig.virtualRouteConfig.children,\n )\n const allNodes = flattenTree({\n children,\n filePath: tsrConfig.virtualRouteConfig.file,\n fullPath: join(fullDir, tsrConfig.virtualRouteConfig.file),\n variableName: 'rootRoute',\n routePath: '/',\n isRoot: true,\n })\n\n const rootRouteNode = allNodes[0]\n const routeNodes = allNodes.slice(1)\n\n return { rootRouteNode, routeNodes }\n}\n\nexport async function getRouteNodesRecursive(\n tsrConfig: Config,\n fullDir: string,\n nodes?: Array<VirtualRouteNode>,\n parent?: RouteNode,\n): Promise<Array<RouteNode>> {\n if (nodes === undefined) {\n return []\n }\n const children = await Promise.all(\n nodes.map(async (node) => {\n if (node.type === 'physical') {\n const { routeNodes } = await getRouteNodesPhysical({\n ...tsrConfig,\n routesDirectory: resolve(fullDir, node.directory),\n })\n routeNodes.forEach((subtreeNode) => {\n subtreeNode.variableName = routePathToVariable(\n `${node.pathPrefix}/${removeExt(subtreeNode.filePath)}`,\n )\n subtreeNode.routePath = `${parent?.routePath ?? ''}${node.pathPrefix}${subtreeNode.routePath}`\n subtreeNode.filePath = `${node.directory}/${subtreeNode.filePath}`\n })\n return routeNodes\n }\n\n function getFile(file: string) {\n const filePath = file.split('/').join(path.sep)\n const variableName = routePathToVariable(removeExt(filePath))\n const fullPath = join(fullDir, filePath)\n return { filePath, variableName, fullPath }\n }\n const parentRoutePath = removeTrailingSlash(parent?.routePath ?? '/')\n const isLayout = node.type === 'layout'\n switch (node.type) {\n case 'index': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n const routePath = `${parentRoutePath}/`\n return {\n filePath,\n fullPath,\n variableName,\n routePath,\n isLayout,\n } satisfies RouteNode\n }\n\n case 'route': {\n const lastSegment = node.path\n let routeNode: RouteNode\n\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n if (node.file) {\n const { filePath, variableName, fullPath } = getFile(node.file)\n routeNode = {\n filePath,\n fullPath,\n variableName,\n routePath,\n isLayout,\n }\n } else {\n routeNode = {\n filePath: '',\n fullPath: '',\n variableName: '',\n routePath,\n isLayout,\n isVirtual: true,\n }\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n }\n return routeNode\n }\n case 'layout': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n\n if (node.id !== undefined) {\n node.id = ensureLeadingUnderScore(node.id)\n } else {\n const baseName = path.basename(filePath)\n const fileNameWithoutExt = path.parse(baseName).name\n node.id = ensureLeadingUnderScore(fileNameWithoutExt)\n }\n const lastSegment = node.id\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n\n const routeNode: RouteNode = {\n fullPath,\n isLayout,\n filePath,\n variableName,\n routePath,\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n }\n return routeNode\n }\n }\n }),\n )\n return children.flat()\n}\n"],"names":["getRouteNodesPhysical","children"],"mappings":"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"}
|
package/dist/esm/generator.js
CHANGED
|
@@ -234,8 +234,15 @@ export const Route = createRootRoute({
|
|
|
234
234
|
for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {
|
|
235
235
|
await handleNode(node);
|
|
236
236
|
}
|
|
237
|
+
checkRouteFullPathUniqueness(
|
|
238
|
+
preRouteNodes.filter(
|
|
239
|
+
(d) => !d.isAPIRoute && d.children === void 0 && d.isLazy !== true
|
|
240
|
+
),
|
|
241
|
+
config
|
|
242
|
+
);
|
|
237
243
|
const startAPIRouteNodes = checkStartAPIRoutes(
|
|
238
|
-
preRouteNodes.filter((d) => d.isAPIRoute)
|
|
244
|
+
preRouteNodes.filter((d) => d.isAPIRoute),
|
|
245
|
+
config
|
|
239
246
|
);
|
|
240
247
|
const handleAPINode = async (node) => {
|
|
241
248
|
var _a;
|
|
@@ -431,11 +438,9 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
431
438
|
interface FileRoutesByPath {
|
|
432
439
|
${routeNodes.map((routeNode) => {
|
|
433
440
|
var _a, _b;
|
|
434
|
-
const
|
|
435
|
-
routeNode.routePath
|
|
436
|
-
);
|
|
441
|
+
const filePathId = getFilePathIdFromPath(routeNode.routePath);
|
|
437
442
|
return `'${filePathId}': {
|
|
438
|
-
id: '${
|
|
443
|
+
id: '${filePathId}'
|
|
439
444
|
path: '${inferPath(routeNode)}'
|
|
440
445
|
fullPath: '${inferFullPath(routeNode)}'
|
|
441
446
|
preLoaderRoute: typeof ${routeNode.variableName}Import
|
|
@@ -488,21 +493,19 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
488
493
|
const routesManifest = {
|
|
489
494
|
__root__: {
|
|
490
495
|
filePath: rootRouteNode.filePath,
|
|
491
|
-
children: routeTree.map(
|
|
492
|
-
(d) => getFilePathIdAndRouteIdFromPath(d.routePath)[1]
|
|
493
|
-
)
|
|
496
|
+
children: routeTree.map((d) => getFilePathIdFromPath(d.routePath))
|
|
494
497
|
},
|
|
495
498
|
...Object.fromEntries(
|
|
496
499
|
routeNodes.map((d) => {
|
|
497
500
|
var _a, _b;
|
|
498
|
-
const
|
|
501
|
+
const filePathId = getFilePathIdFromPath(d.routePath);
|
|
499
502
|
return [
|
|
500
|
-
|
|
503
|
+
filePathId,
|
|
501
504
|
{
|
|
502
505
|
filePath: d.filePath,
|
|
503
|
-
parent: ((_a = d.parent) == null ? void 0 : _a.routePath) ?
|
|
506
|
+
parent: ((_a = d.parent) == null ? void 0 : _a.routePath) ? getFilePathIdFromPath(d.parent.routePath) : void 0,
|
|
504
507
|
children: (_b = d.children) == null ? void 0 : _b.map(
|
|
505
|
-
(childRoute) =>
|
|
508
|
+
(childRoute) => getFilePathIdFromPath(childRoute.routePath)
|
|
506
509
|
)
|
|
507
510
|
}
|
|
508
511
|
];
|
|
@@ -613,7 +616,7 @@ const createRouteNodesByTo = (routeNodes) => {
|
|
|
613
616
|
const createRouteNodesById = (routeNodes) => {
|
|
614
617
|
return new Map(
|
|
615
618
|
routeNodes.map((routeNode) => {
|
|
616
|
-
const
|
|
619
|
+
const id = getFilePathIdFromPath(routeNode.routePath);
|
|
617
620
|
return [id, routeNode];
|
|
618
621
|
})
|
|
619
622
|
);
|
|
@@ -640,12 +643,38 @@ const dedupeBranchesAndIndexRoutes = (routes) => {
|
|
|
640
643
|
return true;
|
|
641
644
|
});
|
|
642
645
|
};
|
|
643
|
-
function
|
|
646
|
+
function getFilePathIdFromPath(pathname) {
|
|
644
647
|
const filePathId = removeTrailingUnderscores(pathname);
|
|
645
|
-
|
|
646
|
-
|
|
648
|
+
return filePathId ?? "";
|
|
649
|
+
}
|
|
650
|
+
function checkUnique(routes, key) {
|
|
651
|
+
const keys = routes.map((d) => d[key]);
|
|
652
|
+
const uniqueKeys = new Set(keys);
|
|
653
|
+
if (keys.length !== uniqueKeys.size) {
|
|
654
|
+
const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i);
|
|
655
|
+
const conflictingFiles = routes.filter(
|
|
656
|
+
(d) => duplicateKeys.includes(d[key])
|
|
657
|
+
);
|
|
658
|
+
return conflictingFiles;
|
|
659
|
+
}
|
|
660
|
+
return void 0;
|
|
661
|
+
}
|
|
662
|
+
function checkRouteFullPathUniqueness(_routes, config) {
|
|
663
|
+
const routes = _routes.map((d) => {
|
|
664
|
+
const inferredFullPath = inferFullPath(d);
|
|
665
|
+
return { ...d, inferredFullPath };
|
|
666
|
+
});
|
|
667
|
+
const conflictingFiles = checkUnique(routes, "inferredFullPath");
|
|
668
|
+
if (conflictingFiles !== void 0) {
|
|
669
|
+
const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? "s" : ""}: ${conflictingFiles.map((p) => `"${p.inferredFullPath}"`).join(", ")}.
|
|
670
|
+
Please ensure each route has a unique full path.
|
|
671
|
+
Conflicting files:
|
|
672
|
+
${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join("\n ")}
|
|
673
|
+
`;
|
|
674
|
+
throw new Error(errorMessage);
|
|
675
|
+
}
|
|
647
676
|
}
|
|
648
|
-
function checkStartAPIRoutes(_routes) {
|
|
677
|
+
function checkStartAPIRoutes(_routes, config) {
|
|
649
678
|
if (_routes.length === 0) {
|
|
650
679
|
return [];
|
|
651
680
|
}
|
|
@@ -653,17 +682,12 @@ function checkStartAPIRoutes(_routes) {
|
|
|
653
682
|
const routePath = removeTrailingSlash(d.routePath ?? "");
|
|
654
683
|
return { ...d, routePath };
|
|
655
684
|
});
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
(d, i) => routePaths.indexOf(d) !== i
|
|
661
|
-
);
|
|
662
|
-
const conflictingFiles = routes.filter((d) => duplicateRoutePaths.includes(d.routePath)).map((d) => `${d.fullPath}`);
|
|
663
|
-
const errorMessage = `Conflicting configuration paths was for found for the following API route${duplicateRoutePaths.length > 1 ? "s" : ""}: ${duplicateRoutePaths.map((p) => `"${p}"`).join(", ")}.
|
|
664
|
-
Please ensure each API route has a unique route path.
|
|
685
|
+
const conflictingFiles = checkUnique(routes, "routePath");
|
|
686
|
+
if (conflictingFiles !== void 0) {
|
|
687
|
+
const errorMessage = `Conflicting configuration paths were found for the following API route${conflictingFiles.length > 1 ? "s" : ""}: ${conflictingFiles.map((p) => `"${p}"`).join(", ")}.
|
|
688
|
+
Please ensure each API route has a unique route path.
|
|
665
689
|
Conflicting files:
|
|
666
|
-
${conflictingFiles.join("\n ")}
|
|
690
|
+
${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join("\n ")}
|
|
667
691
|
`;
|
|
668
692
|
throw new Error(errorMessage);
|
|
669
693
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fs from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport * as prettier from 'prettier'\nimport {\n determineInitialRoutePath,\n logging,\n multiSortBy,\n removeExt,\n removeTrailingSlash,\n removeUnderscores,\n replaceBackslash,\n routePathToVariable,\n trimPathLeft,\n writeIfDifferent,\n} from './utils'\nimport { getRouteNodes as physicalGetRouteNodes } from './filesystem/physical/getRouteNodes'\nimport { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport type { GetRouteNodesResult, RouteNode } from './types'\nimport type { Config } from './config'\n\nlet latestTask = 0\nconst routeGroupPatternRegex = /\\(.+\\)/g\nconst possiblyNestedRouteGroupPatternRegex = /\\([^/]+\\)\\/?/g\n\nlet isFirst = false\nlet skipMessage = false\n\ntype RouteSubNode = {\n component?: RouteNode\n errorComponent?: RouteNode\n pendingComponent?: RouteNode\n loader?: RouteNode\n lazy?: RouteNode\n}\n\nexport async function generator(config: Config) {\n const logger = logging({ disabled: config.disableLogging })\n logger.log('')\n\n if (!isFirst) {\n logger.log('♻️ Generating routes...')\n isFirst = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n logger.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n\n const TYPES_DISABLED = config.disableTypes\n\n const prettierOptions: prettier.Options = {\n semi: config.semicolons,\n singleQuote: config.quoteStyle === 'single',\n parser: 'typescript',\n }\n\n let getRouteNodesResult: GetRouteNodesResult\n\n if (config.virtualRouteConfig) {\n getRouteNodesResult = await virtualGetRouteNodes(config)\n } else {\n getRouteNodesResult = await physicalGetRouteNodes(config)\n }\n\n const { rootRouteNode, routeNodes: beforeRouteNodes } = getRouteNodesResult\n if (rootRouteNode === undefined) {\n let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`\n if (!config.virtualRouteConfig) {\n errorMessage += `\\nMake sure that you add a \"${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\" file to your routes directory.\\nAdd the file in: \"${config.routesDirectory}/${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\"`\n }\n throw new Error(errorMessage)\n }\n\n const preRouteNodes = multiSortBy(beforeRouteNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.indexToken}[.]`)) ? 1 : -1,\n (d) =>\n d.filePath.match(\n /[./](component|errorComponent|pendingComponent|loader|lazy)[.]/,\n )\n ? 1\n : -1,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.routeToken}[.]`)) ? -1 : 1,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => ![`/${rootPathId}`].includes(d.routePath || ''))\n\n const routeTree: Array<RouteNode> = []\n const routePiecesByPath: Record<string, RouteSubNode> = {}\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n const routeNodes: Array<RouteNode> = []\n\n // the handleRootNode function is not being collapsed into the handleNode function\n // because it requires only a subset of the logic that the handleNode function requires\n // and it's easier to read and maintain this way\n const handleRootNode = async (node?: RouteNode) => {\n if (!node) {\n // currently this is not being handled, but it could be in the future\n // for example to handle a virtual root route\n return\n }\n\n // from here on, we are only handling the root node that's present in the file system\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n if (!routeCode) {\n const replaced = `import * as React from 'react';\nimport { Outlet, createRootRoute } from '@tanstack/react-router';\n\nexport const Route = createRootRoute({\n component: () => (\n <React.Fragment>\n <div>Hello \"${rootPathId}\"!</div>\n <Outlet />\n </React.Fragment>\n ),\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n }\n }\n\n await handleRootNode(rootRouteNode)\n\n const handleNode = async (node: RouteNode) => {\n let parentRoute = hasParentRoute(routeNodes, node, node.routePath)\n\n // if the parent route is a virtual parent route, we need to find the real parent route\n if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {\n // only if this sub-parent route returns a valid parent route, we use it, if not leave it as it\n const possibleParentRoute = hasParentRoute(\n parentRoute.children,\n node,\n node.routePath,\n )\n if (possibleParentRoute) {\n parentRoute = possibleParentRoute\n }\n }\n\n if (parentRoute) node.parent = parentRoute\n\n node.path = determineNodePath(node)\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath.split('/')\n const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n\n node.isNonPath =\n lastRouteSegment.startsWith('_') ||\n routeGroupPatternRegex.test(lastRouteSegment)\n\n node.cleanedPath = removeGroups(\n removeUnderscores(removeLayoutSegments(node.path)) ?? '',\n )\n\n // Ensure the boilerplate for the route exists, which can be skipped for virtual parent routes and virtual routes\n if (!node.isVirtualParentRoute && !node.isVirtual) {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n let replaced = routeCode\n\n if (!routeCode) {\n if (node.isLazy) {\n replaced = [\n `import { createLazyFileRoute } from '@tanstack/react-router'`,\n `export const Route = createLazyFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n } else if (\n node.isRoute ||\n (!node.isComponent &&\n !node.isErrorComponent &&\n !node.isPendingComponent &&\n !node.isLoader)\n ) {\n replaced = [\n `import { createFileRoute } from '@tanstack/react-router'`,\n `export const Route = createFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n }\n } else {\n replaced = routeCode\n .replace(\n /(FileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3) => `${p1}${escapedRoutePath}${p3}`,\n )\n .replace(\n /(import\\s*\\{.*)(create(Lazy)?FileRoute)(.*\\}\\s*from\\s*['\"]@tanstack\\/react-router['\"])/gs,\n (match, p1, p2, p3, p4) =>\n `${p1}${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p4}`,\n )\n .replace(\n /create(Lazy)?FileRoute(\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3, p4) =>\n `${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p2}${escapedRoutePath}${p4}`,\n )\n }\n\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n replaced,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n\n if (\n !node.isVirtual &&\n (node.isLoader ||\n node.isComponent ||\n node.isErrorComponent ||\n node.isPendingComponent ||\n node.isLazy)\n ) {\n routePiecesByPath[node.routePath!] =\n routePiecesByPath[node.routePath!] || {}\n\n routePiecesByPath[node.routePath!]![\n node.isLazy\n ? 'lazy'\n : node.isLoader\n ? 'loader'\n : node.isErrorComponent\n ? 'errorComponent'\n : node.isPendingComponent\n ? 'pendingComponent'\n : 'component'\n ] = node\n\n const anchorRoute = routeNodes.find((d) => d.routePath === node.routePath)\n\n if (!anchorRoute) {\n await handleNode({\n ...node,\n isVirtual: true,\n isLazy: false,\n isLoader: false,\n isComponent: false,\n isErrorComponent: false,\n isPendingComponent: false,\n })\n }\n return\n }\n\n const cleanedPathIsEmpty = (node.cleanedPath || '').length === 0\n const nonPathRoute = node.isRoute && node.isNonPath\n node.isVirtualParentRequired =\n node.isLayout || nonPathRoute ? !cleanedPathIsEmpty : false\n if (!node.isVirtual && node.isVirtualParentRequired) {\n const parentRoutePath = removeLastSegmentFromPath(node.routePath) || '/'\n const parentVariableName = routePathToVariable(parentRoutePath)\n\n const anchorRoute = routeNodes.find(\n (d) => d.routePath === parentRoutePath,\n )\n\n if (!anchorRoute) {\n const parentNode = {\n ...node,\n path: removeLastSegmentFromPath(node.path) || '/',\n filePath: removeLastSegmentFromPath(node.filePath) || '/',\n fullPath: removeLastSegmentFromPath(node.fullPath) || '/',\n routePath: parentRoutePath,\n variableName: parentVariableName,\n isVirtual: true,\n isLayout: false,\n isVirtualParentRoute: true,\n isVirtualParentRequired: false,\n }\n\n parentNode.children = parentNode.children ?? []\n parentNode.children.push(node)\n\n node.parent = parentNode\n\n if (node.isLayout) {\n // since `node.path` is used as the `id` on the route definition, we need to update it\n node.path = determineNodePath(node)\n }\n\n await handleNode(parentNode)\n } else {\n anchorRoute.children = anchorRoute.children ?? []\n anchorRoute.children.push(node)\n\n node.parent = anchorRoute\n }\n }\n\n if (node.parent) {\n if (!node.isVirtualParentRequired) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n }\n } else {\n routeTree.push(node)\n }\n\n routeNodes.push(node)\n }\n\n for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {\n await handleNode(node)\n }\n\n const startAPIRouteNodes: Array<RouteNode> = checkStartAPIRoutes(\n preRouteNodes.filter((d) => d.isAPIRoute),\n )\n\n const handleAPINode = async (node: RouteNode) => {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n if (!routeCode) {\n const replaced = `import { json } from '@tanstack/start'\nimport { createAPIFileRoute } from '@tanstack/start/api'\n\nexport const Route = createAPIFileRoute('${escapedRoutePath}')({\n GET: ({ request, params }) => {\n return json({ message: 'Hello ${escapedRoutePath}' })\n },\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n } else {\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n routeCode.replace(\n /(createAPIFileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (_, p1, __, p3) => `${p1}${escapedRoutePath}${p3}`,\n ),\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n }\n\n for (const node of startAPIRouteNodes) {\n await handleAPINode(node)\n }\n\n function buildRouteTreeConfig(nodes: Array<RouteNode>, depth = 1): string {\n const children = nodes.map((node) => {\n if (node.isRoot) {\n return\n }\n\n if (node.isLayout && !node.children?.length) {\n return\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = buildRouteTreeConfig(node.children, depth + 1)\n\n const childrenDeclaration = TYPES_DISABLED\n ? ''\n : `interface ${route}Children {\n ${node.children.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const children = `const ${route}Children${TYPES_DISABLED ? '' : `: ${route}Children`} = {\n ${node.children.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const routeWithChildren = `const ${route}WithChildren = ${route}._addFileChildren(${route}Children)`\n\n return [\n childConfigs,\n childrenDeclaration,\n children,\n routeWithChildren,\n ].join('\\n\\n')\n }\n\n return undefined\n })\n\n return children.filter(Boolean).join('\\n\\n')\n }\n\n const routeConfigChildrenText = buildRouteTreeConfig(routeTree)\n\n const sortedRouteNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(config.indexToken) ? -1 : 1),\n (d) => d,\n ])\n\n const imports = Object.entries({\n createFileRoute: sortedRouteNodes.some((d) => d.isVirtual),\n lazyFn: sortedRouteNodes.some(\n (node) => routePiecesByPath[node.routePath!]?.loader,\n ),\n lazyRouteComponent: sortedRouteNodes.some(\n (node) =>\n routePiecesByPath[node.routePath!]?.component ||\n routePiecesByPath[node.routePath!]?.errorComponent ||\n routePiecesByPath[node.routePath!]?.pendingComponent,\n ),\n })\n .filter((d) => d[1])\n .map((d) => d[0])\n\n const virtualRouteNodes = sortedRouteNodes.filter((d) => d.isVirtual)\n\n function getImportPath(node: RouteNode) {\n return replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n config.addExtensions,\n ),\n )\n }\n const routeImports = [\n ...config.routeTreeFileHeader,\n '// This file is auto-generated by TanStack Router',\n imports.length\n ? `import { ${imports.join(', ')} } from '@tanstack/react-router'\\n`\n : '',\n '// Import Routes',\n [\n `import { Route as rootRoute } from './${getImportPath(rootRouteNode)}'`,\n ...sortedRouteNodes\n .filter((d) => !d.isVirtual)\n .map((node) => {\n return `import { Route as ${\n node.variableName\n }Import } from './${getImportPath(node)}'`\n }),\n ].join('\\n'),\n virtualRouteNodes.length ? '// Create Virtual Routes' : '',\n virtualRouteNodes\n .map((node) => {\n return `const ${\n node.variableName\n }Import = createFileRoute('${removeTrailingUnderscores(\n node.routePath,\n )}')()`\n })\n .join('\\n'),\n '// Create/Update Routes',\n sortedRouteNodes\n .map((node) => {\n const loaderNode = routePiecesByPath[node.routePath!]?.loader\n const componentNode = routePiecesByPath[node.routePath!]?.component\n const errorComponentNode =\n routePiecesByPath[node.routePath!]?.errorComponent\n const pendingComponentNode =\n routePiecesByPath[node.routePath!]?.pendingComponent\n const lazyComponentNode = routePiecesByPath[node.routePath!]?.lazy\n\n return [\n `const ${node.variableName}Route = ${node.variableName}Import.update({\n ${[\n node.isNonPath\n ? `id: '${node.path}'`\n : `path: '${node.cleanedPath}'`,\n `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,\n ]\n .filter(Boolean)\n .join(',')}\n }${TYPES_DISABLED ? '' : 'as any'})`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n config.addExtensions,\n ),\n )}'), 'loader') })`\n : '',\n componentNode || errorComponentNode || pendingComponentNode\n ? `.update({\n ${(\n [\n ['component', componentNode],\n ['errorComponent', errorComponentNode],\n ['pendingComponent', pendingComponentNode],\n ] as const\n )\n .filter((d) => d[1])\n .map((d) => {\n return `${\n d[0]\n }: lazyRouteComponent(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, d[1]!.filePath),\n ),\n config.addExtensions,\n ),\n )}'), '${d[0]}')`\n })\n .join('\\n,')}\n })`\n : '',\n lazyComponentNode\n ? `.lazy(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n lazyComponentNode.filePath,\n ),\n ),\n config.addExtensions,\n ),\n )}').then((d) => d.Route))`\n : '',\n ].join('')\n })\n .join('\\n\\n'),\n ...(TYPES_DISABLED\n ? []\n : [\n '// Populate the FileRoutesByPath interface',\n `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n const [filePathId, routeId] = getFilePathIdAndRouteIdFromPath(\n routeNode.routePath,\n )\n\n return `'${filePathId}': {\n id: '${routeId}'\n path: '${inferPath(routeNode)}'\n fullPath: '${inferFullPath(routeNode)}'\n preLoaderRoute: typeof ${routeNode.variableName}Import\n parentRoute: typeof ${\n routeNode.isVirtualParentRequired\n ? `${routeNode.parent?.variableName}Route`\n : routeNode.parent?.variableName\n ? `${routeNode.parent.variableName}Import`\n : 'rootRoute'\n }\n }`\n })\n .join('\\n')}\n }\n}`,\n ]),\n '// Create and export the route tree',\n routeConfigChildrenText,\n ...(TYPES_DISABLED\n ? []\n : [\n `export interface FileRoutesByFullPath {\n ${[...createRouteNodesByFullPath(routeNodes).entries()].map(\n ([fullPath, routeNode]) => {\n return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n },\n )}\n}`,\n `export interface FileRoutesByTo {\n ${[...createRouteNodesByTo(routeNodes).entries()].map(([to, routeNode]) => {\n return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesById {\n '__root__': typeof rootRoute,\n ${[...createRouteNodesById(routeNodes).entries()].map(([id, routeNode]) => {\n return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRouteTypes {\n fileRoutesByFullPath: FileRoutesByFullPath\n fullPaths: ${routeNodes.length > 0 ? [...createRouteNodesByFullPath(routeNodes).keys()].map((fullPath) => `'${fullPath}'`).join('|') : 'never'}\n fileRoutesByTo: FileRoutesByTo\n to: ${routeNodes.length > 0 ? [...createRouteNodesByTo(routeNodes).keys()].map((to) => `'${to}'`).join('|') : 'never'}\n id: ${[`'__root__'`, ...[...createRouteNodesById(routeNodes).keys()].map((id) => `'${id}'`)].join('|')}\n fileRoutesById: FileRoutesById\n}`,\n `export interface RootRouteChildren {\n ${routeTree.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n ]),\n `const rootRouteChildren${TYPES_DISABLED ? '' : ': RootRouteChildren'} = {\n ${routeTree.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n `export const routeTree = rootRoute._addFileChildren(rootRouteChildren)${TYPES_DISABLED ? '' : '._addFileTypes<FileRouteTypes>()'}`,\n ...config.routeTreeFileFooter,\n ]\n .filter(Boolean)\n .join('\\n\\n')\n\n const createRouteManifest = () => {\n const routesManifest = {\n __root__: {\n filePath: rootRouteNode.filePath,\n children: routeTree.map(\n (d) => getFilePathIdAndRouteIdFromPath(d.routePath)[1],\n ),\n },\n ...Object.fromEntries(\n routeNodes.map((d) => {\n const [_, routeId] = getFilePathIdAndRouteIdFromPath(d.routePath)\n\n return [\n routeId,\n {\n filePath: d.filePath,\n parent: d.parent?.routePath\n ? getFilePathIdAndRouteIdFromPath(d.parent.routePath)[1]\n : undefined,\n children: d.children?.map(\n (childRoute) =>\n getFilePathIdAndRouteIdFromPath(childRoute.routePath)[1],\n ),\n },\n ]\n }),\n ),\n }\n\n return JSON.stringify(\n {\n routes: routesManifest,\n },\n null,\n 2,\n )\n }\n\n const routeConfigFileContent = config.disableManifestGeneration\n ? routeImports\n : [\n routeImports,\n '\\n',\n '/* ROUTE_MANIFEST_START',\n createRouteManifest(),\n 'ROUTE_MANIFEST_END */',\n ].join('\\n')\n\n if (!checkLatest()) return\n\n const existingRouteTreeContent = await fsp\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return ''\n }\n\n throw err\n })\n\n if (!checkLatest()) return\n\n // Ensure the directory exists\n await fsp.mkdir(path.dirname(path.resolve(config.generatedRouteTree)), {\n recursive: true,\n })\n\n if (!checkLatest()) return\n\n // Write the route tree file, if it has changed\n const routeTreeWriteResult = await writeIfDifferent(\n path.resolve(config.generatedRouteTree),\n prettierOptions,\n existingRouteTreeContent,\n routeConfigFileContent,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${config.generatedRouteTree}`)\n },\n },\n )\n if (routeTreeWriteResult && !checkLatest()) {\n return\n }\n\n logger.log(\n `✅ Processed ${routeNodes.length === 1 ? 'route' : 'routes'} in ${\n Date.now() - start\n }ms`,\n )\n}\n\nfunction spaces(d: number): string {\n return Array.from({ length: d })\n .map(() => ' ')\n .join('')\n}\n\nfunction removeTrailingUnderscores(s?: string) {\n return s?.replaceAll(/(_$)/gi, '').replaceAll(/(_\\/)/gi, '/')\n}\n\nfunction removeGroups(s: string) {\n return s.replace(possiblyNestedRouteGroupPatternRegex, '')\n}\n\n/**\n * The `node.path` is used as the `id` in the route definition.\n * This function checks if the given node has a parent and if so, it determines the correct path for the given node.\n * @param node - The node to determine the path for.\n * @returns The correct path for the given node.\n */\nfunction determineNodePath(node: RouteNode) {\n return (node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath ?? '', '') || '/'\n : node.routePath)\n}\n\n/**\n * Removes the last segment from a given path. Segments are considered to be separated by a '/'.\n *\n * @param {string} routePath - The path from which to remove the last segment. Defaults to '/'.\n * @returns {string} The path with the last segment removed.\n * @example\n * removeLastSegmentFromPath('/workspace/_auth/foo') // '/workspace/_auth'\n */\nexport function removeLastSegmentFromPath(routePath: string = '/'): string {\n const segments = routePath.split('/')\n segments.pop() // Remove the last segment\n return segments.join('/')\n}\n\n/**\n * Removes all segments from a given path that start with an underscore ('_').\n *\n * @param {string} routePath - The path from which to remove segments. Defaults to '/'.\n * @returns {string} The path with all underscore-prefixed segments removed.\n * @example\n * removeLayoutSegments('/workspace/_auth/foo') // '/workspace/foo'\n */\nfunction removeLayoutSegments(routePath: string = '/'): string {\n const segments = routePath.split('/')\n const newSegments = segments.filter((segment) => !segment.startsWith('_'))\n return newSegments.join('/')\n}\n\nexport function hasParentRoute(\n routes: Array<RouteNode>,\n node: RouteNode,\n routePathToCheck: string | undefined,\n): RouteNode | null {\n if (!routePathToCheck || routePathToCheck === '/') {\n return null\n }\n\n const sortedNodes = multiSortBy(routes, [\n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue\n\n if (\n routePathToCheck.startsWith(`${route.routePath}/`) &&\n route.routePath !== routePathToCheck\n ) {\n return route\n }\n }\n\n const segments = routePathToCheck.split('/')\n segments.pop() // Remove the last segment\n const parentRoutePath = segments.join('/')\n\n return hasParentRoute(routes, node, parentRoutePath)\n}\n\n/**\n * Gets the final variable name for a route\n */\nexport const getResolvedRouteNodeVariableName = (\n routeNode: RouteNode,\n): string => {\n return routeNode.children?.length\n ? `${routeNode.variableName}RouteWithChildren`\n : `${routeNode.variableName}Route`\n}\n\n/**\n * Creates a map from fullPath to routeNode\n */\nexport const createRouteNodesByFullPath = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => [inferFullPath(routeNode), routeNode]),\n )\n}\n\n/**\n * Create a map from 'to' to a routeNode\n */\nexport const createRouteNodesByTo = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n dedupeBranchesAndIndexRoutes(routeNodes).map((routeNode) => [\n inferTo(routeNode),\n routeNode,\n ]),\n )\n}\n\n/**\n * Create a map from 'id' to a routeNode\n */\nexport const createRouteNodesById = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => {\n const [_, id] = getFilePathIdAndRouteIdFromPath(routeNode.routePath)\n return [id, routeNode]\n }),\n )\n}\n\n/**\n * Infers the full path for use by TS\n */\nexport const inferFullPath = (routeNode: RouteNode): string => {\n const fullPath = removeGroups(\n removeUnderscores(removeLayoutSegments(routeNode.routePath)) ?? '',\n )\n\n return routeNode.cleanedPath === '/' ? fullPath : fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Infers the path for use by TS\n */\nexport const inferPath = (routeNode: RouteNode): string => {\n return routeNode.cleanedPath === '/'\n ? routeNode.cleanedPath\n : (routeNode.cleanedPath?.replace(/\\/$/, '') ?? '')\n}\n\n/**\n * Infers to path\n */\nexport const inferTo = (routeNode: RouteNode): string => {\n const fullPath = inferFullPath(routeNode)\n\n if (fullPath === '/') return fullPath\n\n return fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Dedupes branches and index routes\n */\nexport const dedupeBranchesAndIndexRoutes = (\n routes: Array<RouteNode>,\n): Array<RouteNode> => {\n return routes.filter((route) => {\n if (route.children?.find((child) => child.cleanedPath === '/')) return false\n return true\n })\n}\n\nfunction getFilePathIdAndRouteIdFromPath(pathname?: string) {\n const filePathId = removeTrailingUnderscores(pathname)\n const id = removeGroups(filePathId ?? '')\n\n return [filePathId, id] as const\n}\n\nfunction checkStartAPIRoutes(_routes: Array<RouteNode>) {\n if (_routes.length === 0) {\n return []\n }\n\n // Make sure these are valid URLs\n // Route Groups and Layout Routes aren't being removed since\n // you may want to have an API route that starts with an underscore\n // or be wrapped in parentheses\n const routes = _routes.map((d) => {\n const routePath = removeTrailingSlash(d.routePath ?? '')\n return { ...d, routePath }\n })\n\n // Check no two API routes have the same routePath\n // if they do, throw an error with the conflicting filePaths\n const routePaths = routes.map((d) => d.routePath)\n const uniqueRoutePaths = new Set(routePaths)\n if (routePaths.length !== uniqueRoutePaths.size) {\n const duplicateRoutePaths = routePaths.filter(\n (d, i) => routePaths.indexOf(d) !== i,\n )\n const conflictingFiles = routes\n .filter((d) => duplicateRoutePaths.includes(d.routePath))\n .map((d) => `${d.fullPath}`)\n const errorMessage = `Conflicting configuration paths was for found for the following API route${duplicateRoutePaths.length > 1 ? 's' : ''}: ${duplicateRoutePaths\n .map((p) => `\"${p}\"`)\n .join(', ')}.\nPlease ensure each API route has a unique route path.\nConflicting files: \\n ${conflictingFiles.join('\\n ')}\\n`\n throw new Error(errorMessage)\n }\n\n return routes\n}\n\nexport type StartAPIRoutePathSegment = {\n value: string\n type: 'path' | 'param' | 'splat'\n}\n\n/**\n * This function takes in a path in the format accepted by TanStack Router\n * and returns an array of path segments that can be used to generate\n * the pathname of the TanStack Start API route.\n *\n * @param src\n * @returns\n */\nexport function startAPIRouteSegmentsFromTSRFilePath(\n src: string,\n config: Config,\n): Array<StartAPIRoutePathSegment> {\n const routePath = determineInitialRoutePath(src)\n\n const parts = routePath\n .replaceAll('.', '/')\n .split('/')\n .filter((p) => !!p && p !== config.indexToken)\n const segments: Array<StartAPIRoutePathSegment> = parts.map((part) => {\n if (part.startsWith('$')) {\n if (part === '$') {\n return { value: part, type: 'splat' }\n }\n\n part.replaceAll('$', '')\n return { value: part, type: 'param' }\n }\n\n return { value: part, type: 'path' }\n })\n\n return segments\n}\n"],"names":["virtualGetRouteNodes","physicalGetRouteNodes","children"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generator.js","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fs from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport * as prettier from 'prettier'\nimport {\n determineInitialRoutePath,\n logging,\n multiSortBy,\n removeExt,\n removeTrailingSlash,\n removeUnderscores,\n replaceBackslash,\n routePathToVariable,\n trimPathLeft,\n writeIfDifferent,\n} from './utils'\nimport { getRouteNodes as physicalGetRouteNodes } from './filesystem/physical/getRouteNodes'\nimport { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport type { GetRouteNodesResult, RouteNode } from './types'\nimport type { Config } from './config'\n\nlet latestTask = 0\nconst routeGroupPatternRegex = /\\(.+\\)/g\nconst possiblyNestedRouteGroupPatternRegex = /\\([^/]+\\)\\/?/g\n\nlet isFirst = false\nlet skipMessage = false\n\ntype RouteSubNode = {\n component?: RouteNode\n errorComponent?: RouteNode\n pendingComponent?: RouteNode\n loader?: RouteNode\n lazy?: RouteNode\n}\n\nexport async function generator(config: Config) {\n const logger = logging({ disabled: config.disableLogging })\n logger.log('')\n\n if (!isFirst) {\n logger.log('♻️ Generating routes...')\n isFirst = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n logger.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n\n const TYPES_DISABLED = config.disableTypes\n\n const prettierOptions: prettier.Options = {\n semi: config.semicolons,\n singleQuote: config.quoteStyle === 'single',\n parser: 'typescript',\n }\n\n let getRouteNodesResult: GetRouteNodesResult\n\n if (config.virtualRouteConfig) {\n getRouteNodesResult = await virtualGetRouteNodes(config)\n } else {\n getRouteNodesResult = await physicalGetRouteNodes(config)\n }\n\n const { rootRouteNode, routeNodes: beforeRouteNodes } = getRouteNodesResult\n if (rootRouteNode === undefined) {\n let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`\n if (!config.virtualRouteConfig) {\n errorMessage += `\\nMake sure that you add a \"${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\" file to your routes directory.\\nAdd the file in: \"${config.routesDirectory}/${rootPathId}.${config.disableTypes ? 'js' : 'tsx'}\"`\n }\n throw new Error(errorMessage)\n }\n\n const preRouteNodes = multiSortBy(beforeRouteNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.indexToken}[.]`)) ? 1 : -1,\n (d) =>\n d.filePath.match(\n /[./](component|errorComponent|pendingComponent|loader|lazy)[.]/,\n )\n ? 1\n : -1,\n (d) =>\n d.filePath.match(new RegExp(`[./]${config.routeToken}[.]`)) ? -1 : 1,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => ![`/${rootPathId}`].includes(d.routePath || ''))\n\n const routeTree: Array<RouteNode> = []\n const routePiecesByPath: Record<string, RouteSubNode> = {}\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n const routeNodes: Array<RouteNode> = []\n\n // the handleRootNode function is not being collapsed into the handleNode function\n // because it requires only a subset of the logic that the handleNode function requires\n // and it's easier to read and maintain this way\n const handleRootNode = async (node?: RouteNode) => {\n if (!node) {\n // currently this is not being handled, but it could be in the future\n // for example to handle a virtual root route\n return\n }\n\n // from here on, we are only handling the root node that's present in the file system\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n if (!routeCode) {\n const replaced = `import * as React from 'react';\nimport { Outlet, createRootRoute } from '@tanstack/react-router';\n\nexport const Route = createRootRoute({\n component: () => (\n <React.Fragment>\n <div>Hello \"${rootPathId}\"!</div>\n <Outlet />\n </React.Fragment>\n ),\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n }\n }\n\n await handleRootNode(rootRouteNode)\n\n const handleNode = async (node: RouteNode) => {\n let parentRoute = hasParentRoute(routeNodes, node, node.routePath)\n\n // if the parent route is a virtual parent route, we need to find the real parent route\n if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {\n // only if this sub-parent route returns a valid parent route, we use it, if not leave it as it\n const possibleParentRoute = hasParentRoute(\n parentRoute.children,\n node,\n node.routePath,\n )\n if (possibleParentRoute) {\n parentRoute = possibleParentRoute\n }\n }\n\n if (parentRoute) node.parent = parentRoute\n\n node.path = determineNodePath(node)\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath.split('/')\n const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n\n node.isNonPath =\n lastRouteSegment.startsWith('_') ||\n routeGroupPatternRegex.test(lastRouteSegment)\n\n node.cleanedPath = removeGroups(\n removeUnderscores(removeLayoutSegments(node.path)) ?? '',\n )\n\n // Ensure the boilerplate for the route exists, which can be skipped for virtual parent routes and virtual routes\n if (!node.isVirtualParentRoute && !node.isVirtual) {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n let replaced = routeCode\n\n if (!routeCode) {\n if (node.isLazy) {\n replaced = [\n `import { createLazyFileRoute } from '@tanstack/react-router'`,\n `export const Route = createLazyFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n } else if (\n node.isRoute ||\n (!node.isComponent &&\n !node.isErrorComponent &&\n !node.isPendingComponent &&\n !node.isLoader)\n ) {\n replaced = [\n `import { createFileRoute } from '@tanstack/react-router'`,\n `export const Route = createFileRoute('${escapedRoutePath}')({\n component: () => <div>Hello ${escapedRoutePath}!</div>\n})`,\n ].join('\\n\\n')\n }\n } else {\n replaced = routeCode\n .replace(\n /(FileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3) => `${p1}${escapedRoutePath}${p3}`,\n )\n .replace(\n /(import\\s*\\{.*)(create(Lazy)?FileRoute)(.*\\}\\s*from\\s*['\"]@tanstack\\/react-router['\"])/gs,\n (match, p1, p2, p3, p4) =>\n `${p1}${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p4}`,\n )\n .replace(\n /create(Lazy)?FileRoute(\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (match, p1, p2, p3, p4) =>\n `${node.isLazy ? 'createLazyFileRoute' : 'createFileRoute'}${p2}${escapedRoutePath}${p4}`,\n )\n }\n\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n replaced,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n\n if (\n !node.isVirtual &&\n (node.isLoader ||\n node.isComponent ||\n node.isErrorComponent ||\n node.isPendingComponent ||\n node.isLazy)\n ) {\n routePiecesByPath[node.routePath!] =\n routePiecesByPath[node.routePath!] || {}\n\n routePiecesByPath[node.routePath!]![\n node.isLazy\n ? 'lazy'\n : node.isLoader\n ? 'loader'\n : node.isErrorComponent\n ? 'errorComponent'\n : node.isPendingComponent\n ? 'pendingComponent'\n : 'component'\n ] = node\n\n const anchorRoute = routeNodes.find((d) => d.routePath === node.routePath)\n\n if (!anchorRoute) {\n await handleNode({\n ...node,\n isVirtual: true,\n isLazy: false,\n isLoader: false,\n isComponent: false,\n isErrorComponent: false,\n isPendingComponent: false,\n })\n }\n return\n }\n\n const cleanedPathIsEmpty = (node.cleanedPath || '').length === 0\n const nonPathRoute = node.isRoute && node.isNonPath\n node.isVirtualParentRequired =\n node.isLayout || nonPathRoute ? !cleanedPathIsEmpty : false\n if (!node.isVirtual && node.isVirtualParentRequired) {\n const parentRoutePath = removeLastSegmentFromPath(node.routePath) || '/'\n const parentVariableName = routePathToVariable(parentRoutePath)\n\n const anchorRoute = routeNodes.find(\n (d) => d.routePath === parentRoutePath,\n )\n\n if (!anchorRoute) {\n const parentNode = {\n ...node,\n path: removeLastSegmentFromPath(node.path) || '/',\n filePath: removeLastSegmentFromPath(node.filePath) || '/',\n fullPath: removeLastSegmentFromPath(node.fullPath) || '/',\n routePath: parentRoutePath,\n variableName: parentVariableName,\n isVirtual: true,\n isLayout: false,\n isVirtualParentRoute: true,\n isVirtualParentRequired: false,\n }\n\n parentNode.children = parentNode.children ?? []\n parentNode.children.push(node)\n\n node.parent = parentNode\n\n if (node.isLayout) {\n // since `node.path` is used as the `id` on the route definition, we need to update it\n node.path = determineNodePath(node)\n }\n\n await handleNode(parentNode)\n } else {\n anchorRoute.children = anchorRoute.children ?? []\n anchorRoute.children.push(node)\n\n node.parent = anchorRoute\n }\n }\n\n if (node.parent) {\n if (!node.isVirtualParentRequired) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n }\n } else {\n routeTree.push(node)\n }\n\n routeNodes.push(node)\n }\n\n for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {\n await handleNode(node)\n }\n checkRouteFullPathUniqueness(\n preRouteNodes.filter(\n (d) => !d.isAPIRoute && d.children === undefined && d.isLazy !== true,\n ),\n config,\n )\n\n const startAPIRouteNodes: Array<RouteNode> = checkStartAPIRoutes(\n preRouteNodes.filter((d) => d.isAPIRoute),\n config,\n )\n\n const handleAPINode = async (node: RouteNode) => {\n const routeCode = fs.readFileSync(node.fullPath, 'utf-8')\n\n const escapedRoutePath = removeTrailingUnderscores(\n node.routePath?.replaceAll('$', '$$') ?? '',\n )\n\n if (!routeCode) {\n const replaced = `import { json } from '@tanstack/start'\nimport { createAPIFileRoute } from '@tanstack/start/api'\n\nexport const Route = createAPIFileRoute('${escapedRoutePath}')({\n GET: ({ request, params }) => {\n return json({ message: 'Hello ${escapedRoutePath}' })\n },\n})\n\n`\n\n logger.log(`🟡 Creating ${node.fullPath}`)\n fs.writeFileSync(\n node.fullPath,\n await prettier.format(replaced, prettierOptions),\n )\n } else {\n await writeIfDifferent(\n node.fullPath,\n prettierOptions,\n routeCode,\n routeCode.replace(\n /(createAPIFileRoute\\(\\s*['\"])([^\\s]*)(['\"],?\\s*\\))/g,\n (_, p1, __, p3) => `${p1}${escapedRoutePath}${p3}`,\n ),\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${node.fullPath}`)\n },\n },\n )\n }\n }\n\n for (const node of startAPIRouteNodes) {\n await handleAPINode(node)\n }\n\n function buildRouteTreeConfig(nodes: Array<RouteNode>, depth = 1): string {\n const children = nodes.map((node) => {\n if (node.isRoot) {\n return\n }\n\n if (node.isLayout && !node.children?.length) {\n return\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = buildRouteTreeConfig(node.children, depth + 1)\n\n const childrenDeclaration = TYPES_DISABLED\n ? ''\n : `interface ${route}Children {\n ${node.children.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const children = `const ${route}Children${TYPES_DISABLED ? '' : `: ${route}Children`} = {\n ${node.children.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`\n\n const routeWithChildren = `const ${route}WithChildren = ${route}._addFileChildren(${route}Children)`\n\n return [\n childConfigs,\n childrenDeclaration,\n children,\n routeWithChildren,\n ].join('\\n\\n')\n }\n\n return undefined\n })\n\n return children.filter(Boolean).join('\\n\\n')\n }\n\n const routeConfigChildrenText = buildRouteTreeConfig(routeTree)\n\n const sortedRouteNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(config.indexToken) ? -1 : 1),\n (d) => d,\n ])\n\n const imports = Object.entries({\n createFileRoute: sortedRouteNodes.some((d) => d.isVirtual),\n lazyFn: sortedRouteNodes.some(\n (node) => routePiecesByPath[node.routePath!]?.loader,\n ),\n lazyRouteComponent: sortedRouteNodes.some(\n (node) =>\n routePiecesByPath[node.routePath!]?.component ||\n routePiecesByPath[node.routePath!]?.errorComponent ||\n routePiecesByPath[node.routePath!]?.pendingComponent,\n ),\n })\n .filter((d) => d[1])\n .map((d) => d[0])\n\n const virtualRouteNodes = sortedRouteNodes.filter((d) => d.isVirtual)\n\n function getImportPath(node: RouteNode) {\n return replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n config.addExtensions,\n ),\n )\n }\n const routeImports = [\n ...config.routeTreeFileHeader,\n '// This file is auto-generated by TanStack Router',\n imports.length\n ? `import { ${imports.join(', ')} } from '@tanstack/react-router'\\n`\n : '',\n '// Import Routes',\n [\n `import { Route as rootRoute } from './${getImportPath(rootRouteNode)}'`,\n ...sortedRouteNodes\n .filter((d) => !d.isVirtual)\n .map((node) => {\n return `import { Route as ${\n node.variableName\n }Import } from './${getImportPath(node)}'`\n }),\n ].join('\\n'),\n virtualRouteNodes.length ? '// Create Virtual Routes' : '',\n virtualRouteNodes\n .map((node) => {\n return `const ${\n node.variableName\n }Import = createFileRoute('${removeTrailingUnderscores(\n node.routePath,\n )}')()`\n })\n .join('\\n'),\n '// Create/Update Routes',\n sortedRouteNodes\n .map((node) => {\n const loaderNode = routePiecesByPath[node.routePath!]?.loader\n const componentNode = routePiecesByPath[node.routePath!]?.component\n const errorComponentNode =\n routePiecesByPath[node.routePath!]?.errorComponent\n const pendingComponentNode =\n routePiecesByPath[node.routePath!]?.pendingComponent\n const lazyComponentNode = routePiecesByPath[node.routePath!]?.lazy\n\n return [\n `const ${node.variableName}Route = ${node.variableName}Import.update({\n ${[\n node.isNonPath\n ? `id: '${node.path}'`\n : `path: '${node.cleanedPath}'`,\n `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,\n ]\n .filter(Boolean)\n .join(',')}\n }${TYPES_DISABLED ? '' : 'as any'})`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n config.addExtensions,\n ),\n )}'), 'loader') })`\n : '',\n componentNode || errorComponentNode || pendingComponentNode\n ? `.update({\n ${(\n [\n ['component', componentNode],\n ['errorComponent', errorComponentNode],\n ['pendingComponent', pendingComponentNode],\n ] as const\n )\n .filter((d) => d[1])\n .map((d) => {\n return `${\n d[0]\n }: lazyRouteComponent(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, d[1]!.filePath),\n ),\n config.addExtensions,\n ),\n )}'), '${d[0]}')`\n })\n .join('\\n,')}\n })`\n : '',\n lazyComponentNode\n ? `.lazy(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n lazyComponentNode.filePath,\n ),\n ),\n config.addExtensions,\n ),\n )}').then((d) => d.Route))`\n : '',\n ].join('')\n })\n .join('\\n\\n'),\n ...(TYPES_DISABLED\n ? []\n : [\n '// Populate the FileRoutesByPath interface',\n `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n const filePathId = getFilePathIdFromPath(routeNode.routePath)\n\n return `'${filePathId}': {\n id: '${filePathId}'\n path: '${inferPath(routeNode)}'\n fullPath: '${inferFullPath(routeNode)}'\n preLoaderRoute: typeof ${routeNode.variableName}Import\n parentRoute: typeof ${\n routeNode.isVirtualParentRequired\n ? `${routeNode.parent?.variableName}Route`\n : routeNode.parent?.variableName\n ? `${routeNode.parent.variableName}Import`\n : 'rootRoute'\n }\n }`\n })\n .join('\\n')}\n }\n}`,\n ]),\n '// Create and export the route tree',\n routeConfigChildrenText,\n ...(TYPES_DISABLED\n ? []\n : [\n `export interface FileRoutesByFullPath {\n ${[...createRouteNodesByFullPath(routeNodes).entries()].map(\n ([fullPath, routeNode]) => {\n return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n },\n )}\n}`,\n `export interface FileRoutesByTo {\n ${[...createRouteNodesByTo(routeNodes).entries()].map(([to, routeNode]) => {\n return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesById {\n '__root__': typeof rootRoute,\n ${[...createRouteNodesById(routeNodes).entries()].map(([id, routeNode]) => {\n return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRouteTypes {\n fileRoutesByFullPath: FileRoutesByFullPath\n fullPaths: ${routeNodes.length > 0 ? [...createRouteNodesByFullPath(routeNodes).keys()].map((fullPath) => `'${fullPath}'`).join('|') : 'never'}\n fileRoutesByTo: FileRoutesByTo\n to: ${routeNodes.length > 0 ? [...createRouteNodesByTo(routeNodes).keys()].map((to) => `'${to}'`).join('|') : 'never'}\n id: ${[`'__root__'`, ...[...createRouteNodesById(routeNodes).keys()].map((id) => `'${id}'`)].join('|')}\n fileRoutesById: FileRoutesById\n}`,\n `export interface RootRouteChildren {\n ${routeTree.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n ]),\n `const rootRouteChildren${TYPES_DISABLED ? '' : ': RootRouteChildren'} = {\n ${routeTree.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n `export const routeTree = rootRoute._addFileChildren(rootRouteChildren)${TYPES_DISABLED ? '' : '._addFileTypes<FileRouteTypes>()'}`,\n ...config.routeTreeFileFooter,\n ]\n .filter(Boolean)\n .join('\\n\\n')\n\n const createRouteManifest = () => {\n const routesManifest = {\n __root__: {\n filePath: rootRouteNode.filePath,\n children: routeTree.map((d) => getFilePathIdFromPath(d.routePath)),\n },\n ...Object.fromEntries(\n routeNodes.map((d) => {\n const filePathId = getFilePathIdFromPath(d.routePath)\n\n return [\n filePathId,\n {\n filePath: d.filePath,\n parent: d.parent?.routePath\n ? getFilePathIdFromPath(d.parent.routePath)\n : undefined,\n children: d.children?.map((childRoute) =>\n getFilePathIdFromPath(childRoute.routePath),\n ),\n },\n ]\n }),\n ),\n }\n\n return JSON.stringify(\n {\n routes: routesManifest,\n },\n null,\n 2,\n )\n }\n\n const routeConfigFileContent = config.disableManifestGeneration\n ? routeImports\n : [\n routeImports,\n '\\n',\n '/* ROUTE_MANIFEST_START',\n createRouteManifest(),\n 'ROUTE_MANIFEST_END */',\n ].join('\\n')\n\n if (!checkLatest()) return\n\n const existingRouteTreeContent = await fsp\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return ''\n }\n\n throw err\n })\n\n if (!checkLatest()) return\n\n // Ensure the directory exists\n await fsp.mkdir(path.dirname(path.resolve(config.generatedRouteTree)), {\n recursive: true,\n })\n\n if (!checkLatest()) return\n\n // Write the route tree file, if it has changed\n const routeTreeWriteResult = await writeIfDifferent(\n path.resolve(config.generatedRouteTree),\n prettierOptions,\n existingRouteTreeContent,\n routeConfigFileContent,\n {\n beforeWrite: () => {\n logger.log(`🟡 Updating ${config.generatedRouteTree}`)\n },\n },\n )\n if (routeTreeWriteResult && !checkLatest()) {\n return\n }\n\n logger.log(\n `✅ Processed ${routeNodes.length === 1 ? 'route' : 'routes'} in ${\n Date.now() - start\n }ms`,\n )\n}\n\nfunction removeTrailingUnderscores(s?: string) {\n return s?.replaceAll(/(_$)/gi, '').replaceAll(/(_\\/)/gi, '/')\n}\n\nfunction removeGroups(s: string) {\n return s.replace(possiblyNestedRouteGroupPatternRegex, '')\n}\n\n/**\n * The `node.path` is used as the `id` in the route definition.\n * This function checks if the given node has a parent and if so, it determines the correct path for the given node.\n * @param node - The node to determine the path for.\n * @returns The correct path for the given node.\n */\nfunction determineNodePath(node: RouteNode) {\n return (node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath ?? '', '') || '/'\n : node.routePath)\n}\n\n/**\n * Removes the last segment from a given path. Segments are considered to be separated by a '/'.\n *\n * @param {string} routePath - The path from which to remove the last segment. Defaults to '/'.\n * @returns {string} The path with the last segment removed.\n * @example\n * removeLastSegmentFromPath('/workspace/_auth/foo') // '/workspace/_auth'\n */\nexport function removeLastSegmentFromPath(routePath: string = '/'): string {\n const segments = routePath.split('/')\n segments.pop() // Remove the last segment\n return segments.join('/')\n}\n\n/**\n * Removes all segments from a given path that start with an underscore ('_').\n *\n * @param {string} routePath - The path from which to remove segments. Defaults to '/'.\n * @returns {string} The path with all underscore-prefixed segments removed.\n * @example\n * removeLayoutSegments('/workspace/_auth/foo') // '/workspace/foo'\n */\nfunction removeLayoutSegments(routePath: string = '/'): string {\n const segments = routePath.split('/')\n const newSegments = segments.filter((segment) => !segment.startsWith('_'))\n return newSegments.join('/')\n}\n\nexport function hasParentRoute(\n routes: Array<RouteNode>,\n node: RouteNode,\n routePathToCheck: string | undefined,\n): RouteNode | null {\n if (!routePathToCheck || routePathToCheck === '/') {\n return null\n }\n\n const sortedNodes = multiSortBy(routes, [\n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue\n\n if (\n routePathToCheck.startsWith(`${route.routePath}/`) &&\n route.routePath !== routePathToCheck\n ) {\n return route\n }\n }\n\n const segments = routePathToCheck.split('/')\n segments.pop() // Remove the last segment\n const parentRoutePath = segments.join('/')\n\n return hasParentRoute(routes, node, parentRoutePath)\n}\n\n/**\n * Gets the final variable name for a route\n */\nexport const getResolvedRouteNodeVariableName = (\n routeNode: RouteNode,\n): string => {\n return routeNode.children?.length\n ? `${routeNode.variableName}RouteWithChildren`\n : `${routeNode.variableName}Route`\n}\n\n/**\n * Creates a map from fullPath to routeNode\n */\nexport const createRouteNodesByFullPath = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => [inferFullPath(routeNode), routeNode]),\n )\n}\n\n/**\n * Create a map from 'to' to a routeNode\n */\nexport const createRouteNodesByTo = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n dedupeBranchesAndIndexRoutes(routeNodes).map((routeNode) => [\n inferTo(routeNode),\n routeNode,\n ]),\n )\n}\n\n/**\n * Create a map from 'id' to a routeNode\n */\nexport const createRouteNodesById = (\n routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n return new Map(\n routeNodes.map((routeNode) => {\n const id = getFilePathIdFromPath(routeNode.routePath)\n return [id, routeNode]\n }),\n )\n}\n\n/**\n * Infers the full path for use by TS\n */\nexport const inferFullPath = (routeNode: RouteNode): string => {\n const fullPath = removeGroups(\n removeUnderscores(removeLayoutSegments(routeNode.routePath)) ?? '',\n )\n\n return routeNode.cleanedPath === '/' ? fullPath : fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Infers the path for use by TS\n */\nexport const inferPath = (routeNode: RouteNode): string => {\n return routeNode.cleanedPath === '/'\n ? routeNode.cleanedPath\n : (routeNode.cleanedPath?.replace(/\\/$/, '') ?? '')\n}\n\n/**\n * Infers to path\n */\nexport const inferTo = (routeNode: RouteNode): string => {\n const fullPath = inferFullPath(routeNode)\n\n if (fullPath === '/') return fullPath\n\n return fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Dedupes branches and index routes\n */\nexport const dedupeBranchesAndIndexRoutes = (\n routes: Array<RouteNode>,\n): Array<RouteNode> => {\n return routes.filter((route) => {\n if (route.children?.find((child) => child.cleanedPath === '/')) return false\n return true\n })\n}\n\nfunction getFilePathIdFromPath(pathname?: string) {\n const filePathId = removeTrailingUnderscores(pathname)\n return filePathId ?? ''\n}\n\nfunction checkUnique<TElement>(routes: Array<TElement>, key: keyof TElement) {\n // Check no two routes have the same `key`\n // if they do, throw an error with the conflicting filePaths\n const keys = routes.map((d) => d[key])\n const uniqueKeys = new Set(keys)\n if (keys.length !== uniqueKeys.size) {\n const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i)\n const conflictingFiles = routes.filter((d) =>\n duplicateKeys.includes(d[key]),\n )\n return conflictingFiles\n }\n return undefined\n}\n\nfunction checkRouteFullPathUniqueness(\n _routes: Array<RouteNode>,\n config: Config,\n) {\n const routes = _routes.map((d) => {\n const inferredFullPath = inferFullPath(d)\n return { ...d, inferredFullPath }\n })\n\n const conflictingFiles = checkUnique(routes, 'inferredFullPath')\n\n if (conflictingFiles !== undefined) {\n const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles\n .map((p) => `\"${p.inferredFullPath}\"`)\n .join(', ')}.\nPlease ensure each route has a unique full path.\nConflicting files: \\n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\\n ')}\\n`\n throw new Error(errorMessage)\n }\n}\n\nfunction checkStartAPIRoutes(_routes: Array<RouteNode>, config: Config) {\n if (_routes.length === 0) {\n return []\n }\n\n // Make sure these are valid URLs\n // Route Groups and Layout Routes aren't being removed since\n // you may want to have an API route that starts with an underscore\n // or be wrapped in parentheses\n const routes = _routes.map((d) => {\n const routePath = removeTrailingSlash(d.routePath ?? '')\n return { ...d, routePath }\n })\n\n const conflictingFiles = checkUnique(routes, 'routePath')\n\n if (conflictingFiles !== undefined) {\n const errorMessage = `Conflicting configuration paths were found for the following API route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles\n .map((p) => `\"${p}\"`)\n .join(', ')}.\n Please ensure each API route has a unique route path.\nConflicting files: \\n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\\n ')}\\n`\n throw new Error(errorMessage)\n }\n\n return routes\n}\n\nexport type StartAPIRoutePathSegment = {\n value: string\n type: 'path' | 'param' | 'splat'\n}\n\n/**\n * This function takes in a path in the format accepted by TanStack Router\n * and returns an array of path segments that can be used to generate\n * the pathname of the TanStack Start API route.\n *\n * @param src\n * @returns\n */\nexport function startAPIRouteSegmentsFromTSRFilePath(\n src: string,\n config: Config,\n): Array<StartAPIRoutePathSegment> {\n const routePath = determineInitialRoutePath(src)\n\n const parts = routePath\n .replaceAll('.', '/')\n .split('/')\n .filter((p) => !!p && p !== config.indexToken)\n const segments: Array<StartAPIRoutePathSegment> = parts.map((part) => {\n if (part.startsWith('$')) {\n if (part === '$') {\n return { value: part, type: 'splat' }\n }\n\n part.replaceAll('$', '')\n return { value: part, type: 'param' }\n }\n\n return { value: part, type: 'path' }\n })\n\n return segments\n}\n"],"names":["virtualGetRouteNodes","physicalGetRouteNodes","children"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
routePathToVariable,
|
|
7
7
|
} from '../../utils'
|
|
8
8
|
import { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'
|
|
9
|
-
import type {
|
|
9
|
+
import type { VirtualRouteNode } from '@tanstack/virtual-file-routes'
|
|
10
10
|
import type { GetRouteNodesResult, RouteNode } from '../../types'
|
|
11
11
|
import type { Config } from '../../config'
|
|
12
12
|
|
package/src/generator.ts
CHANGED
|
@@ -344,9 +344,16 @@ export const Route = createRootRoute({
|
|
|
344
344
|
for (const node of preRouteNodes.filter((d) => !d.isAPIRoute)) {
|
|
345
345
|
await handleNode(node)
|
|
346
346
|
}
|
|
347
|
+
checkRouteFullPathUniqueness(
|
|
348
|
+
preRouteNodes.filter(
|
|
349
|
+
(d) => !d.isAPIRoute && d.children === undefined && d.isLazy !== true,
|
|
350
|
+
),
|
|
351
|
+
config,
|
|
352
|
+
)
|
|
347
353
|
|
|
348
354
|
const startAPIRouteNodes: Array<RouteNode> = checkStartAPIRoutes(
|
|
349
355
|
preRouteNodes.filter((d) => d.isAPIRoute),
|
|
356
|
+
config,
|
|
350
357
|
)
|
|
351
358
|
|
|
352
359
|
const handleAPINode = async (node: RouteNode) => {
|
|
@@ -584,12 +591,10 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
584
591
|
interface FileRoutesByPath {
|
|
585
592
|
${routeNodes
|
|
586
593
|
.map((routeNode) => {
|
|
587
|
-
const
|
|
588
|
-
routeNode.routePath,
|
|
589
|
-
)
|
|
594
|
+
const filePathId = getFilePathIdFromPath(routeNode.routePath)
|
|
590
595
|
|
|
591
596
|
return `'${filePathId}': {
|
|
592
|
-
id: '${
|
|
597
|
+
id: '${filePathId}'
|
|
593
598
|
path: '${inferPath(routeNode)}'
|
|
594
599
|
fullPath: '${inferFullPath(routeNode)}'
|
|
595
600
|
preLoaderRoute: typeof ${routeNode.variableName}Import
|
|
@@ -654,24 +659,21 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
654
659
|
const routesManifest = {
|
|
655
660
|
__root__: {
|
|
656
661
|
filePath: rootRouteNode.filePath,
|
|
657
|
-
children: routeTree.map(
|
|
658
|
-
(d) => getFilePathIdAndRouteIdFromPath(d.routePath)[1],
|
|
659
|
-
),
|
|
662
|
+
children: routeTree.map((d) => getFilePathIdFromPath(d.routePath)),
|
|
660
663
|
},
|
|
661
664
|
...Object.fromEntries(
|
|
662
665
|
routeNodes.map((d) => {
|
|
663
|
-
const
|
|
666
|
+
const filePathId = getFilePathIdFromPath(d.routePath)
|
|
664
667
|
|
|
665
668
|
return [
|
|
666
|
-
|
|
669
|
+
filePathId,
|
|
667
670
|
{
|
|
668
671
|
filePath: d.filePath,
|
|
669
672
|
parent: d.parent?.routePath
|
|
670
|
-
?
|
|
673
|
+
? getFilePathIdFromPath(d.parent.routePath)
|
|
671
674
|
: undefined,
|
|
672
|
-
children: d.children?.map(
|
|
673
|
-
(childRoute)
|
|
674
|
-
getFilePathIdAndRouteIdFromPath(childRoute.routePath)[1],
|
|
675
|
+
children: d.children?.map((childRoute) =>
|
|
676
|
+
getFilePathIdFromPath(childRoute.routePath),
|
|
675
677
|
),
|
|
676
678
|
},
|
|
677
679
|
]
|
|
@@ -742,12 +744,6 @@ export const Route = createAPIFileRoute('${escapedRoutePath}')({
|
|
|
742
744
|
)
|
|
743
745
|
}
|
|
744
746
|
|
|
745
|
-
function spaces(d: number): string {
|
|
746
|
-
return Array.from({ length: d })
|
|
747
|
-
.map(() => ' ')
|
|
748
|
-
.join('')
|
|
749
|
-
}
|
|
750
|
-
|
|
751
747
|
function removeTrailingUnderscores(s?: string) {
|
|
752
748
|
return s?.replaceAll(/(_$)/gi, '').replaceAll(/(_\/)/gi, '/')
|
|
753
749
|
}
|
|
@@ -872,7 +868,7 @@ export const createRouteNodesById = (
|
|
|
872
868
|
): Map<string, RouteNode> => {
|
|
873
869
|
return new Map(
|
|
874
870
|
routeNodes.map((routeNode) => {
|
|
875
|
-
const
|
|
871
|
+
const id = getFilePathIdFromPath(routeNode.routePath)
|
|
876
872
|
return [id, routeNode]
|
|
877
873
|
}),
|
|
878
874
|
)
|
|
@@ -921,14 +917,48 @@ export const dedupeBranchesAndIndexRoutes = (
|
|
|
921
917
|
})
|
|
922
918
|
}
|
|
923
919
|
|
|
924
|
-
function
|
|
920
|
+
function getFilePathIdFromPath(pathname?: string) {
|
|
925
921
|
const filePathId = removeTrailingUnderscores(pathname)
|
|
926
|
-
|
|
922
|
+
return filePathId ?? ''
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
function checkUnique<TElement>(routes: Array<TElement>, key: keyof TElement) {
|
|
926
|
+
// Check no two routes have the same `key`
|
|
927
|
+
// if they do, throw an error with the conflicting filePaths
|
|
928
|
+
const keys = routes.map((d) => d[key])
|
|
929
|
+
const uniqueKeys = new Set(keys)
|
|
930
|
+
if (keys.length !== uniqueKeys.size) {
|
|
931
|
+
const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i)
|
|
932
|
+
const conflictingFiles = routes.filter((d) =>
|
|
933
|
+
duplicateKeys.includes(d[key]),
|
|
934
|
+
)
|
|
935
|
+
return conflictingFiles
|
|
936
|
+
}
|
|
937
|
+
return undefined
|
|
938
|
+
}
|
|
927
939
|
|
|
928
|
-
|
|
940
|
+
function checkRouteFullPathUniqueness(
|
|
941
|
+
_routes: Array<RouteNode>,
|
|
942
|
+
config: Config,
|
|
943
|
+
) {
|
|
944
|
+
const routes = _routes.map((d) => {
|
|
945
|
+
const inferredFullPath = inferFullPath(d)
|
|
946
|
+
return { ...d, inferredFullPath }
|
|
947
|
+
})
|
|
948
|
+
|
|
949
|
+
const conflictingFiles = checkUnique(routes, 'inferredFullPath')
|
|
950
|
+
|
|
951
|
+
if (conflictingFiles !== undefined) {
|
|
952
|
+
const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles
|
|
953
|
+
.map((p) => `"${p.inferredFullPath}"`)
|
|
954
|
+
.join(', ')}.
|
|
955
|
+
Please ensure each route has a unique full path.
|
|
956
|
+
Conflicting files: \n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\n ')}\n`
|
|
957
|
+
throw new Error(errorMessage)
|
|
958
|
+
}
|
|
929
959
|
}
|
|
930
960
|
|
|
931
|
-
function checkStartAPIRoutes(_routes: Array<RouteNode
|
|
961
|
+
function checkStartAPIRoutes(_routes: Array<RouteNode>, config: Config) {
|
|
932
962
|
if (_routes.length === 0) {
|
|
933
963
|
return []
|
|
934
964
|
}
|
|
@@ -942,22 +972,14 @@ function checkStartAPIRoutes(_routes: Array<RouteNode>) {
|
|
|
942
972
|
return { ...d, routePath }
|
|
943
973
|
})
|
|
944
974
|
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
if (routePaths.length !== uniqueRoutePaths.size) {
|
|
950
|
-
const duplicateRoutePaths = routePaths.filter(
|
|
951
|
-
(d, i) => routePaths.indexOf(d) !== i,
|
|
952
|
-
)
|
|
953
|
-
const conflictingFiles = routes
|
|
954
|
-
.filter((d) => duplicateRoutePaths.includes(d.routePath))
|
|
955
|
-
.map((d) => `${d.fullPath}`)
|
|
956
|
-
const errorMessage = `Conflicting configuration paths was for found for the following API route${duplicateRoutePaths.length > 1 ? 's' : ''}: ${duplicateRoutePaths
|
|
975
|
+
const conflictingFiles = checkUnique(routes, 'routePath')
|
|
976
|
+
|
|
977
|
+
if (conflictingFiles !== undefined) {
|
|
978
|
+
const errorMessage = `Conflicting configuration paths were found for the following API route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles
|
|
957
979
|
.map((p) => `"${p}"`)
|
|
958
980
|
.join(', ')}.
|
|
959
|
-
Please ensure each API route has a unique route path.
|
|
960
|
-
Conflicting files: \n ${conflictingFiles.join('\n ')}\n`
|
|
981
|
+
Please ensure each API route has a unique route path.
|
|
982
|
+
Conflicting files: \n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\n ')}\n`
|
|
961
983
|
throw new Error(errorMessage)
|
|
962
984
|
}
|
|
963
985
|
|