@tanstack/router-generator 1.139.13 → 1.140.0
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 -1
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.cts +6 -6
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +32 -17
- 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 +141 -42
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/template.cjs +47 -0
- package/dist/cjs/template.cjs.map +1 -1
- package/dist/cjs/types.d.cts +2 -1
- package/dist/esm/config.d.ts +6 -6
- package/dist/esm/config.js +1 -1
- 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 +32 -17
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/dist/esm/generator.js +141 -42
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/template.js +47 -0
- package/dist/esm/template.js.map +1 -1
- package/dist/esm/types.d.ts +2 -1
- package/package.json +6 -6
- package/src/config.ts +1 -1
- package/src/filesystem/physical/getRouteNodes.ts +42 -19
- package/src/generator.ts +208 -54
- package/src/template.ts +65 -0
- package/src/types.ts +2 -0
package/dist/cjs/config.cjs
CHANGED
|
@@ -5,7 +5,7 @@ const node_fs = require("node:fs");
|
|
|
5
5
|
const zod = require("zod");
|
|
6
6
|
const config = require("./filesystem/virtual/config.cjs");
|
|
7
7
|
const baseConfigSchema = zod.z.object({
|
|
8
|
-
target: zod.z.enum(["react", "solid"]).optional().default("react"),
|
|
8
|
+
target: zod.z.enum(["react", "solid", "vue"]).optional().default("react"),
|
|
9
9
|
virtualRouteConfig: config.virtualRootRouteSchema.or(zod.z.string()).optional(),
|
|
10
10
|
routeFilePrefix: zod.z.string().optional(),
|
|
11
11
|
routeFileIgnorePrefix: zod.z.string().optional().default("-"),
|
package/dist/cjs/config.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","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']).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 // TODO: This resolves issues with non-nested paths in file-based routing. To be made default in next major version.\n nonNestedRoutes: 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":["z","virtualRootRouteSchema","existsSync","config","readFileSync"],"mappings":";;;;;;AAMO,MAAM,mBAAmBA,IAAAA,EAAE,OAAO;AAAA,EACvC,QAAQA,IAAAA,EAAE,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"config.cjs","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 // TODO: This resolves issues with non-nested paths in file-based routing. To be made default in next major version.\n nonNestedRoutes: 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":["z","virtualRootRouteSchema","existsSync","config","readFileSync"],"mappings":"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"}
|
package/dist/cjs/config.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { GeneratorPlugin } from './plugin/types.cjs';
|
|
3
3
|
export declare const baseConfigSchema: z.ZodObject<{
|
|
4
|
-
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<["react", "solid"]>>>;
|
|
4
|
+
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<["react", "solid", "vue"]>>>;
|
|
5
5
|
virtualRouteConfig: z.ZodOptional<z.ZodUnion<[z.ZodType<import('@tanstack/virtual-file-routes').VirtualRootRoute, z.ZodTypeDef, import('@tanstack/virtual-file-routes').VirtualRootRoute>, z.ZodString]>>;
|
|
6
6
|
routeFilePrefix: z.ZodOptional<z.ZodString>;
|
|
7
7
|
routeFileIgnorePrefix: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -15,7 +15,7 @@ export declare const baseConfigSchema: z.ZodObject<{
|
|
|
15
15
|
routeToken: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
16
16
|
pathParamsAllowedCharacters: z.ZodOptional<z.ZodArray<z.ZodEnum<[";", ":", "@", "&", "=", "+", "$", ","]>, "many">>;
|
|
17
17
|
}, "strip", z.ZodTypeAny, {
|
|
18
|
-
target: "react" | "solid";
|
|
18
|
+
target: "react" | "solid" | "vue";
|
|
19
19
|
routeFileIgnorePrefix: string;
|
|
20
20
|
routesDirectory: string;
|
|
21
21
|
quoteStyle: "single" | "double";
|
|
@@ -29,7 +29,7 @@ export declare const baseConfigSchema: z.ZodObject<{
|
|
|
29
29
|
routeFileIgnorePattern?: string | undefined;
|
|
30
30
|
pathParamsAllowedCharacters?: (";" | ":" | "@" | "&" | "=" | "+" | "$" | ",")[] | undefined;
|
|
31
31
|
}, {
|
|
32
|
-
target?: "react" | "solid" | undefined;
|
|
32
|
+
target?: "react" | "solid" | "vue" | undefined;
|
|
33
33
|
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
34
34
|
routeFilePrefix?: string | undefined;
|
|
35
35
|
routeFileIgnorePrefix?: string | undefined;
|
|
@@ -45,7 +45,7 @@ export declare const baseConfigSchema: z.ZodObject<{
|
|
|
45
45
|
}>;
|
|
46
46
|
export type BaseConfig = z.infer<typeof baseConfigSchema>;
|
|
47
47
|
export declare const configSchema: z.ZodObject<{
|
|
48
|
-
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<["react", "solid"]>>>;
|
|
48
|
+
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<["react", "solid", "vue"]>>>;
|
|
49
49
|
virtualRouteConfig: z.ZodOptional<z.ZodUnion<[z.ZodType<import('@tanstack/virtual-file-routes').VirtualRootRoute, z.ZodTypeDef, import('@tanstack/virtual-file-routes').VirtualRootRoute>, z.ZodString]>>;
|
|
50
50
|
routeFilePrefix: z.ZodOptional<z.ZodString>;
|
|
51
51
|
routeFileIgnorePrefix: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -90,7 +90,7 @@ export declare const configSchema: z.ZodObject<{
|
|
|
90
90
|
tmpDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
91
91
|
importRoutesUsingAbsolutePaths: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
92
92
|
}, "strip", z.ZodTypeAny, {
|
|
93
|
-
target: "react" | "solid";
|
|
93
|
+
target: "react" | "solid" | "vue";
|
|
94
94
|
routeFileIgnorePrefix: string;
|
|
95
95
|
routesDirectory: string;
|
|
96
96
|
quoteStyle: "single" | "double";
|
|
@@ -122,7 +122,7 @@ export declare const configSchema: z.ZodObject<{
|
|
|
122
122
|
} | undefined;
|
|
123
123
|
plugins?: GeneratorPlugin[] | undefined;
|
|
124
124
|
}, {
|
|
125
|
-
target?: "react" | "solid" | undefined;
|
|
125
|
+
target?: "react" | "solid" | "vue" | undefined;
|
|
126
126
|
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
127
127
|
routeFilePrefix?: string | undefined;
|
|
128
128
|
routeFileIgnorePrefix?: string | undefined;
|
|
@@ -24,7 +24,7 @@ function _interopNamespaceDefault(e) {
|
|
|
24
24
|
return Object.freeze(n);
|
|
25
25
|
}
|
|
26
26
|
const fsp__namespace = /* @__PURE__ */ _interopNamespaceDefault(fsp);
|
|
27
|
-
const disallowedRouteGroupConfiguration = /\(([^)]+)\).(ts|js|tsx|jsx)/;
|
|
27
|
+
const disallowedRouteGroupConfiguration = /\(([^)]+)\).(ts|js|tsx|jsx|vue)/;
|
|
28
28
|
const virtualConfigFileRegExp = /__virtual\.[mc]?[jt]s$/;
|
|
29
29
|
function isVirtualConfigFile(fileName) {
|
|
30
30
|
return virtualConfigFileRegExp.test(fileName);
|
|
@@ -98,7 +98,7 @@ async function getRouteNodes(config, root) {
|
|
|
98
98
|
const relativePath = path.posix.join(dir, dirent.name);
|
|
99
99
|
if (dirent.isDirectory()) {
|
|
100
100
|
await recurse(relativePath);
|
|
101
|
-
} else if (fullPath.match(/\.(tsx|ts|jsx|js)$/)) {
|
|
101
|
+
} else if (fullPath.match(/\.(tsx|ts|jsx|js|vue)$/)) {
|
|
102
102
|
const filePath = utils.replaceBackslash(path.join(dir, dirent.name));
|
|
103
103
|
const filePathNoExt = utils.removeExt(filePath);
|
|
104
104
|
const {
|
|
@@ -130,27 +130,31 @@ async function getRouteNodes(config, root) {
|
|
|
130
130
|
if (isValidPathlessLayoutRoute(routePath, routeType, config)) {
|
|
131
131
|
routeType = "pathless_layout";
|
|
132
132
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
[
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
133
|
+
const isVueFile = filePath.endsWith(".vue");
|
|
134
|
+
if (!isVueFile) {
|
|
135
|
+
[
|
|
136
|
+
["component", "component"],
|
|
137
|
+
["errorComponent", "errorComponent"],
|
|
138
|
+
["notFoundComponent", "notFoundComponent"],
|
|
139
|
+
["pendingComponent", "pendingComponent"],
|
|
140
|
+
["loader", "loader"]
|
|
141
|
+
].forEach(([matcher, type]) => {
|
|
142
|
+
if (routeType === matcher) {
|
|
143
|
+
logger$1.warn(
|
|
144
|
+
`WARNING: The \`.${type}.tsx\` suffix used for the ${filePath} file is deprecated. Use the new \`.lazy.tsx\` suffix instead.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
145
149
|
routePath = routePath.replace(
|
|
146
150
|
new RegExp(
|
|
147
|
-
`/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`
|
|
151
|
+
`/(component|errorComponent|notFoundComponent|pendingComponent|loader|${config.routeToken}|lazy)$`
|
|
148
152
|
),
|
|
149
153
|
""
|
|
150
154
|
);
|
|
151
155
|
originalRoutePath = originalRoutePath.replace(
|
|
152
156
|
new RegExp(
|
|
153
|
-
`/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`
|
|
157
|
+
`/(component|errorComponent|notFoundComponent|pendingComponent|loader|${config.routeToken}|lazy)$`
|
|
154
158
|
),
|
|
155
159
|
""
|
|
156
160
|
);
|
|
@@ -180,7 +184,16 @@ async function getRouteNodes(config, root) {
|
|
|
180
184
|
return routeNodes;
|
|
181
185
|
}
|
|
182
186
|
await recurse("./");
|
|
183
|
-
const rootRouteNode = routeNodes.find(
|
|
187
|
+
const rootRouteNode = routeNodes.find(
|
|
188
|
+
(d) => d.routePath === `/${rootPathId.rootPathId}` && ![
|
|
189
|
+
"component",
|
|
190
|
+
"errorComponent",
|
|
191
|
+
"notFoundComponent",
|
|
192
|
+
"pendingComponent",
|
|
193
|
+
"loader",
|
|
194
|
+
"lazy"
|
|
195
|
+
].includes(d._fsRouteType)
|
|
196
|
+
) ?? routeNodes.find((d) => d.routePath === `/${rootPathId.rootPathId}`);
|
|
184
197
|
if (rootRouteNode) {
|
|
185
198
|
rootRouteNode._fsRouteType = "__root";
|
|
186
199
|
rootRouteNode.variableName = "root";
|
|
@@ -205,6 +218,8 @@ function getRouteMeta(routePath, config) {
|
|
|
205
218
|
fsRouteType = "pendingComponent";
|
|
206
219
|
} else if (routePath.endsWith("/errorComponent")) {
|
|
207
220
|
fsRouteType = "errorComponent";
|
|
221
|
+
} else if (routePath.endsWith("/notFoundComponent")) {
|
|
222
|
+
fsRouteType = "notFoundComponent";
|
|
208
223
|
}
|
|
209
224
|
const variableName = utils.routePathToVariable(routePath);
|
|
210
225
|
return { fsRouteType, variableName };
|
|
@@ -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 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)/\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)$/)) {\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 ;(\n [\n ['component', 'component'],\n ['errorComponent', 'errorComponent'],\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 routePath = routePath.replace(\n new RegExp(\n `/(component|errorComponent|pendingComponent|loader|${config.routeToken}|lazy)$`,\n ),\n '',\n )\n\n originalRoutePath = originalRoutePath.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 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 const rootRouteNode = 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 >\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 }\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":["logger","logging","fsp","loadConfigFile","getRouteNodesVirtual","replaceBackslash","routePathToVariable","removeExt","determineInitialRoutePath","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 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":["logger","logging","fsp","loadConfigFile","getRouteNodesVirtual","replaceBackslash","routePathToVariable","removeExt","determineInitialRoutePath","rootPathId"],"mappings":"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"}
|
|
@@ -10,6 +10,6 @@ export declare function getRouteNodes(config: Pick<Config, 'routesDirectory' | '
|
|
|
10
10
|
* @returns An object containing the type of the route and the variable name derived from the route path.
|
|
11
11
|
*/
|
|
12
12
|
export declare function getRouteMeta(routePath: string, config: Pick<Config, 'routeToken' | 'indexToken'>): {
|
|
13
|
-
fsRouteType: Extract<FsRouteType, 'static' | 'layout' | 'api' | 'lazy' | 'loader' | 'component' | 'pendingComponent' | 'errorComponent'>;
|
|
13
|
+
fsRouteType: Extract<FsRouteType, 'static' | 'layout' | 'api' | 'lazy' | 'loader' | 'component' | 'pendingComponent' | 'errorComponent' | 'notFoundComponent'>;
|
|
14
14
|
variableName: string;
|
|
15
15
|
};
|
package/dist/cjs/generator.cjs
CHANGED
|
@@ -196,12 +196,24 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
196
196
|
(d) => d.routePath?.split("/").length,
|
|
197
197
|
(d) => d.filePath.match(new RegExp(`[./]${this.config.indexToken}[.]`)) ? 1 : -1,
|
|
198
198
|
(d) => d.filePath.match(
|
|
199
|
-
/[./](component|errorComponent|pendingComponent|loader|lazy)[.]/
|
|
199
|
+
/[./](component|errorComponent|notFoundComponent|pendingComponent|loader|lazy)[.]/
|
|
200
200
|
) ? 1 : -1,
|
|
201
201
|
(d) => d.filePath.match(new RegExp(`[./]${this.config.routeToken}[.]`)) ? -1 : 1,
|
|
202
202
|
(d) => d.routePath?.endsWith("/") ? -1 : 1,
|
|
203
203
|
(d) => d.routePath
|
|
204
|
-
]).filter((d) =>
|
|
204
|
+
]).filter((d) => {
|
|
205
|
+
if (d.routePath === `/${rootPathId.rootPathId}`) {
|
|
206
|
+
return [
|
|
207
|
+
"component",
|
|
208
|
+
"errorComponent",
|
|
209
|
+
"notFoundComponent",
|
|
210
|
+
"pendingComponent",
|
|
211
|
+
"loader",
|
|
212
|
+
"lazy"
|
|
213
|
+
].includes(d._fsRouteType);
|
|
214
|
+
}
|
|
215
|
+
return true;
|
|
216
|
+
});
|
|
205
217
|
const routeFileAllResult = await Promise.allSettled(
|
|
206
218
|
preRouteNodes.filter((n) => !n.isVirtualParentRoute && !n.isVirtual).map((n) => this.processRouteNodeFile(n))
|
|
207
219
|
);
|
|
@@ -353,6 +365,25 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
353
365
|
source: this.targetTemplate.fullPkg
|
|
354
366
|
});
|
|
355
367
|
}
|
|
368
|
+
const hasComponentPieces = sortedRouteNodes.some(
|
|
369
|
+
(node) => acc.routePiecesByPath[node.routePath]?.component || acc.routePiecesByPath[node.routePath]?.errorComponent || acc.routePiecesByPath[node.routePath]?.notFoundComponent || acc.routePiecesByPath[node.routePath]?.pendingComponent
|
|
370
|
+
);
|
|
371
|
+
const hasLoaderPieces = sortedRouteNodes.some(
|
|
372
|
+
(node) => acc.routePiecesByPath[node.routePath]?.loader
|
|
373
|
+
);
|
|
374
|
+
if (hasComponentPieces || hasLoaderPieces) {
|
|
375
|
+
const runtimeImport = {
|
|
376
|
+
specifiers: [],
|
|
377
|
+
source: this.targetTemplate.fullPkg
|
|
378
|
+
};
|
|
379
|
+
if (hasComponentPieces) {
|
|
380
|
+
runtimeImport.specifiers.push({ imported: "lazyRouteComponent" });
|
|
381
|
+
}
|
|
382
|
+
if (hasLoaderPieces) {
|
|
383
|
+
runtimeImport.specifiers.push({ imported: "lazyFn" });
|
|
384
|
+
}
|
|
385
|
+
imports.push(runtimeImport);
|
|
386
|
+
}
|
|
356
387
|
if (config.verboseFileRoutes === false) {
|
|
357
388
|
const typeImport = {
|
|
358
389
|
specifiers: [],
|
|
@@ -382,6 +413,7 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
382
413
|
const loaderNode = acc.routePiecesByPath[node.routePath]?.loader;
|
|
383
414
|
const componentNode = acc.routePiecesByPath[node.routePath]?.component;
|
|
384
415
|
const errorComponentNode = acc.routePiecesByPath[node.routePath]?.errorComponent;
|
|
416
|
+
const notFoundComponentNode = acc.routePiecesByPath[node.routePath]?.notFoundComponent;
|
|
385
417
|
const pendingComponentNode = acc.routePiecesByPath[node.routePath]?.pendingComponent;
|
|
386
418
|
const lazyComponentNode = acc.routePiecesByPath[node.routePath]?.lazy;
|
|
387
419
|
return [
|
|
@@ -402,38 +434,97 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
402
434
|
config.addExtensions
|
|
403
435
|
)
|
|
404
436
|
)}'), 'loader') })` : "",
|
|
405
|
-
componentNode || errorComponentNode || pendingComponentNode ? `.update({
|
|
437
|
+
componentNode || errorComponentNode || notFoundComponentNode || pendingComponentNode ? `.update({
|
|
406
438
|
${[
|
|
407
439
|
["component", componentNode],
|
|
408
440
|
["errorComponent", errorComponentNode],
|
|
441
|
+
["notFoundComponent", notFoundComponentNode],
|
|
409
442
|
["pendingComponent", pendingComponentNode]
|
|
410
443
|
].filter((d) => d[1]).map((d) => {
|
|
411
|
-
|
|
412
|
-
|
|
444
|
+
const isVueFile = d[1].filePath.endsWith(".vue");
|
|
445
|
+
const exportName = isVueFile ? "default" : d[0];
|
|
446
|
+
const importPath = utils.replaceBackslash(
|
|
447
|
+
isVueFile ? path.relative(
|
|
448
|
+
path.dirname(config.generatedRouteTree),
|
|
449
|
+
path.resolve(
|
|
450
|
+
config.routesDirectory,
|
|
451
|
+
d[1].filePath
|
|
452
|
+
)
|
|
453
|
+
) : utils.removeExt(
|
|
413
454
|
path.relative(
|
|
414
455
|
path.dirname(config.generatedRouteTree),
|
|
415
|
-
path.resolve(
|
|
456
|
+
path.resolve(
|
|
457
|
+
config.routesDirectory,
|
|
458
|
+
d[1].filePath
|
|
459
|
+
)
|
|
416
460
|
),
|
|
417
461
|
config.addExtensions
|
|
418
462
|
)
|
|
419
|
-
)
|
|
463
|
+
);
|
|
464
|
+
return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`;
|
|
420
465
|
}).join("\n,")}
|
|
421
466
|
})` : "",
|
|
422
|
-
lazyComponentNode ?
|
|
423
|
-
|
|
424
|
-
|
|
467
|
+
lazyComponentNode ? (() => {
|
|
468
|
+
const isVueFile = lazyComponentNode.filePath.endsWith(".vue");
|
|
469
|
+
const exportAccessor = isVueFile ? "d.default" : "d.Route";
|
|
470
|
+
const importPath = utils.replaceBackslash(
|
|
471
|
+
isVueFile ? path.relative(
|
|
425
472
|
path.dirname(config.generatedRouteTree),
|
|
426
473
|
path.resolve(
|
|
427
474
|
config.routesDirectory,
|
|
428
475
|
lazyComponentNode.filePath
|
|
429
476
|
)
|
|
430
|
-
)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
477
|
+
) : utils.removeExt(
|
|
478
|
+
path.relative(
|
|
479
|
+
path.dirname(config.generatedRouteTree),
|
|
480
|
+
path.resolve(
|
|
481
|
+
config.routesDirectory,
|
|
482
|
+
lazyComponentNode.filePath
|
|
483
|
+
)
|
|
484
|
+
),
|
|
485
|
+
config.addExtensions
|
|
486
|
+
)
|
|
487
|
+
);
|
|
488
|
+
return `.lazy(() => import('./${importPath}').then((d) => ${exportAccessor}))`;
|
|
489
|
+
})() : ""
|
|
434
490
|
].join("")
|
|
435
491
|
].join("\n\n");
|
|
436
492
|
});
|
|
493
|
+
const rootRoutePath = `/${rootPathId.rootPathId}`;
|
|
494
|
+
const rootComponentNode = acc.routePiecesByPath[rootRoutePath]?.component;
|
|
495
|
+
const rootErrorComponentNode = acc.routePiecesByPath[rootRoutePath]?.errorComponent;
|
|
496
|
+
const rootNotFoundComponentNode = acc.routePiecesByPath[rootRoutePath]?.notFoundComponent;
|
|
497
|
+
const rootPendingComponentNode = acc.routePiecesByPath[rootRoutePath]?.pendingComponent;
|
|
498
|
+
let rootRouteUpdate = "";
|
|
499
|
+
if (rootComponentNode || rootErrorComponentNode || rootNotFoundComponentNode || rootPendingComponentNode) {
|
|
500
|
+
rootRouteUpdate = `const rootRouteWithChildren = rootRouteImport${rootComponentNode || rootErrorComponentNode || rootNotFoundComponentNode || rootPendingComponentNode ? `.update({
|
|
501
|
+
${[
|
|
502
|
+
["component", rootComponentNode],
|
|
503
|
+
["errorComponent", rootErrorComponentNode],
|
|
504
|
+
["notFoundComponent", rootNotFoundComponentNode],
|
|
505
|
+
["pendingComponent", rootPendingComponentNode]
|
|
506
|
+
].filter((d) => d[1]).map((d) => {
|
|
507
|
+
const isVueFile = d[1].filePath.endsWith(".vue");
|
|
508
|
+
const exportName = isVueFile ? "default" : d[0];
|
|
509
|
+
const importPath = utils.replaceBackslash(
|
|
510
|
+
isVueFile ? path.relative(
|
|
511
|
+
path.dirname(config.generatedRouteTree),
|
|
512
|
+
path.resolve(config.routesDirectory, d[1].filePath)
|
|
513
|
+
) : utils.removeExt(
|
|
514
|
+
path.relative(
|
|
515
|
+
path.dirname(config.generatedRouteTree),
|
|
516
|
+
path.resolve(
|
|
517
|
+
config.routesDirectory,
|
|
518
|
+
d[1].filePath
|
|
519
|
+
)
|
|
520
|
+
),
|
|
521
|
+
config.addExtensions
|
|
522
|
+
)
|
|
523
|
+
);
|
|
524
|
+
return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`;
|
|
525
|
+
}).join("\n,")}
|
|
526
|
+
})` : ""}._addFileChildren(rootRouteChildren)${config.disableTypes ? "" : `._addFileTypes<FileRouteTypes>()`}`;
|
|
527
|
+
}
|
|
437
528
|
let fileRoutesByPathInterface = "";
|
|
438
529
|
let fileRoutesByFullPath = "";
|
|
439
530
|
if (!config.disableTypes) {
|
|
@@ -479,7 +570,10 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${utils.getRe
|
|
|
479
570
|
(child) => `${child.variableName}Route: ${utils.getResolvedRouteNodeVariableName(child)}`
|
|
480
571
|
).join(",")}
|
|
481
572
|
}`,
|
|
482
|
-
|
|
573
|
+
rootRouteUpdate ? rootRouteUpdate.replace(
|
|
574
|
+
"const rootRouteWithChildren = ",
|
|
575
|
+
"export const routeTree = "
|
|
576
|
+
) : `export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)${config.disableTypes ? "" : `._addFileTypes<FileRouteTypes>()`}`
|
|
483
577
|
].join("\n");
|
|
484
578
|
utils.checkRouteFullPathUniqueness(
|
|
485
579
|
sortedRouteNodes.filter(
|
|
@@ -601,6 +695,7 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${utils.getRe
|
|
|
601
695
|
"component",
|
|
602
696
|
"pendingComponent",
|
|
603
697
|
"errorComponent",
|
|
698
|
+
"notFoundComponent",
|
|
604
699
|
"loader"
|
|
605
700
|
].every((d) => d !== node._fsRouteType)
|
|
606
701
|
) {
|
|
@@ -619,30 +714,33 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${utils.getRe
|
|
|
619
714
|
return null;
|
|
620
715
|
}
|
|
621
716
|
}
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
717
|
+
const isVueFile = node.filePath.endsWith(".vue");
|
|
718
|
+
if (!isVueFile) {
|
|
719
|
+
const transformResult = await transform.transform({
|
|
720
|
+
source: updatedCacheEntry.fileContent,
|
|
721
|
+
ctx: {
|
|
722
|
+
target: this.config.target,
|
|
723
|
+
routeId: escapedRoutePath,
|
|
724
|
+
lazy: node._fsRouteType === "lazy",
|
|
725
|
+
verboseFileRoutes: !(this.config.verboseFileRoutes === false)
|
|
726
|
+
},
|
|
727
|
+
node
|
|
728
|
+
});
|
|
729
|
+
if (transformResult.result === "no-route-export") {
|
|
730
|
+
this.logger.warn(
|
|
731
|
+
`Route file "${node.fullPath}" does not contain any route piece. This is likely a mistake.`
|
|
732
|
+
);
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
if (transformResult.result === "error") {
|
|
736
|
+
throw new Error(
|
|
737
|
+
`Error transforming route file ${node.fullPath}: ${transformResult.error}`
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
if (transformResult.result === "modified") {
|
|
741
|
+
updatedCacheEntry.fileContent = transformResult.output;
|
|
742
|
+
shouldWriteRouteFile = true;
|
|
743
|
+
}
|
|
646
744
|
}
|
|
647
745
|
for (const plugin of this.plugins) {
|
|
648
746
|
plugin.afterTransform?.({ node, prevNode: previousCacheEntry?.node });
|
|
@@ -856,14 +954,15 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${utils.getRe
|
|
|
856
954
|
"loader",
|
|
857
955
|
"component",
|
|
858
956
|
"pendingComponent",
|
|
859
|
-
"errorComponent"
|
|
957
|
+
"errorComponent",
|
|
958
|
+
"notFoundComponent"
|
|
860
959
|
].some((d) => d === node._fsRouteType)) {
|
|
861
960
|
acc.routePiecesByPath[node.routePath] = acc.routePiecesByPath[node.routePath] || {};
|
|
862
|
-
acc.routePiecesByPath[node.routePath][node._fsRouteType === "lazy" ? "lazy" : node._fsRouteType === "loader" ? "loader" : node._fsRouteType === "errorComponent" ? "errorComponent" : node._fsRouteType === "pendingComponent" ? "pendingComponent" : "component"] = node;
|
|
961
|
+
acc.routePiecesByPath[node.routePath][node._fsRouteType === "lazy" ? "lazy" : node._fsRouteType === "loader" ? "loader" : node._fsRouteType === "errorComponent" ? "errorComponent" : node._fsRouteType === "notFoundComponent" ? "notFoundComponent" : node._fsRouteType === "pendingComponent" ? "pendingComponent" : "component"] = node;
|
|
863
962
|
const anchorRoute = acc.routeNodes.find(
|
|
864
963
|
(d) => d.routePath === node.routePath
|
|
865
964
|
);
|
|
866
|
-
if (!anchorRoute) {
|
|
965
|
+
if (!anchorRoute && node.routePath !== `/${rootPathId.rootPathId}`) {
|
|
867
966
|
this.handleNode(
|
|
868
967
|
{
|
|
869
968
|
...node,
|