@tanstack/router-generator 1.141.7 → 1.141.9
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/config.cjs +1 -3
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.cts +10 -15
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +2 -4
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/filesystem/physical/getRouteNodes.d.cts +1 -1
- package/dist/cjs/generator.cjs +5 -18
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/types.d.cts +0 -1
- package/dist/cjs/utils.cjs +15 -132
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +7 -25
- package/dist/esm/config.d.ts +10 -15
- package/dist/esm/config.js +1 -3
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.d.ts +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js +2 -4
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/dist/esm/generator.js +6 -19
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/types.d.ts +0 -1
- package/dist/esm/utils.d.ts +7 -25
- package/dist/esm/utils.js +15 -132
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/config.ts +0 -2
- package/src/filesystem/physical/getRouteNodes.ts +1 -4
- package/src/generator.ts +4 -23
- package/src/types.ts +0 -1
- package/src/utils.ts +12 -188
package/dist/esm/config.js
CHANGED
|
@@ -38,9 +38,7 @@ const configSchema = baseConfigSchema.extend({
|
|
|
38
38
|
}).optional(),
|
|
39
39
|
experimental: z.object({
|
|
40
40
|
// TODO: This has been made stable and is now "autoCodeSplitting". Remove in next major version.
|
|
41
|
-
enableCodeSplitting: z.boolean().optional()
|
|
42
|
-
// TODO: This resolves issues with non-nested paths in file-based routing. To be made default in next major version.
|
|
43
|
-
nonNestedRoutes: z.boolean().optional()
|
|
41
|
+
enableCodeSplitting: z.boolean().optional()
|
|
44
42
|
}).optional(),
|
|
45
43
|
plugins: z.array(z.custom()).optional(),
|
|
46
44
|
tmpDir: z.string().optional().default(""),
|
package/dist/esm/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { z } from 'zod'\nimport { virtualRootRouteSchema } from './filesystem/virtual/config'\nimport type { GeneratorPlugin } from './plugin/types'\n\nexport const baseConfigSchema = z.object({\n target: z.enum(['react', 'solid', 'vue']).optional().default('react'),\n virtualRouteConfig: virtualRootRouteSchema.or(z.string()).optional(),\n routeFilePrefix: z.string().optional(),\n routeFileIgnorePrefix: z.string().optional().default('-'),\n routeFileIgnorePattern: z.string().optional(),\n routesDirectory: z.string().optional().default('./src/routes'),\n quoteStyle: z.enum(['single', 'double']).optional().default('single'),\n semicolons: z.boolean().optional().default(false),\n disableLogging: z.boolean().optional().default(false),\n routeTreeFileHeader: z\n .array(z.string())\n .optional()\n .default([\n '/* eslint-disable */',\n '// @ts-nocheck',\n '// noinspection JSUnusedGlobalSymbols',\n ]),\n indexToken: z.string().optional().default('index'),\n routeToken: z.string().optional().default('route'),\n pathParamsAllowedCharacters: z\n .array(z.enum([';', ':', '@', '&', '=', '+', '$', ',']))\n .optional(),\n})\n\nexport type BaseConfig = z.infer<typeof baseConfigSchema>\n\nexport const configSchema = baseConfigSchema.extend({\n generatedRouteTree: z.string().optional().default('./src/routeTree.gen.ts'),\n disableTypes: z.boolean().optional().default(false),\n verboseFileRoutes: z.boolean().optional(),\n addExtensions: z.boolean().optional().default(false),\n enableRouteTreeFormatting: z.boolean().optional().default(true),\n routeTreeFileFooter: z\n .union([\n z.array(z.string()).optional().default([]),\n z.function().returns(z.array(z.string())),\n ])\n .optional(),\n autoCodeSplitting: z.boolean().optional(),\n customScaffolding: z\n .object({\n routeTemplate: z.string().optional(),\n lazyRouteTemplate: z.string().optional(),\n })\n .optional(),\n experimental: z\n .object({\n // TODO: This has been made stable and is now \"autoCodeSplitting\". Remove in next major version.\n enableCodeSplitting: z.boolean().optional(),\n
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { z } from 'zod'\nimport { virtualRootRouteSchema } from './filesystem/virtual/config'\nimport type { GeneratorPlugin } from './plugin/types'\n\nexport const baseConfigSchema = z.object({\n target: z.enum(['react', 'solid', 'vue']).optional().default('react'),\n virtualRouteConfig: virtualRootRouteSchema.or(z.string()).optional(),\n routeFilePrefix: z.string().optional(),\n routeFileIgnorePrefix: z.string().optional().default('-'),\n routeFileIgnorePattern: z.string().optional(),\n routesDirectory: z.string().optional().default('./src/routes'),\n quoteStyle: z.enum(['single', 'double']).optional().default('single'),\n semicolons: z.boolean().optional().default(false),\n disableLogging: z.boolean().optional().default(false),\n routeTreeFileHeader: z\n .array(z.string())\n .optional()\n .default([\n '/* eslint-disable */',\n '// @ts-nocheck',\n '// noinspection JSUnusedGlobalSymbols',\n ]),\n indexToken: z.string().optional().default('index'),\n routeToken: z.string().optional().default('route'),\n pathParamsAllowedCharacters: z\n .array(z.enum([';', ':', '@', '&', '=', '+', '$', ',']))\n .optional(),\n})\n\nexport type BaseConfig = z.infer<typeof baseConfigSchema>\n\nexport const configSchema = baseConfigSchema.extend({\n generatedRouteTree: z.string().optional().default('./src/routeTree.gen.ts'),\n disableTypes: z.boolean().optional().default(false),\n verboseFileRoutes: z.boolean().optional(),\n addExtensions: z.boolean().optional().default(false),\n enableRouteTreeFormatting: z.boolean().optional().default(true),\n routeTreeFileFooter: z\n .union([\n z.array(z.string()).optional().default([]),\n z.function().returns(z.array(z.string())),\n ])\n .optional(),\n autoCodeSplitting: z.boolean().optional(),\n customScaffolding: z\n .object({\n routeTemplate: z.string().optional(),\n lazyRouteTemplate: z.string().optional(),\n })\n .optional(),\n experimental: z\n .object({\n // TODO: This has been made stable and is now \"autoCodeSplitting\". Remove in next major version.\n enableCodeSplitting: z.boolean().optional(),\n })\n .optional(),\n plugins: z.array(z.custom<GeneratorPlugin>()).optional(),\n tmpDir: z.string().optional().default(''),\n importRoutesUsingAbsolutePaths: z.boolean().optional().default(false),\n})\n\nexport type Config = z.infer<typeof configSchema>\n\ntype ResolveParams = {\n configDirectory: string\n}\n\nexport function resolveConfigPath({ configDirectory }: ResolveParams) {\n return path.resolve(configDirectory, 'tsr.config.json')\n}\n\nexport function getConfig(\n inlineConfig: Partial<Config> = {},\n configDirectory?: string,\n): Config {\n if (configDirectory === undefined) {\n configDirectory = process.cwd()\n }\n const configFilePathJson = resolveConfigPath({ configDirectory })\n const exists = existsSync(configFilePathJson)\n\n let config: Config\n\n if (exists) {\n config = configSchema.parse({\n ...JSON.parse(readFileSync(configFilePathJson, 'utf-8')),\n ...inlineConfig,\n })\n } else {\n config = configSchema.parse(inlineConfig)\n }\n\n // If typescript is disabled, make sure the generated route tree is a .js file\n if (config.disableTypes) {\n config.generatedRouteTree = config.generatedRouteTree.replace(\n /\\.(ts|tsx)$/,\n '.js',\n )\n }\n\n // if a configDirectory is used, paths should be relative to that directory\n if (configDirectory) {\n // if absolute configDirectory is provided, use it as the root\n if (path.isAbsolute(configDirectory)) {\n config.routesDirectory = path.resolve(\n configDirectory,\n config.routesDirectory,\n )\n config.generatedRouteTree = path.resolve(\n configDirectory,\n config.generatedRouteTree,\n )\n } else {\n config.routesDirectory = path.resolve(\n process.cwd(),\n configDirectory,\n config.routesDirectory,\n )\n config.generatedRouteTree = path.resolve(\n process.cwd(),\n configDirectory,\n config.generatedRouteTree,\n )\n }\n }\n\n const resolveTmpDir = (dir: string | Array<string>) => {\n if (Array.isArray(dir)) {\n dir = path.join(...dir)\n }\n if (!path.isAbsolute(dir)) {\n dir = path.resolve(process.cwd(), dir)\n }\n return dir\n }\n\n if (config.tmpDir) {\n config.tmpDir = resolveTmpDir(config.tmpDir)\n } else if (process.env.TSR_TMP_DIR) {\n config.tmpDir = resolveTmpDir(process.env.TSR_TMP_DIR)\n } else {\n config.tmpDir = resolveTmpDir(['.tanstack', 'tmp'])\n }\n\n validateConfig(config)\n return config\n}\n\nfunction validateConfig(config: Config) {\n if (typeof config.experimental?.enableCodeSplitting !== 'undefined') {\n const message = `\n------\n⚠️ ⚠️ ⚠️\nERROR: The \"experimental.enableCodeSplitting\" flag has been made stable and is now \"autoCodeSplitting\". Please update your configuration file to use \"autoCodeSplitting\" instead of \"experimental.enableCodeSplitting\".\n------\n`\n console.error(message)\n throw new Error(message)\n }\n\n if (config.indexToken === config.routeToken) {\n throw new Error(\n `The \"indexToken\" and \"routeToken\" options must be different.`,\n )\n }\n\n if (\n config.routeFileIgnorePrefix &&\n config.routeFileIgnorePrefix.trim() === '_'\n ) {\n throw new Error(\n `The \"routeFileIgnorePrefix\" cannot be an underscore (\"_\"). This is a reserved character used to denote a pathless route. Please use a different prefix.`,\n )\n }\n\n return config\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FsRouteType, GetRouteNodesResult } from '../../types.js';
|
|
2
2
|
import { Config } from '../../config.js';
|
|
3
3
|
export declare function isVirtualConfigFile(fileName: string): boolean;
|
|
4
|
-
export declare function getRouteNodes(config: Pick<Config, 'routesDirectory' | 'routeFilePrefix' | 'routeFileIgnorePrefix' | 'routeFileIgnorePattern' | 'disableLogging' | 'routeToken' | 'indexToken'
|
|
4
|
+
export declare function getRouteNodes(config: Pick<Config, 'routesDirectory' | 'routeFilePrefix' | 'routeFileIgnorePrefix' | 'routeFileIgnorePattern' | 'disableLogging' | 'routeToken' | 'indexToken'>, root: string): Promise<GetRouteNodesResult>;
|
|
5
5
|
/**
|
|
6
6
|
* Determines the metadata for a given route path based on the provided configuration.
|
|
7
7
|
*
|
|
@@ -84,9 +84,8 @@ async function getRouteNodes(config, root) {
|
|
|
84
84
|
const filePathNoExt = removeExt(filePath);
|
|
85
85
|
const {
|
|
86
86
|
routePath: initialRoutePath,
|
|
87
|
-
originalRoutePath: initialOriginalRoutePath
|
|
88
|
-
|
|
89
|
-
} = determineInitialRoutePath(filePathNoExt, config);
|
|
87
|
+
originalRoutePath: initialOriginalRoutePath
|
|
88
|
+
} = determineInitialRoutePath(filePathNoExt);
|
|
90
89
|
let routePath = initialRoutePath;
|
|
91
90
|
let originalRoutePath = initialOriginalRoutePath;
|
|
92
91
|
if (routeFilePrefix) {
|
|
@@ -156,7 +155,6 @@ async function getRouteNodes(config, root) {
|
|
|
156
155
|
routePath,
|
|
157
156
|
variableName,
|
|
158
157
|
_fsRouteType: routeType,
|
|
159
|
-
_isExperimentalNonNestedRoute: isExperimentalNonNestedRoute,
|
|
160
158
|
originalRoutePath
|
|
161
159
|
});
|
|
162
160
|
}
|
|
@@ -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 removeExt,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { logging } from '../../logger'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { FsRouteType, GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx|vue)/\n\nconst virtualConfigFileRegExp = /__virtual\\.[mc]?[jt]s$/\nexport function isVirtualConfigFile(fileName: string): boolean {\n return virtualConfigFileRegExp.test(fileName)\n}\n\nexport async function getRouteNodes(\n config: Pick<\n Config,\n | 'routesDirectory'\n | 'routeFilePrefix'\n | 'routeFileIgnorePrefix'\n | 'routeFileIgnorePattern'\n | 'disableLogging'\n | 'routeToken'\n | 'indexToken'\n | 'experimental'\n >,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n const allPhysicalDirectories: Array<string> = []\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 if (routeFileIgnorePattern) {\n return (\n d.name.startsWith(routeFilePrefix) &&\n !d.name.match(routeFileIgnoreRegExp)\n )\n }\n\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() && isVirtualConfigFile(dirent.name)\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, physicalDirectories } =\n await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n allPhysicalDirectories.push(...physicalDirectories)\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 = replaceBackslash(path.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|vue)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n const {\n routePath: initialRoutePath,\n originalRoutePath: initialOriginalRoutePath,\n isExperimentalNonNestedRoute,\n } = determineInitialRoutePath(filePathNoExt, config)\n\n let routePath = initialRoutePath\n let originalRoutePath = initialOriginalRoutePath\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n originalRoutePath = originalRoutePath.replaceAll(\n routeFilePrefix,\n '',\n )\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 meta = getRouteMeta(routePath, config)\n const variableName = meta.variableName\n let routeType: FsRouteType = meta.fsRouteType\n\n if (routeType === 'lazy') {\n routePath = routePath.replace(/\\/lazy$/, '')\n originalRoutePath = originalRoutePath.replace(/\\/lazy$/, '')\n }\n\n // this check needs to happen after the lazy route has been cleaned up\n // since the routePath is used to determine if a route is pathless\n if (isValidPathlessLayoutRoute(routePath, routeType, config)) {\n routeType = 'pathless_layout'\n }\n\n // Only show deprecation warning for .tsx/.ts files, not .vue files\n // Vue files using .component.vue is the Vue-native way\n const isVueFile = filePath.endsWith('.vue')\n if (!isVueFile) {\n ;(\n [\n ['component', 'component'],\n ['errorComponent', 'errorComponent'],\n ['notFoundComponent', 'notFoundComponent'],\n ['pendingComponent', 'pendingComponent'],\n ['loader', 'loader'],\n ] satisfies Array<[FsRouteType, string]>\n ).forEach(([matcher, type]) => {\n if (routeType === matcher) {\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\n routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|notFoundComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n originalRoutePath = originalRoutePath.replace(\n new RegExp(\n `/(component|errorComponent|notFoundComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n if (originalRoutePath === config.indexToken) {\n originalRoutePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n originalRoutePath =\n originalRoutePath.replace(\n new RegExp(`/${config.indexToken}$`),\n '/',\n ) || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n _fsRouteType: routeType,\n _isExperimentalNonNestedRoute: isExperimentalNonNestedRoute,\n originalRoutePath,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n // Find the root route node - prefer the actual route file over component/loader files\n const rootRouteNode =\n routeNodes.find(\n (d) =>\n d.routePath === `/${rootPathId}` &&\n ![\n 'component',\n 'errorComponent',\n 'notFoundComponent',\n 'pendingComponent',\n 'loader',\n 'lazy',\n ].includes(d._fsRouteType),\n ) ?? routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n if (rootRouteNode) {\n rootRouteNode._fsRouteType = '__root'\n rootRouteNode.variableName = 'root'\n }\n\n return {\n rootRouteNode,\n routeNodes,\n physicalDirectories: allPhysicalDirectories,\n }\n}\n\n/**\n * Determines the metadata for a given route path based on the provided configuration.\n *\n * @param routePath - The determined initial routePath.\n * @param config - The user configuration object.\n * @returns An object containing the type of the route and the variable name derived from the route path.\n */\nexport function getRouteMeta(\n routePath: string,\n config: Pick<Config, 'routeToken' | 'indexToken'>,\n): {\n // `__root` is can be more easily determined by filtering down to routePath === /${rootPathId}\n // `pathless` is needs to determined after `lazy` has been cleaned up from the routePath\n fsRouteType: Extract<\n FsRouteType,\n | 'static'\n | 'layout'\n | 'api'\n | 'lazy'\n | 'loader'\n | 'component'\n | 'pendingComponent'\n | 'errorComponent'\n | 'notFoundComponent'\n >\n variableName: string\n} {\n let fsRouteType: FsRouteType = 'static'\n\n if (routePath.endsWith(`/${config.routeToken}`)) {\n // layout routes, i.e `/foo/route.tsx` or `/foo/_layout/route.tsx`\n fsRouteType = 'layout'\n } else if (routePath.endsWith('/lazy')) {\n // lazy routes, i.e. `/foo.lazy.tsx`\n fsRouteType = 'lazy'\n } else if (routePath.endsWith('/loader')) {\n // loader routes, i.e. `/foo.loader.tsx`\n fsRouteType = 'loader'\n } else if (routePath.endsWith('/component')) {\n // component routes, i.e. `/foo.component.tsx`\n fsRouteType = 'component'\n } else if (routePath.endsWith('/pendingComponent')) {\n // pending component routes, i.e. `/foo.pendingComponent.tsx`\n fsRouteType = 'pendingComponent'\n } else if (routePath.endsWith('/errorComponent')) {\n // error component routes, i.e. `/foo.errorComponent.tsx`\n fsRouteType = 'errorComponent'\n } else if (routePath.endsWith('/notFoundComponent')) {\n // not found component routes, i.e. `/foo.notFoundComponent.tsx`\n fsRouteType = 'notFoundComponent'\n }\n\n const variableName = routePathToVariable(routePath)\n\n return { fsRouteType, variableName }\n}\n\n/**\n * Used to validate if a route is a pathless layout route\n * @param normalizedRoutePath Normalized route path, i.e `/foo/_layout/route.tsx` and `/foo._layout.route.tsx` to `/foo/_layout/route`\n * @param config The `router-generator` configuration object\n * @returns Boolean indicating if the route is a pathless layout route\n */\nfunction isValidPathlessLayoutRoute(\n normalizedRoutePath: string,\n routeType: FsRouteType,\n config: Pick<Config, 'routeToken' | 'indexToken'>,\n): boolean {\n if (routeType === 'lazy') {\n return false\n }\n\n const segments = normalizedRoutePath.split('/').filter(Boolean)\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 segment === __root, then exit as false\n if (lastRouteSegment === rootPathId) {\n return false\n }\n\n // If segment === config.routeToken and secondToLastSegment is a string that starts with _, then exit as true\n // Since the route is actually a configuration route for a layout/pathless route\n // i.e. /foo/_layout/route.tsx === /foo/_layout.tsx\n if (\n lastRouteSegment === config.routeToken &&\n typeof secondToLastRouteSegment === 'string'\n ) {\n return secondToLastRouteSegment.startsWith('_')\n }\n\n // Segment starts with _\n return (\n lastRouteSegment !== config.indexToken &&\n lastRouteSegment !== config.routeToken &&\n lastRouteSegment.startsWith('_')\n )\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 removeExt,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { logging } from '../../logger'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { FsRouteType, GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx|vue)/\n\nconst virtualConfigFileRegExp = /__virtual\\.[mc]?[jt]s$/\nexport function isVirtualConfigFile(fileName: string): boolean {\n return virtualConfigFileRegExp.test(fileName)\n}\n\nexport async function getRouteNodes(\n config: Pick<\n Config,\n | 'routesDirectory'\n | 'routeFilePrefix'\n | 'routeFileIgnorePrefix'\n | 'routeFileIgnorePattern'\n | 'disableLogging'\n | 'routeToken'\n | 'indexToken'\n >,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n const allPhysicalDirectories: Array<string> = []\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 if (routeFileIgnorePattern) {\n return (\n d.name.startsWith(routeFilePrefix) &&\n !d.name.match(routeFileIgnoreRegExp)\n )\n }\n\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() && isVirtualConfigFile(dirent.name)\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, physicalDirectories } =\n await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n allPhysicalDirectories.push(...physicalDirectories)\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 = replaceBackslash(path.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|vue)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n const {\n routePath: initialRoutePath,\n originalRoutePath: initialOriginalRoutePath,\n } = determineInitialRoutePath(filePathNoExt)\n\n let routePath = initialRoutePath\n let originalRoutePath = initialOriginalRoutePath\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n originalRoutePath = originalRoutePath.replaceAll(\n routeFilePrefix,\n '',\n )\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 meta = getRouteMeta(routePath, config)\n const variableName = meta.variableName\n let routeType: FsRouteType = meta.fsRouteType\n\n if (routeType === 'lazy') {\n routePath = routePath.replace(/\\/lazy$/, '')\n originalRoutePath = originalRoutePath.replace(/\\/lazy$/, '')\n }\n\n // this check needs to happen after the lazy route has been cleaned up\n // since the routePath is used to determine if a route is pathless\n if (isValidPathlessLayoutRoute(routePath, routeType, config)) {\n routeType = 'pathless_layout'\n }\n\n // Only show deprecation warning for .tsx/.ts files, not .vue files\n // Vue files using .component.vue is the Vue-native way\n const isVueFile = filePath.endsWith('.vue')\n if (!isVueFile) {\n ;(\n [\n ['component', 'component'],\n ['errorComponent', 'errorComponent'],\n ['notFoundComponent', 'notFoundComponent'],\n ['pendingComponent', 'pendingComponent'],\n ['loader', 'loader'],\n ] satisfies Array<[FsRouteType, string]>\n ).forEach(([matcher, type]) => {\n if (routeType === matcher) {\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\n routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|notFoundComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n originalRoutePath = originalRoutePath.replace(\n new RegExp(\n `/(component|errorComponent|notFoundComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n if (originalRoutePath === config.indexToken) {\n originalRoutePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n originalRoutePath =\n originalRoutePath.replace(\n new RegExp(`/${config.indexToken}$`),\n '/',\n ) || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n _fsRouteType: routeType,\n originalRoutePath,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n // Find the root route node - prefer the actual route file over component/loader files\n const rootRouteNode =\n routeNodes.find(\n (d) =>\n d.routePath === `/${rootPathId}` &&\n ![\n 'component',\n 'errorComponent',\n 'notFoundComponent',\n 'pendingComponent',\n 'loader',\n 'lazy',\n ].includes(d._fsRouteType),\n ) ?? routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n if (rootRouteNode) {\n rootRouteNode._fsRouteType = '__root'\n rootRouteNode.variableName = 'root'\n }\n\n return {\n rootRouteNode,\n routeNodes,\n physicalDirectories: allPhysicalDirectories,\n }\n}\n\n/**\n * Determines the metadata for a given route path based on the provided configuration.\n *\n * @param routePath - The determined initial routePath.\n * @param config - The user configuration object.\n * @returns An object containing the type of the route and the variable name derived from the route path.\n */\nexport function getRouteMeta(\n routePath: string,\n config: Pick<Config, 'routeToken' | 'indexToken'>,\n): {\n // `__root` is can be more easily determined by filtering down to routePath === /${rootPathId}\n // `pathless` is needs to determined after `lazy` has been cleaned up from the routePath\n fsRouteType: Extract<\n FsRouteType,\n | 'static'\n | 'layout'\n | 'api'\n | 'lazy'\n | 'loader'\n | 'component'\n | 'pendingComponent'\n | 'errorComponent'\n | 'notFoundComponent'\n >\n variableName: string\n} {\n let fsRouteType: FsRouteType = 'static'\n\n if (routePath.endsWith(`/${config.routeToken}`)) {\n // layout routes, i.e `/foo/route.tsx` or `/foo/_layout/route.tsx`\n fsRouteType = 'layout'\n } else if (routePath.endsWith('/lazy')) {\n // lazy routes, i.e. `/foo.lazy.tsx`\n fsRouteType = 'lazy'\n } else if (routePath.endsWith('/loader')) {\n // loader routes, i.e. `/foo.loader.tsx`\n fsRouteType = 'loader'\n } else if (routePath.endsWith('/component')) {\n // component routes, i.e. `/foo.component.tsx`\n fsRouteType = 'component'\n } else if (routePath.endsWith('/pendingComponent')) {\n // pending component routes, i.e. `/foo.pendingComponent.tsx`\n fsRouteType = 'pendingComponent'\n } else if (routePath.endsWith('/errorComponent')) {\n // error component routes, i.e. `/foo.errorComponent.tsx`\n fsRouteType = 'errorComponent'\n } else if (routePath.endsWith('/notFoundComponent')) {\n // not found component routes, i.e. `/foo.notFoundComponent.tsx`\n fsRouteType = 'notFoundComponent'\n }\n\n const variableName = routePathToVariable(routePath)\n\n return { fsRouteType, variableName }\n}\n\n/**\n * Used to validate if a route is a pathless layout route\n * @param normalizedRoutePath Normalized route path, i.e `/foo/_layout/route.tsx` and `/foo._layout.route.tsx` to `/foo/_layout/route`\n * @param config The `router-generator` configuration object\n * @returns Boolean indicating if the route is a pathless layout route\n */\nfunction isValidPathlessLayoutRoute(\n normalizedRoutePath: string,\n routeType: FsRouteType,\n config: Pick<Config, 'routeToken' | 'indexToken'>,\n): boolean {\n if (routeType === 'lazy') {\n return false\n }\n\n const segments = normalizedRoutePath.split('/').filter(Boolean)\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 segment === __root, then exit as false\n if (lastRouteSegment === rootPathId) {\n return false\n }\n\n // If segment === config.routeToken and secondToLastSegment is a string that starts with _, then exit as true\n // Since the route is actually a configuration route for a layout/pathless route\n // i.e. /foo/_layout/route.tsx === /foo/_layout.tsx\n if (\n lastRouteSegment === config.routeToken &&\n typeof secondToLastRouteSegment === 'string'\n ) {\n return secondToLastRouteSegment.startsWith('_')\n }\n\n // Segment starts with _\n return (\n lastRouteSegment !== config.indexToken &&\n lastRouteSegment !== config.routeToken &&\n lastRouteSegment.startsWith('_')\n )\n}\n"],"names":["getRouteNodesVirtual"],"mappings":"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"}
|
package/dist/esm/generator.js
CHANGED
|
@@ -7,7 +7,7 @@ import { logging } from "./logger.js";
|
|
|
7
7
|
import { getRouteNodes as getRouteNodes$1, isVirtualConfigFile } from "./filesystem/physical/getRouteNodes.js";
|
|
8
8
|
import { getRouteNodes } from "./filesystem/virtual/getRouteNodes.js";
|
|
9
9
|
import { rootPathId } from "./filesystem/physical/rootPathId.js";
|
|
10
|
-
import { multiSortBy, RoutePrefixMap, format, getImportForRouteNode, isRouteNodeValidForAugmentation, buildRouteTreeConfig, findParent, replaceBackslash, removeExt, createRouteNodesByFullPath, createRouteNodesByTo, createRouteNodesById, getResolvedRouteNodeVariableName, buildFileRoutesByPathInterface, checkRouteFullPathUniqueness, mergeImportDeclarations, buildImportString, checkFileExists, hasParentRoute, determineNodePath, trimPathLeft, removeGroups,
|
|
10
|
+
import { multiSortBy, RoutePrefixMap, format, getImportForRouteNode, isRouteNodeValidForAugmentation, buildRouteTreeConfig, findParent, replaceBackslash, removeExt, createRouteNodesByFullPath, createRouteNodesByTo, createRouteNodesById, getResolvedRouteNodeVariableName, buildFileRoutesByPathInterface, checkRouteFullPathUniqueness, mergeImportDeclarations, buildImportString, checkFileExists, hasParentRoute, determineNodePath, trimPathLeft, removeGroups, removeUnderscores, removeLayoutSegments, removeTrailingSlash, removeLastSegmentFromPath, getImportPath } from "./utils.js";
|
|
11
11
|
import { getTargetTemplate, fillTemplate } from "./template.js";
|
|
12
12
|
import { transform } from "./transform/transform.js";
|
|
13
13
|
const DefaultFileSystem = {
|
|
@@ -537,11 +537,8 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId}.${this.config.dis
|
|
|
537
537
|
let fileRoutesByPathInterface = "";
|
|
538
538
|
let fileRoutesByFullPath = "";
|
|
539
539
|
if (!config.disableTypes) {
|
|
540
|
-
const routeNodesByFullPath = createRouteNodesByFullPath(
|
|
541
|
-
|
|
542
|
-
config
|
|
543
|
-
);
|
|
544
|
-
const routeNodesByTo = createRouteNodesByTo(acc.routeNodes, config);
|
|
540
|
+
const routeNodesByFullPath = createRouteNodesByFullPath(acc.routeNodes);
|
|
541
|
+
const routeNodesByTo = createRouteNodesByTo(acc.routeNodes);
|
|
545
542
|
const routeNodesById = createRouteNodesById(acc.routeNodes);
|
|
546
543
|
fileRoutesByFullPath = [
|
|
547
544
|
`export interface FileRoutesByFullPath {
|
|
@@ -575,8 +572,7 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
575
572
|
fileRoutesByPathInterface = buildFileRoutesByPathInterface({
|
|
576
573
|
module: this.targetTemplate.fullPkg,
|
|
577
574
|
interfaceName: "FileRoutesByPath",
|
|
578
|
-
routeNodes: sortedRouteNodes
|
|
579
|
-
config
|
|
575
|
+
routeNodes: sortedRouteNodes
|
|
580
576
|
});
|
|
581
577
|
}
|
|
582
578
|
const routeTree = [
|
|
@@ -930,13 +926,7 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
930
926
|
return this.crawlingResult;
|
|
931
927
|
}
|
|
932
928
|
static handleNode(node, acc, prefixMap, config) {
|
|
933
|
-
const
|
|
934
|
-
const parentRoute = hasParentRoute(
|
|
935
|
-
prefixMap,
|
|
936
|
-
node,
|
|
937
|
-
node.routePath,
|
|
938
|
-
node.originalRoutePath
|
|
939
|
-
);
|
|
929
|
+
const parentRoute = hasParentRoute(prefixMap, node, node.routePath);
|
|
940
930
|
if (parentRoute) node.parent = parentRoute;
|
|
941
931
|
node.path = determineNodePath(node);
|
|
942
932
|
const trimmedPath = trimPathLeft(node.path ?? "");
|
|
@@ -944,10 +934,7 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
|
|
|
944
934
|
const lastRouteSegment = split[split.length - 1] ?? trimmedPath;
|
|
945
935
|
node.isNonPath = lastRouteSegment.startsWith("_") || split.every((part) => this.routeGroupPatternRegex.test(part));
|
|
946
936
|
node.cleanedPath = removeGroups(
|
|
947
|
-
(
|
|
948
|
-
removeLayoutSegments(node.path ?? ""),
|
|
949
|
-
config?.routeToken ?? ""
|
|
950
|
-
) : removeUnderscores(removeLayoutSegments(node.path))) ?? ""
|
|
937
|
+
removeUnderscores(removeLayoutSegments(node.path)) ?? ""
|
|
951
938
|
);
|
|
952
939
|
if (node._fsRouteType === "layout" || node._fsRouteType === "pathless_layout") {
|
|
953
940
|
node.cleanedPath = removeTrailingSlash(node.cleanedPath);
|