@tanstack/router-generator 1.121.0-alpha.22 → 1.121.0-alpha.27
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 +23 -5
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.cts +7 -3
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +5 -3
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/filesystem/virtual/getRouteNodes.cjs +1 -1
- package/dist/cjs/filesystem/virtual/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/generator.cjs +828 -665
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/generator.d.cts +78 -1
- package/dist/cjs/index.cjs +5 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +7 -3
- package/dist/cjs/logger.cjs +37 -0
- package/dist/cjs/logger.cjs.map +1 -0
- package/dist/cjs/logger.d.cts +10 -0
- package/dist/cjs/plugin/default-generator-plugin.cjs +88 -0
- package/dist/cjs/plugin/default-generator-plugin.cjs.map +1 -0
- package/dist/cjs/plugin/default-generator-plugin.d.cts +2 -0
- package/dist/cjs/plugin/types.d.cts +46 -0
- package/dist/cjs/template.cjs +10 -10
- package/dist/cjs/template.cjs.map +1 -1
- package/dist/cjs/template.d.cts +2 -2
- package/dist/cjs/transform/default-transform-plugin.cjs +95 -0
- package/dist/cjs/transform/default-transform-plugin.cjs.map +1 -0
- package/dist/cjs/transform/default-transform-plugin.d.cts +2 -0
- package/dist/cjs/transform/transform.cjs +351 -0
- package/dist/cjs/transform/transform.cjs.map +1 -0
- package/dist/cjs/transform/transform.d.cts +4 -0
- package/dist/cjs/transform/types.d.cts +43 -0
- package/dist/cjs/transform/utils.cjs +36 -0
- package/dist/cjs/transform/utils.cjs.map +1 -0
- package/dist/cjs/transform/utils.d.cts +2 -0
- package/dist/cjs/types.d.cts +22 -0
- package/dist/cjs/utils.cjs +237 -40
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +76 -9
- package/dist/esm/config.d.ts +7 -3
- package/dist/esm/config.js +21 -3
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js +3 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/dist/esm/filesystem/virtual/getRouteNodes.js +1 -1
- package/dist/esm/filesystem/virtual/getRouteNodes.js.map +1 -1
- package/dist/esm/generator.d.ts +78 -1
- package/dist/esm/generator.js +817 -653
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/index.d.ts +7 -3
- package/dist/esm/index.js +7 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/logger.d.ts +10 -0
- package/dist/esm/logger.js +37 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/plugin/default-generator-plugin.d.ts +2 -0
- package/dist/esm/plugin/default-generator-plugin.js +88 -0
- package/dist/esm/plugin/default-generator-plugin.js.map +1 -0
- package/dist/esm/plugin/types.d.ts +46 -0
- package/dist/esm/template.d.ts +2 -2
- package/dist/esm/template.js +10 -10
- package/dist/esm/template.js.map +1 -1
- package/dist/esm/transform/default-transform-plugin.d.ts +2 -0
- package/dist/esm/transform/default-transform-plugin.js +95 -0
- package/dist/esm/transform/default-transform-plugin.js.map +1 -0
- package/dist/esm/transform/transform.d.ts +4 -0
- package/dist/esm/transform/transform.js +351 -0
- package/dist/esm/transform/transform.js.map +1 -0
- package/dist/esm/transform/types.d.ts +43 -0
- package/dist/esm/transform/utils.d.ts +2 -0
- package/dist/esm/transform/utils.js +36 -0
- package/dist/esm/transform/utils.js.map +1 -0
- package/dist/esm/types.d.ts +22 -0
- package/dist/esm/utils.d.ts +76 -9
- package/dist/esm/utils.js +237 -40
- package/dist/esm/utils.js.map +1 -1
- package/package.json +9 -10
- package/src/config.ts +23 -2
- package/src/filesystem/physical/getRouteNodes.ts +2 -1
- package/src/filesystem/virtual/getRouteNodes.ts +1 -1
- package/src/generator.ts +1108 -934
- package/src/index.ts +25 -3
- package/src/logger.ts +43 -0
- package/src/plugin/default-generator-plugin.ts +96 -0
- package/src/plugin/types.ts +51 -0
- package/src/template.ts +33 -12
- package/src/transform/default-transform-plugin.ts +103 -0
- package/src/transform/transform.ts +430 -0
- package/src/transform/types.ts +50 -0
- package/src/transform/utils.ts +42 -0
- package/src/types.ts +25 -0
- package/src/utils.ts +351 -36
package/dist/cjs/config.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const path = require("node:path");
|
|
4
|
-
const
|
|
4
|
+
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({
|
|
@@ -28,7 +28,6 @@ const configSchema = baseConfigSchema.extend({
|
|
|
28
28
|
disableTypes: zod.z.boolean().optional().default(false),
|
|
29
29
|
verboseFileRoutes: zod.z.boolean().optional(),
|
|
30
30
|
addExtensions: zod.z.boolean().optional().default(false),
|
|
31
|
-
disableManifestGeneration: zod.z.boolean().optional().default(false),
|
|
32
31
|
enableRouteTreeFormatting: zod.z.boolean().optional().default(true),
|
|
33
32
|
routeTreeFileFooter: zod.z.array(zod.z.string()).optional().default([]),
|
|
34
33
|
autoCodeSplitting: zod.z.boolean().optional(),
|
|
@@ -39,7 +38,9 @@ const configSchema = baseConfigSchema.extend({
|
|
|
39
38
|
experimental: zod.z.object({
|
|
40
39
|
// TODO: This has been made stable and is now "autoCodeSplitting". Remove in next major version.
|
|
41
40
|
enableCodeSplitting: zod.z.boolean().optional()
|
|
42
|
-
}).optional()
|
|
41
|
+
}).optional(),
|
|
42
|
+
plugins: zod.z.array(zod.z.custom()).optional(),
|
|
43
|
+
tmpDir: zod.z.string().optional().default("")
|
|
43
44
|
});
|
|
44
45
|
function resolveConfigPath({ configDirectory }) {
|
|
45
46
|
return path.resolve(configDirectory, "tsr.config.json");
|
|
@@ -49,11 +50,11 @@ function getConfig(inlineConfig = {}, configDirectory) {
|
|
|
49
50
|
configDirectory = process.cwd();
|
|
50
51
|
}
|
|
51
52
|
const configFilePathJson = resolveConfigPath({ configDirectory });
|
|
52
|
-
const exists =
|
|
53
|
+
const exists = node_fs.existsSync(configFilePathJson);
|
|
53
54
|
let config2;
|
|
54
55
|
if (exists) {
|
|
55
56
|
config2 = configSchema.parse({
|
|
56
|
-
...JSON.parse(
|
|
57
|
+
...JSON.parse(node_fs.readFileSync(configFilePathJson, "utf-8")),
|
|
57
58
|
...inlineConfig
|
|
58
59
|
});
|
|
59
60
|
} else {
|
|
@@ -88,6 +89,23 @@ function getConfig(inlineConfig = {}, configDirectory) {
|
|
|
88
89
|
);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
92
|
+
const resolveTmpDir = (dir) => {
|
|
93
|
+
if (Array.isArray(dir)) {
|
|
94
|
+
dir = path.join(...dir);
|
|
95
|
+
}
|
|
96
|
+
if (!path.isAbsolute(dir)) {
|
|
97
|
+
dir = path.resolve(process.cwd(), dir);
|
|
98
|
+
}
|
|
99
|
+
node_fs.mkdirSync(dir, { recursive: true });
|
|
100
|
+
return dir;
|
|
101
|
+
};
|
|
102
|
+
if (config2.tmpDir) {
|
|
103
|
+
config2.tmpDir = resolveTmpDir(config2.tmpDir);
|
|
104
|
+
} else if (process.env.TSR_TMP_DIR) {
|
|
105
|
+
config2.tmpDir = resolveTmpDir(process.env.TSR_TMP_DIR);
|
|
106
|
+
} else {
|
|
107
|
+
config2.tmpDir = resolveTmpDir([".tanstack", "tmp"]);
|
|
108
|
+
}
|
|
91
109
|
validateConfig(config2);
|
|
92
110
|
return config2;
|
|
93
111
|
}
|
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'\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
|
|
1
|
+
{"version":3,"file":"config.cjs","sources":["../../src/config.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync, mkdirSync, 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.array(z.string()).optional().default([]),\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})\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 mkdirSync(dir, { recursive: true })\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","mkdirSync"],"mappings":"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"}
|
package/dist/cjs/config.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { GeneratorPlugin } from './plugin/types.cjs';
|
|
2
3
|
export declare const baseConfigSchema: z.ZodObject<{
|
|
3
4
|
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<["react", "solid"]>>>;
|
|
4
5
|
virtualRouteConfig: z.ZodOptional<z.ZodUnion<[z.ZodType<import('@tanstack/virtual-file-routes').VirtualRootRoute, z.ZodTypeDef, import('@tanstack/virtual-file-routes').VirtualRootRoute>, z.ZodString]>>;
|
|
@@ -62,7 +63,6 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
|
|
|
62
63
|
disableTypes: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
63
64
|
verboseFileRoutes: z.ZodOptional<z.ZodBoolean>;
|
|
64
65
|
addExtensions: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
65
|
-
disableManifestGeneration: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
66
66
|
enableRouteTreeFormatting: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
67
67
|
routeTreeFileFooter: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
68
68
|
autoCodeSplitting: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -83,6 +83,8 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
|
|
|
83
83
|
}, {
|
|
84
84
|
enableCodeSplitting?: boolean | undefined;
|
|
85
85
|
}>>;
|
|
86
|
+
plugins: z.ZodOptional<z.ZodArray<z.ZodType<GeneratorPlugin, z.ZodTypeDef, GeneratorPlugin>, "many">>;
|
|
87
|
+
tmpDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
86
88
|
}>, "strip", z.ZodTypeAny, {
|
|
87
89
|
target: "react" | "solid";
|
|
88
90
|
routeFileIgnorePrefix: string;
|
|
@@ -96,9 +98,9 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
|
|
|
96
98
|
generatedRouteTree: string;
|
|
97
99
|
disableTypes: boolean;
|
|
98
100
|
addExtensions: boolean;
|
|
99
|
-
disableManifestGeneration: boolean;
|
|
100
101
|
enableRouteTreeFormatting: boolean;
|
|
101
102
|
routeTreeFileFooter: string[];
|
|
103
|
+
tmpDir: string;
|
|
102
104
|
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
103
105
|
routeFilePrefix?: string | undefined;
|
|
104
106
|
routeFileIgnorePattern?: string | undefined;
|
|
@@ -112,6 +114,7 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
|
|
|
112
114
|
experimental?: {
|
|
113
115
|
enableCodeSplitting?: boolean | undefined;
|
|
114
116
|
} | undefined;
|
|
117
|
+
plugins?: GeneratorPlugin[] | undefined;
|
|
115
118
|
}, {
|
|
116
119
|
target?: "react" | "solid" | undefined;
|
|
117
120
|
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
@@ -130,7 +133,6 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
|
|
|
130
133
|
disableTypes?: boolean | undefined;
|
|
131
134
|
verboseFileRoutes?: boolean | undefined;
|
|
132
135
|
addExtensions?: boolean | undefined;
|
|
133
|
-
disableManifestGeneration?: boolean | undefined;
|
|
134
136
|
enableRouteTreeFormatting?: boolean | undefined;
|
|
135
137
|
routeTreeFileFooter?: string[] | undefined;
|
|
136
138
|
autoCodeSplitting?: boolean | undefined;
|
|
@@ -141,6 +143,8 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
|
|
|
141
143
|
experimental?: {
|
|
142
144
|
enableCodeSplitting?: boolean | undefined;
|
|
143
145
|
} | undefined;
|
|
146
|
+
plugins?: GeneratorPlugin[] | undefined;
|
|
147
|
+
tmpDir?: string | undefined;
|
|
144
148
|
}>;
|
|
145
149
|
export type Config = z.infer<typeof configSchema>;
|
|
146
150
|
type ResolveParams = {
|
|
@@ -5,6 +5,7 @@ const fsp = require("node:fs/promises");
|
|
|
5
5
|
const utils = require("../../utils.cjs");
|
|
6
6
|
const getRouteNodes$1 = require("../virtual/getRouteNodes.cjs");
|
|
7
7
|
const loadConfigFile = require("../virtual/loadConfigFile.cjs");
|
|
8
|
+
const logger = require("../../logger.cjs");
|
|
8
9
|
const rootPathId = require("./rootPathId.cjs");
|
|
9
10
|
function _interopNamespaceDefault(e) {
|
|
10
11
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -26,7 +27,7 @@ const fsp__namespace = /* @__PURE__ */ _interopNamespaceDefault(fsp);
|
|
|
26
27
|
const disallowedRouteGroupConfiguration = /\(([^)]+)\).(ts|js|tsx|jsx)/;
|
|
27
28
|
async function getRouteNodes(config, root) {
|
|
28
29
|
const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } = config;
|
|
29
|
-
const logger =
|
|
30
|
+
const logger$1 = logger.logging({ disabled: config.disableLogging });
|
|
30
31
|
const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? "", "g");
|
|
31
32
|
const routeNodes = [];
|
|
32
33
|
async function recurse(dir) {
|
|
@@ -97,7 +98,7 @@ async function getRouteNodes(config, root) {
|
|
|
97
98
|
}
|
|
98
99
|
if (disallowedRouteGroupConfiguration.test(dirent.name)) {
|
|
99
100
|
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?`;
|
|
100
|
-
logger.error(`ERROR: ${errorMessage}`);
|
|
101
|
+
logger$1.error(`ERROR: ${errorMessage}`);
|
|
101
102
|
throw new Error(errorMessage);
|
|
102
103
|
}
|
|
103
104
|
const meta = getRouteMeta(routePath, config);
|
|
@@ -116,7 +117,7 @@ async function getRouteNodes(config, root) {
|
|
|
116
117
|
["loader", "loader"]
|
|
117
118
|
].forEach(([matcher, type]) => {
|
|
118
119
|
if (routeType === matcher) {
|
|
119
|
-
logger.warn(
|
|
120
|
+
logger$1.warn(
|
|
120
121
|
`WARNING: The \`.${type}.tsx\` suffix used for the ${filePath} file is deprecated. Use the new \`.lazy.tsx\` suffix instead.`
|
|
121
122
|
);
|
|
122
123
|
}
|
|
@@ -147,6 +148,7 @@ async function getRouteNodes(config, root) {
|
|
|
147
148
|
const rootRouteNode = routeNodes.find((d) => d.routePath === `/${rootPathId.rootPathId}`);
|
|
148
149
|
if (rootRouteNode) {
|
|
149
150
|
rootRouteNode._fsRouteType = "__root";
|
|
151
|
+
rootRouteNode.variableName = "root";
|
|
150
152
|
}
|
|
151
153
|
return { rootRouteNode, routeNodes };
|
|
152
154
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n logging,\n removeExt,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { FsRouteType, GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\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 const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && dirent.name.match(/__virtual\\.[mc]?[jt]s$/)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes } = await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = path.posix.join(fullDir, dirent.name)\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n let routePath = determineInitialRoutePath(filePathNoExt)\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n }\n\n if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n logger.error(`ERROR: ${errorMessage}`)\n throw new Error(errorMessage)\n }\n\n const 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 }\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 if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n _fsRouteType: routeType,\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 }\n\n return { rootRouteNode, routeNodes }\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":["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)/\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 const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && dirent.name.match(/__virtual\\.[mc]?[jt]s$/)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes } = await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = path.posix.join(fullDir, dirent.name)\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\n const filePath = replaceBackslash(path.join(dir, dirent.name))\n const filePathNoExt = removeExt(filePath)\n let routePath = determineInitialRoutePath(filePathNoExt)\n\n if (routeFilePrefix) {\n routePath = routePath.replaceAll(routeFilePrefix, '')\n }\n\n if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n logger.error(`ERROR: ${errorMessage}`)\n throw new Error(errorMessage)\n }\n\n const 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 }\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 if (routePath === config.indexToken) {\n routePath = '/'\n }\n\n routePath =\n routePath.replace(new RegExp(`/${config.indexToken}$`), '/') || '/'\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n _fsRouteType: routeType,\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 { rootRouteNode, routeNodes }\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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"}
|
|
@@ -47,7 +47,7 @@ async function getRouteNodes(tsrConfig, root) {
|
|
|
47
47
|
children,
|
|
48
48
|
filePath: virtualRouteConfig.file,
|
|
49
49
|
fullPath: path.join(fullDir, virtualRouteConfig.file),
|
|
50
|
-
variableName: "
|
|
50
|
+
variableName: "root",
|
|
51
51
|
routePath: `/${rootPathId.rootPathId}`,
|
|
52
52
|
_fsRouteType: "__root"
|
|
53
53
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport { rootPathId } from '../physical/rootPathId'\nimport { virtualRootRouteSchema } from './config'\nimport { loadConfigFile } from './loadConfigFile'\nimport type {\n VirtualRootRoute,\n VirtualRouteNode,\n} from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nfunction ensureLeadingUnderScore(id: string) {\n if (id.startsWith('_')) {\n return id\n }\n return `_${id}`\n}\n\nfunction flattenTree(node: RouteNode): Array<RouteNode> {\n const result = [node]\n\n if (node.children) {\n for (const child of node.children) {\n result.push(...flattenTree(child))\n }\n }\n delete node.children\n\n return result\n}\n\nexport async function getRouteNodes(\n tsrConfig: Pick<\n Config,\n | 'routesDirectory'\n | 'virtualRouteConfig'\n | 'routeFileIgnorePrefix'\n | 'disableLogging'\n | 'indexToken'\n | 'routeToken'\n >,\n root: string,\n): Promise<GetRouteNodesResult> {\n const fullDir = resolve(tsrConfig.routesDirectory)\n if (tsrConfig.virtualRouteConfig === undefined) {\n throw new Error(`virtualRouteConfig is undefined`)\n }\n let virtualRouteConfig: VirtualRootRoute\n let children: Array<RouteNode> = []\n if (typeof tsrConfig.virtualRouteConfig === 'string') {\n virtualRouteConfig = await getVirtualRouteConfigFromFileExport(\n tsrConfig,\n root,\n )\n } else {\n virtualRouteConfig = tsrConfig.virtualRouteConfig\n }\n children = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n virtualRouteConfig.children,\n )\n const allNodes = flattenTree({\n children,\n filePath: virtualRouteConfig.file,\n fullPath: join(fullDir, virtualRouteConfig.file),\n variableName: 'rootRoute',\n routePath: `/${rootPathId}`,\n _fsRouteType: '__root',\n })\n\n const rootRouteNode = allNodes[0]\n const routeNodes = allNodes.slice(1)\n\n return { rootRouteNode, routeNodes }\n}\n\n/**\n * Get the virtual route config from a file export\n *\n * @example\n * ```ts\n * // routes.ts\n * import { rootRoute } from '@tanstack/virtual-file-routes'\n *\n * export const routes = rootRoute({ ... })\n * // or\n * export default rootRoute({ ... })\n * ```\n *\n */\nasync function getVirtualRouteConfigFromFileExport(\n tsrConfig: Pick<Config, 'virtualRouteConfig'>,\n root: string,\n): Promise<VirtualRootRoute> {\n if (\n tsrConfig.virtualRouteConfig === undefined ||\n typeof tsrConfig.virtualRouteConfig !== 'string' ||\n tsrConfig.virtualRouteConfig === ''\n ) {\n throw new Error(`virtualRouteConfig is undefined or empty`)\n }\n const exports = await loadConfigFile(join(root, tsrConfig.virtualRouteConfig))\n\n if (!('routes' in exports) && !('default' in exports)) {\n throw new Error(\n `routes not found in ${tsrConfig.virtualRouteConfig}. The routes export must be named like 'export const routes = ...' or done using 'export default ...'`,\n )\n }\n\n const virtualRouteConfig =\n 'routes' in exports ? exports.routes : exports.default\n\n return virtualRootRouteSchema.parse(virtualRouteConfig)\n}\n\nexport async function getRouteNodesRecursive(\n tsrConfig: Pick<\n Config,\n | 'routesDirectory'\n | 'routeFileIgnorePrefix'\n | 'disableLogging'\n | 'indexToken'\n | 'routeToken'\n >,\n root: string,\n fullDir: string,\n nodes?: Array<VirtualRouteNode>,\n parent?: RouteNode,\n): Promise<Array<RouteNode>> {\n if (nodes === undefined) {\n return []\n }\n const children = await Promise.all(\n nodes.map(async (node) => {\n if (node.type === 'physical') {\n const { routeNodes } = await getRouteNodesPhysical(\n {\n ...tsrConfig,\n routesDirectory: resolve(fullDir, node.directory),\n },\n root,\n )\n routeNodes.forEach((subtreeNode) => {\n subtreeNode.variableName = routePathToVariable(\n `${node.pathPrefix}/${removeExt(subtreeNode.filePath)}`,\n )\n subtreeNode.routePath = `${parent?.routePath ?? ''}${node.pathPrefix}${subtreeNode.routePath}`\n subtreeNode.filePath = `${node.directory}/${subtreeNode.filePath}`\n })\n return routeNodes\n }\n\n function getFile(file: string) {\n const filePath = file\n const variableName = routePathToVariable(removeExt(filePath))\n const fullPath = join(fullDir, filePath)\n return { filePath, variableName, fullPath }\n }\n const parentRoutePath = removeTrailingSlash(parent?.routePath ?? '/')\n\n switch (node.type) {\n case 'index': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n const routePath = `${parentRoutePath}/`\n return {\n filePath,\n fullPath,\n variableName,\n routePath,\n _fsRouteType: 'static',\n } satisfies RouteNode\n }\n\n case 'route': {\n const lastSegment = node.path\n let routeNode: RouteNode\n\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n if (node.file) {\n const { filePath, variableName, fullPath } = getFile(node.file)\n routeNode = {\n filePath,\n fullPath,\n variableName,\n routePath,\n _fsRouteType: 'static',\n }\n } else {\n routeNode = {\n filePath: '',\n fullPath: '',\n variableName: routePathToVariable(routePath),\n routePath,\n isVirtual: true,\n _fsRouteType: 'static',\n }\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n\n // If the route has children, it should be a layout\n routeNode._fsRouteType = 'layout'\n }\n return routeNode\n }\n case 'layout': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n\n if (node.id !== undefined) {\n node.id = ensureLeadingUnderScore(node.id)\n } else {\n const baseName = path.basename(filePath)\n const fileNameWithoutExt = path.parse(baseName).name\n node.id = ensureLeadingUnderScore(fileNameWithoutExt)\n }\n const lastSegment = node.id\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n\n const routeNode: RouteNode = {\n fullPath,\n filePath,\n variableName,\n routePath,\n _fsRouteType: 'pathless_layout',\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n }\n return routeNode\n }\n }\n }),\n )\n return children.flat()\n}\n"],"names":["resolve","join","rootPathId","exports","loadConfigFile","virtualRootRouteSchema","getRouteNodesPhysical","routePathToVariable","removeExt","removeTrailingSlash","removeLeadingSlash","children"],"mappings":";;;;;;;;AAkBA,SAAS,wBAAwB,IAAY;AACvC,MAAA,GAAG,WAAW,GAAG,GAAG;AACf,WAAA;AAAA,EAAA;AAET,SAAO,IAAI,EAAE;AACf;AAEA,SAAS,YAAY,MAAmC;AAChD,QAAA,SAAS,CAAC,IAAI;AAEpB,MAAI,KAAK,UAAU;AACN,eAAA,SAAS,KAAK,UAAU;AACjC,aAAO,KAAK,GAAG,YAAY,KAAK,CAAC;AAAA,IAAA;AAAA,EACnC;AAEF,SAAO,KAAK;AAEL,SAAA;AACT;AAEsB,eAAA,cACpB,WASA,MAC8B;AACxB,QAAA,UAAUA,KAAAA,QAAQ,UAAU,eAAe;AAC7C,MAAA,UAAU,uBAAuB,QAAW;AACxC,UAAA,IAAI,MAAM,iCAAiC;AAAA,EAAA;AAE/C,MAAA;AACJ,MAAI,WAA6B,CAAC;AAC9B,MAAA,OAAO,UAAU,uBAAuB,UAAU;AACpD,yBAAqB,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAAA,EAAA,OACK;AACL,yBAAqB,UAAU;AAAA,EAAA;AAEjC,aAAW,MAAM;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,EACrB;AACA,QAAM,WAAW,YAAY;AAAA,IAC3B;AAAA,IACA,UAAU,mBAAmB;AAAA,IAC7B,UAAUC,KAAA,KAAK,SAAS,mBAAmB,IAAI;AAAA,IAC/C,cAAc;AAAA,IACd,WAAW,IAAIC,WAAAA,UAAU;AAAA,IACzB,cAAc;AAAA,EAAA,CACf;AAEK,QAAA,gBAAgB,SAAS,CAAC;AAC1B,QAAA,aAAa,SAAS,MAAM,CAAC;AAE5B,SAAA,EAAE,eAAe,WAAW;AACrC;AAgBA,eAAe,oCACb,WACA,MAC2B;AAEzB,MAAA,UAAU,uBAAuB,UACjC,OAAO,UAAU,uBAAuB,YACxC,UAAU,uBAAuB,IACjC;AACM,UAAA,IAAI,MAAM,0CAA0C;AAAA,EAAA;AAE5D,QAAMC,WAAU,MAAMC,8BAAeH,KAAAA,KAAK,MAAM,UAAU,kBAAkB,CAAC;AAE7E,MAAI,EAAE,YAAYE,aAAY,EAAE,aAAaA,WAAU;AACrD,UAAM,IAAI;AAAA,MACR,uBAAuB,UAAU,kBAAkB;AAAA,IACrD;AAAA,EAAA;AAGF,QAAM,qBACJ,YAAYA,WAAUA,SAAQ,SAASA,SAAQ;AAE1C,SAAAE,OAAA,uBAAuB,MAAM,kBAAkB;AACxD;AAEA,eAAsB,uBACpB,WAQA,MACA,SACA,OACA,QAC2B;AAC3B,MAAI,UAAU,QAAW;AACvB,WAAO,CAAC;AAAA,EAAA;AAEJ,QAAA,WAAW,MAAM,QAAQ;AAAA,IAC7B,MAAM,IAAI,OAAO,SAAS;AACpB,UAAA,KAAK,SAAS,YAAY;AACtB,cAAA,EAAE,WAAW,IAAI,MAAMC,gBAAA;AAAA,UAC3B;AAAA,YACE,GAAG;AAAA,YACH,iBAAiBN,KAAA,QAAQ,SAAS,KAAK,SAAS;AAAA,UAClD;AAAA,UACA;AAAA,QACF;AACW,mBAAA,QAAQ,CAAC,gBAAgB;AAClC,sBAAY,eAAeO,MAAA;AAAA,YACzB,GAAG,KAAK,UAAU,IAAIC,MAAAA,UAAU,YAAY,QAAQ,CAAC;AAAA,UACvD;AACY,sBAAA,YAAY,IAAG,iCAAQ,cAAa,EAAE,GAAG,KAAK,UAAU,GAAG,YAAY,SAAS;AAC5F,sBAAY,WAAW,GAAG,KAAK,SAAS,IAAI,YAAY,QAAQ;AAAA,QAAA,CACjE;AACM,eAAA;AAAA,MAAA;AAGT,eAAS,QAAQ,MAAc;AAC7B,cAAM,WAAW;AACjB,cAAM,eAAeD,MAAAA,oBAAoBC,MAAU,UAAA,QAAQ,CAAC;AACtD,cAAA,WAAWP,KAAAA,KAAK,SAAS,QAAQ;AAChC,eAAA,EAAE,UAAU,cAAc,SAAS;AAAA,MAAA;AAE5C,YAAM,kBAAkBQ,MAAA,qBAAoB,iCAAQ,cAAa,GAAG;AAEpE,cAAQ,KAAK,MAAM;AAAA,QACjB,KAAK,SAAS;AACZ,gBAAM,EAAE,UAAU,cAAc,SAAa,IAAA,QAAQ,KAAK,IAAI;AACxD,gBAAA,YAAY,GAAG,eAAe;AAC7B,iBAAA;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAChB;AAAA,QAAA;AAAA,QAGF,KAAK,SAAS;AACZ,gBAAM,cAAc,KAAK;AACrB,cAAA;AAEJ,gBAAM,YAAY,GAAG,eAAe,IAAIC,MAAA,mBAAmB,WAAW,CAAC;AACvE,cAAI,KAAK,MAAM;AACb,kBAAM,EAAE,UAAU,cAAc,SAAa,IAAA,QAAQ,KAAK,IAAI;AAClD,wBAAA;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,cAAc;AAAA,YAChB;AAAA,UAAA,OACK;AACO,wBAAA;AAAA,cACV,UAAU;AAAA,cACV,UAAU;AAAA,cACV,cAAcH,0BAAoB,SAAS;AAAA,cAC3C;AAAA,cACA,WAAW;AAAA,cACX,cAAc;AAAA,YAChB;AAAA,UAAA;AAGE,cAAA,KAAK,aAAa,QAAW;AAC/B,kBAAMI,YAAW,MAAM;AAAA,cACrB;AAAA,cACA;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL;AAAA,YACF;AACA,sBAAU,WAAWA;AAGrB,sBAAU,eAAe;AAAA,UAAA;AAEpB,iBAAA;AAAA,QAAA;AAAA,QAET,KAAK,UAAU;AACb,gBAAM,EAAE,UAAU,cAAc,SAAa,IAAA,QAAQ,KAAK,IAAI;AAE1D,cAAA,KAAK,OAAO,QAAW;AACpB,iBAAA,KAAK,wBAAwB,KAAK,EAAE;AAAA,UAAA,OACpC;AACC,kBAAA,WAAW,KAAK,SAAS,QAAQ;AACvC,kBAAM,qBAAqB,KAAK,MAAM,QAAQ,EAAE;AAC3C,iBAAA,KAAK,wBAAwB,kBAAkB;AAAA,UAAA;AAEtD,gBAAM,cAAc,KAAK;AACzB,gBAAM,YAAY,GAAG,eAAe,IAAID,MAAA,mBAAmB,WAAW,CAAC;AAEvE,gBAAM,YAAuB;AAAA,YAC3B;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAChB;AAEI,cAAA,KAAK,aAAa,QAAW;AAC/B,kBAAMC,YAAW,MAAM;AAAA,cACrB;AAAA,cACA;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL;AAAA,YACF;AACA,sBAAU,WAAWA;AAAAA,UAAA;AAEhB,iBAAA;AAAA,QAAA;AAAA,MACT;AAAA,IAEH,CAAA;AAAA,EACH;AACA,SAAO,SAAS,KAAK;AACvB;;;"}
|
|
1
|
+
{"version":3,"file":"getRouteNodes.cjs","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport { rootPathId } from '../physical/rootPathId'\nimport { virtualRootRouteSchema } from './config'\nimport { loadConfigFile } from './loadConfigFile'\nimport type {\n VirtualRootRoute,\n VirtualRouteNode,\n} from '@tanstack/virtual-file-routes'\nimport type { GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nfunction ensureLeadingUnderScore(id: string) {\n if (id.startsWith('_')) {\n return id\n }\n return `_${id}`\n}\n\nfunction flattenTree(node: RouteNode): Array<RouteNode> {\n const result = [node]\n\n if (node.children) {\n for (const child of node.children) {\n result.push(...flattenTree(child))\n }\n }\n delete node.children\n\n return result\n}\n\nexport async function getRouteNodes(\n tsrConfig: Pick<\n Config,\n | 'routesDirectory'\n | 'virtualRouteConfig'\n | 'routeFileIgnorePrefix'\n | 'disableLogging'\n | 'indexToken'\n | 'routeToken'\n >,\n root: string,\n): Promise<GetRouteNodesResult> {\n const fullDir = resolve(tsrConfig.routesDirectory)\n if (tsrConfig.virtualRouteConfig === undefined) {\n throw new Error(`virtualRouteConfig is undefined`)\n }\n let virtualRouteConfig: VirtualRootRoute\n let children: Array<RouteNode> = []\n if (typeof tsrConfig.virtualRouteConfig === 'string') {\n virtualRouteConfig = await getVirtualRouteConfigFromFileExport(\n tsrConfig,\n root,\n )\n } else {\n virtualRouteConfig = tsrConfig.virtualRouteConfig\n }\n children = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n virtualRouteConfig.children,\n )\n const allNodes = flattenTree({\n children,\n filePath: virtualRouteConfig.file,\n fullPath: join(fullDir, virtualRouteConfig.file),\n variableName: 'root',\n routePath: `/${rootPathId}`,\n _fsRouteType: '__root',\n })\n\n const rootRouteNode = allNodes[0]\n const routeNodes = allNodes.slice(1)\n\n return { rootRouteNode, routeNodes }\n}\n\n/**\n * Get the virtual route config from a file export\n *\n * @example\n * ```ts\n * // routes.ts\n * import { rootRoute } from '@tanstack/virtual-file-routes'\n *\n * export const routes = rootRoute({ ... })\n * // or\n * export default rootRoute({ ... })\n * ```\n *\n */\nasync function getVirtualRouteConfigFromFileExport(\n tsrConfig: Pick<Config, 'virtualRouteConfig'>,\n root: string,\n): Promise<VirtualRootRoute> {\n if (\n tsrConfig.virtualRouteConfig === undefined ||\n typeof tsrConfig.virtualRouteConfig !== 'string' ||\n tsrConfig.virtualRouteConfig === ''\n ) {\n throw new Error(`virtualRouteConfig is undefined or empty`)\n }\n const exports = await loadConfigFile(join(root, tsrConfig.virtualRouteConfig))\n\n if (!('routes' in exports) && !('default' in exports)) {\n throw new Error(\n `routes not found in ${tsrConfig.virtualRouteConfig}. The routes export must be named like 'export const routes = ...' or done using 'export default ...'`,\n )\n }\n\n const virtualRouteConfig =\n 'routes' in exports ? exports.routes : exports.default\n\n return virtualRootRouteSchema.parse(virtualRouteConfig)\n}\n\nexport async function getRouteNodesRecursive(\n tsrConfig: Pick<\n Config,\n | 'routesDirectory'\n | 'routeFileIgnorePrefix'\n | 'disableLogging'\n | 'indexToken'\n | 'routeToken'\n >,\n root: string,\n fullDir: string,\n nodes?: Array<VirtualRouteNode>,\n parent?: RouteNode,\n): Promise<Array<RouteNode>> {\n if (nodes === undefined) {\n return []\n }\n const children = await Promise.all(\n nodes.map(async (node) => {\n if (node.type === 'physical') {\n const { routeNodes } = await getRouteNodesPhysical(\n {\n ...tsrConfig,\n routesDirectory: resolve(fullDir, node.directory),\n },\n root,\n )\n routeNodes.forEach((subtreeNode) => {\n subtreeNode.variableName = routePathToVariable(\n `${node.pathPrefix}/${removeExt(subtreeNode.filePath)}`,\n )\n subtreeNode.routePath = `${parent?.routePath ?? ''}${node.pathPrefix}${subtreeNode.routePath}`\n subtreeNode.filePath = `${node.directory}/${subtreeNode.filePath}`\n })\n return routeNodes\n }\n\n function getFile(file: string) {\n const filePath = file\n const variableName = routePathToVariable(removeExt(filePath))\n const fullPath = join(fullDir, filePath)\n return { filePath, variableName, fullPath }\n }\n const parentRoutePath = removeTrailingSlash(parent?.routePath ?? '/')\n\n switch (node.type) {\n case 'index': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n const routePath = `${parentRoutePath}/`\n return {\n filePath,\n fullPath,\n variableName,\n routePath,\n _fsRouteType: 'static',\n } satisfies RouteNode\n }\n\n case 'route': {\n const lastSegment = node.path\n let routeNode: RouteNode\n\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n if (node.file) {\n const { filePath, variableName, fullPath } = getFile(node.file)\n routeNode = {\n filePath,\n fullPath,\n variableName,\n routePath,\n _fsRouteType: 'static',\n }\n } else {\n routeNode = {\n filePath: '',\n fullPath: '',\n variableName: routePathToVariable(routePath),\n routePath,\n isVirtual: true,\n _fsRouteType: 'static',\n }\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n\n // If the route has children, it should be a layout\n routeNode._fsRouteType = 'layout'\n }\n return routeNode\n }\n case 'layout': {\n const { filePath, variableName, fullPath } = getFile(node.file)\n\n if (node.id !== undefined) {\n node.id = ensureLeadingUnderScore(node.id)\n } else {\n const baseName = path.basename(filePath)\n const fileNameWithoutExt = path.parse(baseName).name\n node.id = ensureLeadingUnderScore(fileNameWithoutExt)\n }\n const lastSegment = node.id\n const routePath = `${parentRoutePath}/${removeLeadingSlash(lastSegment)}`\n\n const routeNode: RouteNode = {\n fullPath,\n filePath,\n variableName,\n routePath,\n _fsRouteType: 'pathless_layout',\n }\n\n if (node.children !== undefined) {\n const children = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n }\n return routeNode\n }\n }\n }),\n )\n return children.flat()\n}\n"],"names":["resolve","join","rootPathId","exports","loadConfigFile","virtualRootRouteSchema","getRouteNodesPhysical","routePathToVariable","removeExt","removeTrailingSlash","removeLeadingSlash","children"],"mappings":"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"}
|