@tanstack/router-generator 1.99.6 → 1.99.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +18 -2
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js +18 -2
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/package.json +2 -2
- package/src/filesystem/physical/getRouteNodes.ts +33 -6
|
@@ -114,8 +114,7 @@ async function getRouteNodes(config, root) {
|
|
|
114
114
|
`${utils.removeTrailingSlash(config.apiBase)}/`
|
|
115
115
|
);
|
|
116
116
|
const segments = routePath.split("/");
|
|
117
|
-
const
|
|
118
|
-
const isLayout = lastRouteSegment !== config.indexToken && lastRouteSegment !== config.routeToken && (lastRouteSegment == null ? void 0 : lastRouteSegment.startsWith("_")) || false;
|
|
117
|
+
const isLayout = determineIsLayout({ segments, config });
|
|
119
118
|
[
|
|
120
119
|
[isComponent, "component"],
|
|
121
120
|
[isErrorComponent, "errorComponent"],
|
|
@@ -161,5 +160,22 @@ async function getRouteNodes(config, root) {
|
|
|
161
160
|
const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId.rootPathId}`);
|
|
162
161
|
return { rootRouteNode, routeNodes };
|
|
163
162
|
}
|
|
163
|
+
function determineIsLayout({
|
|
164
|
+
segments,
|
|
165
|
+
config
|
|
166
|
+
}) {
|
|
167
|
+
if (segments.length === 0) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const lastRouteSegment = segments[segments.length - 1];
|
|
171
|
+
const secondToLastRouteSegment = segments[segments.length - 2];
|
|
172
|
+
if (lastRouteSegment === rootPathId.rootPathId) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
if (lastRouteSegment === config.routeToken && typeof secondToLastRouteSegment === "string") {
|
|
176
|
+
return secondToLastRouteSegment.startsWith("_");
|
|
177
|
+
}
|
|
178
|
+
return lastRouteSegment !== config.indexToken && lastRouteSegment !== config.routeToken && lastRouteSegment.startsWith("_");
|
|
179
|
+
}
|
|
164
180
|
exports.getRouteNodes = getRouteNodes;
|
|
165
181
|
//# sourceMappingURL=getRouteNodes.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n logging,\n removeExt,\n removeTrailingSlash,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\n\nexport async function getRouteNodes(\n config: Config,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && dirent.name.match(/__virtual\\.[mc]?[jt]s$/)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes } = await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = path.posix.join(fullDir, dirent.name)\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n let routePath = determineInitialRoutePath(filePathNoExt)\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n }\n\n if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n logger.error(`ERROR: ${errorMessage}`)\n throw new Error(errorMessage)\n }\n\n const variableName = routePathToVariable(routePath)\n\n const isLazy = routePath.endsWith('/lazy')\n\n if (isLazy) {\n routePath = routePath.replace(/\\/lazy$/, '')\n }\n\n const isRoute = routePath.endsWith(`/${config.routeToken}`)\n const isComponent = routePath.endsWith('/component')\n const isErrorComponent = routePath.endsWith('/errorComponent')\n const isPendingComponent = routePath.endsWith('/pendingComponent')\n const isLoader = routePath.endsWith('/loader')\n const isAPIRoute = routePath.startsWith(\n `${removeTrailingSlash(config.apiBase)}/`,\n )\n\n const segments = routePath.split('/')\n const lastRouteSegment = segments[segments.length - 1]\n const isLayout =\n (lastRouteSegment !== config.indexToken &&\n lastRouteSegment !== config.routeToken &&\n lastRouteSegment?.startsWith('_')) ||\n false\n\n ;(\n [\n [isComponent, 'component'],\n [isErrorComponent, 'errorComponent'],\n [isPendingComponent, 'pendingComponent'],\n [isLoader, 'loader'],\n ] as const\n ).forEach(([isType, type]) => {\n if (isType) {\n logger.warn(\n `WARNING: The \\`.${type}.tsx\\` suffix used for the ${filePath} file is deprecated. Use the new \\`.lazy.tsx\\` suffix instead.`,\n )\n }\n })\n\n routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n isRoute,\n isComponent,\n isErrorComponent,\n isPendingComponent,\n isLoader,\n isLazy,\n isLayout,\n isAPIRoute,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n return { rootRouteNode, routeNodes }\n}\n"],"names":["logging","fsp","loadConfigFile","getRouteNodesVirtual","replaceBackslash","routePathToVariable","removeExt","determineInitialRoutePath","removeTrailingSlash","rootPathId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n logging,\n removeExt,\n removeTrailingSlash,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\n\nexport async function getRouteNodes(\n config: Config,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && dirent.name.match(/__virtual\\.[mc]?[jt]s$/)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes } = await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = path.posix.join(fullDir, dirent.name)\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n let routePath = determineInitialRoutePath(filePathNoExt)\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n }\n\n if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n logger.error(`ERROR: ${errorMessage}`)\n throw new Error(errorMessage)\n }\n\n const variableName = routePathToVariable(routePath)\n\n const isLazy = routePath.endsWith('/lazy')\n\n if (isLazy) {\n routePath = routePath.replace(/\\/lazy$/, '')\n }\n\n const isRoute = routePath.endsWith(`/${config.routeToken}`)\n const isComponent = routePath.endsWith('/component')\n const isErrorComponent = routePath.endsWith('/errorComponent')\n const isPendingComponent = routePath.endsWith('/pendingComponent')\n const isLoader = routePath.endsWith('/loader')\n const isAPIRoute = routePath.startsWith(\n `${removeTrailingSlash(config.apiBase)}/`,\n )\n\n const segments = routePath.split('/')\n const isLayout = determineIsLayout({ segments, config })\n\n ;(\n [\n [isComponent, 'component'],\n [isErrorComponent, 'errorComponent'],\n [isPendingComponent, 'pendingComponent'],\n [isLoader, 'loader'],\n ] as const\n ).forEach(([isType, type]) => {\n if (isType) {\n logger.warn(\n `WARNING: The \\`.${type}.tsx\\` suffix used for the ${filePath} file is deprecated. Use the new \\`.lazy.tsx\\` suffix instead.`,\n )\n }\n })\n\n routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n isRoute,\n isComponent,\n isErrorComponent,\n isPendingComponent,\n isLoader,\n isLazy,\n isLayout,\n isAPIRoute,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n return { rootRouteNode, routeNodes }\n}\n\nfunction determineIsLayout({\n segments,\n config,\n}: {\n segments: Array<string>\n config: Config\n}) {\n if (segments.length === 0) {\n return false\n }\n\n const lastRouteSegment = segments[segments.length - 1]!\n const secondToLastRouteSegment = segments[segments.length - 2]\n\n if (lastRouteSegment === rootPathId) {\n return false\n }\n\n if (\n lastRouteSegment === config.routeToken &&\n typeof secondToLastRouteSegment === 'string'\n ) {\n return secondToLastRouteSegment.startsWith('_')\n }\n\n return (\n lastRouteSegment !== config.indexToken &&\n lastRouteSegment !== config.routeToken &&\n lastRouteSegment.startsWith('_')\n )\n}\n"],"names":["logging","fsp","loadConfigFile","getRouteNodesVirtual","replaceBackslash","routePathToVariable","removeExt","determineInitialRoutePath","removeTrailingSlash","rootPathId"],"mappings":"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"}
|
|
@@ -95,8 +95,7 @@ async function getRouteNodes(config, root) {
|
|
|
95
95
|
`${removeTrailingSlash(config.apiBase)}/`
|
|
96
96
|
);
|
|
97
97
|
const segments = routePath.split("/");
|
|
98
|
-
const
|
|
99
|
-
const isLayout = lastRouteSegment !== config.indexToken && lastRouteSegment !== config.routeToken && (lastRouteSegment == null ? void 0 : lastRouteSegment.startsWith("_")) || false;
|
|
98
|
+
const isLayout = determineIsLayout({ segments, config });
|
|
100
99
|
[
|
|
101
100
|
[isComponent, "component"],
|
|
102
101
|
[isErrorComponent, "errorComponent"],
|
|
@@ -142,6 +141,23 @@ async function getRouteNodes(config, root) {
|
|
|
142
141
|
const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId}`);
|
|
143
142
|
return { rootRouteNode, routeNodes };
|
|
144
143
|
}
|
|
144
|
+
function determineIsLayout({
|
|
145
|
+
segments,
|
|
146
|
+
config
|
|
147
|
+
}) {
|
|
148
|
+
if (segments.length === 0) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
const lastRouteSegment = segments[segments.length - 1];
|
|
152
|
+
const secondToLastRouteSegment = segments[segments.length - 2];
|
|
153
|
+
if (lastRouteSegment === rootPathId) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (lastRouteSegment === config.routeToken && typeof secondToLastRouteSegment === "string") {
|
|
157
|
+
return secondToLastRouteSegment.startsWith("_");
|
|
158
|
+
}
|
|
159
|
+
return lastRouteSegment !== config.indexToken && lastRouteSegment !== config.routeToken && lastRouteSegment.startsWith("_");
|
|
160
|
+
}
|
|
145
161
|
export {
|
|
146
162
|
getRouteNodes
|
|
147
163
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n logging,\n removeExt,\n removeTrailingSlash,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\n\nexport async function getRouteNodes(\n config: Config,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && dirent.name.match(/__virtual\\.[mc]?[jt]s$/)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes } = await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = path.posix.join(fullDir, dirent.name)\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n let routePath = determineInitialRoutePath(filePathNoExt)\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n }\n\n if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n logger.error(`ERROR: ${errorMessage}`)\n throw new Error(errorMessage)\n }\n\n const variableName = routePathToVariable(routePath)\n\n const isLazy = routePath.endsWith('/lazy')\n\n if (isLazy) {\n routePath = routePath.replace(/\\/lazy$/, '')\n }\n\n const isRoute = routePath.endsWith(`/${config.routeToken}`)\n const isComponent = routePath.endsWith('/component')\n const isErrorComponent = routePath.endsWith('/errorComponent')\n const isPendingComponent = routePath.endsWith('/pendingComponent')\n const isLoader = routePath.endsWith('/loader')\n const isAPIRoute = routePath.startsWith(\n `${removeTrailingSlash(config.apiBase)}/`,\n )\n\n const segments = routePath.split('/')\n const lastRouteSegment = segments[segments.length - 1]\n const isLayout =\n (lastRouteSegment !== config.indexToken &&\n lastRouteSegment !== config.routeToken &&\n lastRouteSegment?.startsWith('_')) ||\n false\n\n ;(\n [\n [isComponent, 'component'],\n [isErrorComponent, 'errorComponent'],\n [isPendingComponent, 'pendingComponent'],\n [isLoader, 'loader'],\n ] as const\n ).forEach(([isType, type]) => {\n if (isType) {\n logger.warn(\n `WARNING: The \\`.${type}.tsx\\` suffix used for the ${filePath} file is deprecated. Use the new \\`.lazy.tsx\\` suffix instead.`,\n )\n }\n })\n\n routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n isRoute,\n isComponent,\n isErrorComponent,\n isPendingComponent,\n isLoader,\n isLazy,\n isLayout,\n isAPIRoute,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n return { rootRouteNode, routeNodes }\n}\n"],"names":["getRouteNodesVirtual"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n logging,\n removeExt,\n removeTrailingSlash,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\n\nexport async function getRouteNodes(\n config: Config,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && dirent.name.match(/__virtual\\.[mc]?[jt]s$/)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes } = await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = path.posix.join(fullDir, dirent.name)\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n let routePath = determineInitialRoutePath(filePathNoExt)\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n }\n\n if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n logger.error(`ERROR: ${errorMessage}`)\n throw new Error(errorMessage)\n }\n\n const variableName = routePathToVariable(routePath)\n\n const isLazy = routePath.endsWith('/lazy')\n\n if (isLazy) {\n routePath = routePath.replace(/\\/lazy$/, '')\n }\n\n const isRoute = routePath.endsWith(`/${config.routeToken}`)\n const isComponent = routePath.endsWith('/component')\n const isErrorComponent = routePath.endsWith('/errorComponent')\n const isPendingComponent = routePath.endsWith('/pendingComponent')\n const isLoader = routePath.endsWith('/loader')\n const isAPIRoute = routePath.startsWith(\n `${removeTrailingSlash(config.apiBase)}/`,\n )\n\n const segments = routePath.split('/')\n const isLayout = determineIsLayout({ segments, config })\n\n ;(\n [\n [isComponent, 'component'],\n [isErrorComponent, 'errorComponent'],\n [isPendingComponent, 'pendingComponent'],\n [isLoader, 'loader'],\n ] as const\n ).forEach(([isType, type]) => {\n if (isType) {\n logger.warn(\n `WARNING: The \\`.${type}.tsx\\` suffix used for the ${filePath} file is deprecated. Use the new \\`.lazy.tsx\\` suffix instead.`,\n )\n }\n })\n\n routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n isRoute,\n isComponent,\n isErrorComponent,\n isPendingComponent,\n isLoader,\n isLazy,\n isLayout,\n isAPIRoute,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n return { rootRouteNode, routeNodes }\n}\n\nfunction determineIsLayout({\n segments,\n config,\n}: {\n segments: Array<string>\n config: Config\n}) {\n if (segments.length === 0) {\n return false\n }\n\n const lastRouteSegment = segments[segments.length - 1]!\n const secondToLastRouteSegment = segments[segments.length - 2]\n\n if (lastRouteSegment === rootPathId) {\n return false\n }\n\n if (\n lastRouteSegment === config.routeToken &&\n typeof secondToLastRouteSegment === 'string'\n ) {\n return secondToLastRouteSegment.startsWith('_')\n }\n\n return (\n lastRouteSegment !== config.indexToken &&\n lastRouteSegment !== config.routeToken &&\n lastRouteSegment.startsWith('_')\n )\n}\n"],"names":["getRouteNodesVirtual"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/router-generator",
|
|
3
|
-
"version": "1.99.
|
|
3
|
+
"version": "1.99.7",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@tanstack/virtual-file-routes": "^1.99.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@tanstack/react-router": "^1.99.
|
|
58
|
+
"@tanstack/react-router": "^1.99.7"
|
|
59
59
|
},
|
|
60
60
|
"peerDependenciesMeta": {
|
|
61
61
|
"@tanstack/react-router": {
|
|
@@ -137,12 +137,7 @@ export async function getRouteNodes(
|
|
|
137
137
|
)
|
|
138
138
|
|
|
139
139
|
const segments = routePath.split('/')
|
|
140
|
-
const
|
|
141
|
-
const isLayout =
|
|
142
|
-
(lastRouteSegment !== config.indexToken &&
|
|
143
|
-
lastRouteSegment !== config.routeToken &&
|
|
144
|
-
lastRouteSegment?.startsWith('_')) ||
|
|
145
|
-
false
|
|
140
|
+
const isLayout = determineIsLayout({ segments, config })
|
|
146
141
|
|
|
147
142
|
;(
|
|
148
143
|
[
|
|
@@ -199,3 +194,35 @@ export async function getRouteNodes(
|
|
|
199
194
|
const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId}`)
|
|
200
195
|
return { rootRouteNode, routeNodes }
|
|
201
196
|
}
|
|
197
|
+
|
|
198
|
+
function determineIsLayout({
|
|
199
|
+
segments,
|
|
200
|
+
config,
|
|
201
|
+
}: {
|
|
202
|
+
segments: Array<string>
|
|
203
|
+
config: Config
|
|
204
|
+
}) {
|
|
205
|
+
if (segments.length === 0) {
|
|
206
|
+
return false
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const lastRouteSegment = segments[segments.length - 1]!
|
|
210
|
+
const secondToLastRouteSegment = segments[segments.length - 2]
|
|
211
|
+
|
|
212
|
+
if (lastRouteSegment === rootPathId) {
|
|
213
|
+
return false
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (
|
|
217
|
+
lastRouteSegment === config.routeToken &&
|
|
218
|
+
typeof secondToLastRouteSegment === 'string'
|
|
219
|
+
) {
|
|
220
|
+
return secondToLastRouteSegment.startsWith('_')
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
lastRouteSegment !== config.indexToken &&
|
|
225
|
+
lastRouteSegment !== config.routeToken &&
|
|
226
|
+
lastRouteSegment.startsWith('_')
|
|
227
|
+
)
|
|
228
|
+
}
|