@tanstack/router-generator 1.121.0-alpha.26 → 1.121.0-alpha.28

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.
Files changed (75) hide show
  1. package/dist/cjs/config.cjs +5 -5
  2. package/dist/cjs/config.cjs.map +1 -1
  3. package/dist/cjs/config.d.cts +3 -3
  4. package/dist/cjs/filesystem/physical/getRouteNodes.cjs +18 -4
  5. package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
  6. package/dist/cjs/filesystem/physical/getRouteNodes.d.cts +1 -0
  7. package/dist/cjs/filesystem/virtual/config.cjs.map +1 -1
  8. package/dist/cjs/filesystem/virtual/getRouteNodes.cjs +18 -12
  9. package/dist/cjs/filesystem/virtual/getRouteNodes.cjs.map +1 -1
  10. package/dist/cjs/filesystem/virtual/getRouteNodes.d.cts +4 -1
  11. package/dist/cjs/filesystem/virtual/loadConfigFile.cjs.map +1 -1
  12. package/dist/cjs/generator.cjs +147 -98
  13. package/dist/cjs/generator.cjs.map +1 -1
  14. package/dist/cjs/generator.d.cts +11 -9
  15. package/dist/cjs/index.d.cts +1 -1
  16. package/dist/cjs/logger.cjs.map +1 -1
  17. package/dist/cjs/plugin/default-generator-plugin.cjs +16 -10
  18. package/dist/cjs/plugin/default-generator-plugin.cjs.map +1 -1
  19. package/dist/cjs/template.cjs.map +1 -1
  20. package/dist/cjs/transform/default-transform-plugin.cjs +6 -4
  21. package/dist/cjs/transform/default-transform-plugin.cjs.map +1 -1
  22. package/dist/cjs/transform/transform.cjs +48 -32
  23. package/dist/cjs/transform/transform.cjs.map +1 -1
  24. package/dist/cjs/transform/transform.d.cts +1 -1
  25. package/dist/cjs/transform/types.d.cts +1 -1
  26. package/dist/cjs/transform/utils.cjs.map +1 -1
  27. package/dist/cjs/transform/utils.d.cts +1 -1
  28. package/dist/cjs/types.d.cts +5 -0
  29. package/dist/cjs/utils.cjs +43 -24
  30. package/dist/cjs/utils.cjs.map +1 -1
  31. package/dist/cjs/utils.d.cts +6 -0
  32. package/dist/esm/config.d.ts +3 -3
  33. package/dist/esm/config.js +6 -6
  34. package/dist/esm/config.js.map +1 -1
  35. package/dist/esm/filesystem/physical/getRouteNodes.d.ts +1 -0
  36. package/dist/esm/filesystem/physical/getRouteNodes.js +19 -5
  37. package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
  38. package/dist/esm/filesystem/virtual/config.js.map +1 -1
  39. package/dist/esm/filesystem/virtual/getRouteNodes.d.ts +4 -1
  40. package/dist/esm/filesystem/virtual/getRouteNodes.js +19 -13
  41. package/dist/esm/filesystem/virtual/getRouteNodes.js.map +1 -1
  42. package/dist/esm/filesystem/virtual/loadConfigFile.js.map +1 -1
  43. package/dist/esm/generator.d.ts +11 -9
  44. package/dist/esm/generator.js +150 -101
  45. package/dist/esm/generator.js.map +1 -1
  46. package/dist/esm/index.d.ts +1 -1
  47. package/dist/esm/logger.js.map +1 -1
  48. package/dist/esm/plugin/default-generator-plugin.js +16 -10
  49. package/dist/esm/plugin/default-generator-plugin.js.map +1 -1
  50. package/dist/esm/template.js.map +1 -1
  51. package/dist/esm/transform/default-transform-plugin.js +6 -4
  52. package/dist/esm/transform/default-transform-plugin.js.map +1 -1
  53. package/dist/esm/transform/transform.d.ts +1 -1
  54. package/dist/esm/transform/transform.js +48 -32
  55. package/dist/esm/transform/transform.js.map +1 -1
  56. package/dist/esm/transform/types.d.ts +1 -1
  57. package/dist/esm/transform/utils.d.ts +1 -1
  58. package/dist/esm/transform/utils.js.map +1 -1
  59. package/dist/esm/types.d.ts +5 -0
  60. package/dist/esm/utils.d.ts +6 -0
  61. package/dist/esm/utils.js +43 -24
  62. package/dist/esm/utils.js.map +1 -1
  63. package/package.json +5 -5
  64. package/src/config.ts +6 -5
  65. package/src/filesystem/physical/getRouteNodes.ts +31 -11
  66. package/src/filesystem/virtual/getRouteNodes.ts +32 -23
  67. package/src/generator.ts +196 -72
  68. package/src/index.ts +2 -0
  69. package/src/plugin/default-generator-plugin.ts +16 -3
  70. package/src/transform/default-transform-plugin.ts +5 -2
  71. package/src/transform/transform.ts +68 -43
  72. package/src/transform/types.ts +1 -1
  73. package/src/transform/utils.ts +1 -1
  74. package/src/types.ts +7 -0
  75. package/src/utils.ts +79 -31
@@ -125,3 +125,9 @@ export declare function lowerCaseFirstChar(value: string): string;
125
125
  export declare function mergeImportDeclarations(imports: Array<ImportDeclaration>): Array<ImportDeclaration>;
126
126
  export declare function hasChildWithExport(node: RouteNode, exportName: string): boolean;
127
127
  export declare const findParent: (node: RouteNode | undefined, exportName: string) => string;
128
+ export declare function buildFileRoutesByPathInterface(opts: {
129
+ routeNodes: Array<RouteNode>;
130
+ module: string;
131
+ interfaceName: string;
132
+ exportName: string;
133
+ }): string;
@@ -44,7 +44,7 @@ export declare const baseConfigSchema: z.ZodObject<{
44
44
  pathParamsAllowedCharacters?: (";" | ":" | "@" | "&" | "=" | "+" | "$" | ",")[] | undefined;
45
45
  }>;
46
46
  export type BaseConfig = z.infer<typeof baseConfigSchema>;
47
- export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
47
+ export declare const configSchema: z.ZodObject<{
48
48
  target: z.ZodDefault<z.ZodOptional<z.ZodEnum<["react", "solid"]>>>;
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>;
@@ -58,7 +58,7 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
58
58
  indexToken: z.ZodDefault<z.ZodOptional<z.ZodString>>;
59
59
  routeToken: z.ZodDefault<z.ZodOptional<z.ZodString>>;
60
60
  pathParamsAllowedCharacters: z.ZodOptional<z.ZodArray<z.ZodEnum<[";", ":", "@", "&", "=", "+", "$", ","]>, "many">>;
61
- }, {
61
+ } & {
62
62
  generatedRouteTree: z.ZodDefault<z.ZodOptional<z.ZodString>>;
63
63
  disableTypes: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
64
64
  verboseFileRoutes: z.ZodOptional<z.ZodBoolean>;
@@ -85,7 +85,7 @@ export declare const configSchema: z.ZodObject<z.objectUtil.extendShape<{
85
85
  }>>;
86
86
  plugins: z.ZodOptional<z.ZodArray<z.ZodType<GeneratorPlugin, z.ZodTypeDef, GeneratorPlugin>, "many">>;
87
87
  tmpDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
88
- }>, "strip", z.ZodTypeAny, {
88
+ }, "strip", z.ZodTypeAny, {
89
89
  target: "react" | "solid";
90
90
  routeFileIgnorePrefix: string;
91
91
  routesDirectory: string;
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
- import { tmpdir } from "node:os";
3
- import { existsSync, readFileSync, mkdirSync } from "node:fs";
2
+ import { existsSync, readFileSync } from "node:fs";
4
3
  import { z } from "zod";
5
4
  import { virtualRootRouteSchema } from "./filesystem/virtual/config.js";
6
5
  const baseConfigSchema = z.object({
@@ -89,10 +88,12 @@ function getConfig(inlineConfig = {}, configDirectory) {
89
88
  }
90
89
  }
91
90
  const resolveTmpDir = (dir) => {
91
+ if (Array.isArray(dir)) {
92
+ dir = path.join(...dir);
93
+ }
92
94
  if (!path.isAbsolute(dir)) {
93
95
  dir = path.resolve(process.cwd(), dir);
94
96
  }
95
- mkdirSync(dir, { recursive: true });
96
97
  return dir;
97
98
  };
98
99
  if (config.tmpDir) {
@@ -100,14 +101,13 @@ function getConfig(inlineConfig = {}, configDirectory) {
100
101
  } else if (process.env.TSR_TMP_DIR) {
101
102
  config.tmpDir = resolveTmpDir(process.env.TSR_TMP_DIR);
102
103
  } else {
103
- config.tmpDir = tmpdir();
104
+ config.tmpDir = resolveTmpDir([".tanstack", "tmp"]);
104
105
  }
105
106
  validateConfig(config);
106
107
  return config;
107
108
  }
108
109
  function validateConfig(config) {
109
- var _a;
110
- if (typeof ((_a = config.experimental) == null ? void 0 : _a.enableCodeSplitting) !== "undefined") {
110
+ if (typeof config.experimental?.enableCodeSplitting !== "undefined") {
111
111
  const message = `
112
112
  ------
113
113
  ⚠️ ⚠️ ⚠️
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import path from 'node:path'\nimport { tmpdir } from 'node:os'\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) => {\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 = tmpdir()\n }\n\n validateConfig(config)\n return config\n}\n\nfunction validateConfig(config: Config) {\n if (typeof config.experimental?.enableCodeSplitting !== 'undefined') {\n const message = `\n------\n⚠️ ⚠️ ⚠️\nERROR: The \"experimental.enableCodeSplitting\" flag has been made stable and is now \"autoCodeSplitting\". Please update your configuration file to use \"autoCodeSplitting\" instead of \"experimental.enableCodeSplitting\".\n------\n`\n console.error(message)\n throw new Error(message)\n }\n\n if (config.indexToken === config.routeToken) {\n throw new Error(\n `The \"indexToken\" and \"routeToken\" options must be different.`,\n )\n }\n\n if (\n config.routeFileIgnorePrefix &&\n config.routeFileIgnorePrefix.trim() === '_'\n ) {\n throw new Error(\n `The \"routeFileIgnorePrefix\" cannot be an underscore (\"_\"). This is a reserved character used to denote a pathless route. Please use a different prefix.`,\n )\n }\n\n return config\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { z } from 'zod'\nimport { virtualRootRouteSchema } from './filesystem/virtual/config'\nimport type { GeneratorPlugin } from './plugin/types'\n\nexport const baseConfigSchema = z.object({\n target: z.enum(['react', 'solid']).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 return dir\n }\n\n if (config.tmpDir) {\n config.tmpDir = resolveTmpDir(config.tmpDir)\n } else if (process.env.TSR_TMP_DIR) {\n config.tmpDir = resolveTmpDir(process.env.TSR_TMP_DIR)\n } else {\n config.tmpDir = resolveTmpDir(['.tanstack', 'tmp'])\n }\n\n validateConfig(config)\n return config\n}\n\nfunction validateConfig(config: Config) {\n if (typeof config.experimental?.enableCodeSplitting !== 'undefined') {\n const message = `\n------\n⚠️ ⚠️ ⚠️\nERROR: The \"experimental.enableCodeSplitting\" flag has been made stable and is now \"autoCodeSplitting\". Please update your configuration file to use \"autoCodeSplitting\" instead of \"experimental.enableCodeSplitting\".\n------\n`\n console.error(message)\n throw new Error(message)\n }\n\n if (config.indexToken === config.routeToken) {\n throw new Error(\n `The \"indexToken\" and \"routeToken\" options must be different.`,\n )\n }\n\n if (\n config.routeFileIgnorePrefix &&\n config.routeFileIgnorePrefix.trim() === '_'\n ) {\n throw new Error(\n `The \"routeFileIgnorePrefix\" cannot be an underscore (\"_\"). This is a reserved character used to denote a pathless route. Please use a different prefix.`,\n )\n }\n\n return config\n}\n"],"names":[],"mappings":";;;;AAMO,MAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,OAAO,CAAC,EAAE,SAAA,EAAW,QAAQ,OAAO;AAAA,EAC7D,oBAAoB,uBAAuB,GAAG,EAAE,OAAA,CAAQ,EAAE,SAAA;AAAA,EAC1D,iBAAiB,EAAE,OAAA,EAAS,SAAA;AAAA,EAC5B,uBAAuB,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,GAAG;AAAA,EACxD,wBAAwB,EAAE,OAAA,EAAS,SAAA;AAAA,EACnC,iBAAiB,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,cAAc;AAAA,EAC7D,YAAY,EAAE,KAAK,CAAC,UAAU,QAAQ,CAAC,EAAE,SAAA,EAAW,QAAQ,QAAQ;AAAA,EACpE,YAAY,EAAE,QAAA,EAAU,SAAA,EAAW,QAAQ,KAAK;AAAA,EAChD,gBAAgB,EAAE,QAAA,EAAU,SAAA,EAAW,QAAQ,KAAK;AAAA,EACpD,qBAAqB,EAClB,MAAM,EAAE,QAAQ,EAChB,SAAA,EACA,QAAQ;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAAA,EACH,YAAY,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,OAAO;AAAA,EACjD,YAAY,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,OAAO;AAAA,EACjD,6BAA6B,EAC1B,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC,CAAC,EACtD,SAAA;AACL,CAAC;AAIM,MAAM,eAAe,iBAAiB,OAAO;AAAA,EAClD,oBAAoB,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,wBAAwB;AAAA,EAC1E,cAAc,EAAE,QAAA,EAAU,SAAA,EAAW,QAAQ,KAAK;AAAA,EAClD,mBAAmB,EAAE,QAAA,EAAU,SAAA;AAAA,EAC/B,eAAe,EAAE,QAAA,EAAU,SAAA,EAAW,QAAQ,KAAK;AAAA,EACnD,2BAA2B,EAAE,QAAA,EAAU,SAAA,EAAW,QAAQ,IAAI;AAAA,EAC9D,qBAAqB,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,SAAA,EAAW,QAAQ,EAAE;AAAA,EAC9D,mBAAmB,EAAE,QAAA,EAAU,SAAA;AAAA,EAC/B,mBAAmB,EAChB,OAAO;AAAA,IACN,eAAe,EAAE,OAAA,EAAS,SAAA;AAAA,IAC1B,mBAAmB,EAAE,OAAA,EAAS,SAAA;AAAA,EAAS,CACxC,EACA,SAAA;AAAA,EACH,cAAc,EACX,OAAO;AAAA;AAAA,IAEN,qBAAqB,EAAE,QAAA,EAAU,SAAA;AAAA,EAAS,CAC3C,EACA,SAAA;AAAA,EACH,SAAS,EAAE,MAAM,EAAE,OAAA,CAAyB,EAAE,SAAA;AAAA,EAC9C,QAAQ,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,EAAE;AAC1C,CAAC;AAQM,SAAS,kBAAkB,EAAE,mBAAkC;AACpE,SAAO,KAAK,QAAQ,iBAAiB,iBAAiB;AACxD;AAEO,SAAS,UACd,eAAgC,CAAA,GAChC,iBACQ;AACR,MAAI,oBAAoB,QAAW;AACjC,sBAAkB,QAAQ,IAAA;AAAA,EAC5B;AACA,QAAM,qBAAqB,kBAAkB,EAAE,iBAAiB;AAChE,QAAM,SAAS,WAAW,kBAAkB;AAE5C,MAAI;AAEJ,MAAI,QAAQ;AACV,aAAS,aAAa,MAAM;AAAA,MAC1B,GAAG,KAAK,MAAM,aAAa,oBAAoB,OAAO,CAAC;AAAA,MACvD,GAAG;AAAA,IAAA,CACJ;AAAA,EACH,OAAO;AACL,aAAS,aAAa,MAAM,YAAY;AAAA,EAC1C;AAGA,MAAI,OAAO,cAAc;AACvB,WAAO,qBAAqB,OAAO,mBAAmB;AAAA,MACpD;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAGA,MAAI,iBAAiB;AAEnB,QAAI,KAAK,WAAW,eAAe,GAAG;AACpC,aAAO,kBAAkB,KAAK;AAAA,QAC5B;AAAA,QACA,OAAO;AAAA,MAAA;AAET,aAAO,qBAAqB,KAAK;AAAA,QAC/B;AAAA,QACA,OAAO;AAAA,MAAA;AAAA,IAEX,OAAO;AACL,aAAO,kBAAkB,KAAK;AAAA,QAC5B,QAAQ,IAAA;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MAAA;AAET,aAAO,qBAAqB,KAAK;AAAA,QAC/B,QAAQ,IAAA;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MAAA;AAAA,IAEX;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,QAAgC;AACrD,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,YAAM,KAAK,KAAK,GAAG,GAAG;AAAA,IACxB;AACA,QAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,YAAM,KAAK,QAAQ,QAAQ,IAAA,GAAO,GAAG;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,QAAQ;AACjB,WAAO,SAAS,cAAc,OAAO,MAAM;AAAA,EAC7C,WAAW,QAAQ,IAAI,aAAa;AAClC,WAAO,SAAS,cAAc,QAAQ,IAAI,WAAW;AAAA,EACvD,OAAO;AACL,WAAO,SAAS,cAAc,CAAC,aAAa,KAAK,CAAC;AAAA,EACpD;AAEA,iBAAe,MAAM;AACrB,SAAO;AACT;AAEA,SAAS,eAAe,QAAgB;AACtC,MAAI,OAAO,OAAO,cAAc,wBAAwB,aAAa;AACnE,UAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAMhB,YAAQ,MAAM,OAAO;AACrB,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AAEA,MAAI,OAAO,eAAe,OAAO,YAAY;AAC3C,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,MACE,OAAO,yBACP,OAAO,sBAAsB,KAAA,MAAW,KACxC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,SAAO;AACT;"}
@@ -1,5 +1,6 @@
1
1
  import { FsRouteType, GetRouteNodesResult } from '../../types.js';
2
2
  import { Config } from '../../config.js';
3
+ export declare function isVirtualConfigFile(fileName: string): boolean;
3
4
  export declare function getRouteNodes(config: Pick<Config, 'routesDirectory' | 'routeFilePrefix' | 'routeFileIgnorePrefix' | 'routeFileIgnorePattern' | 'disableLogging' | 'routeToken' | 'indexToken'>, root: string): Promise<GetRouteNodesResult>;
4
5
  /**
5
6
  * Determines the metadata for a given route path based on the provided configuration.
@@ -6,11 +6,16 @@ import { loadConfigFile } from "../virtual/loadConfigFile.js";
6
6
  import { logging } from "../../logger.js";
7
7
  import { rootPathId } from "./rootPathId.js";
8
8
  const disallowedRouteGroupConfiguration = /\(([^)]+)\).(ts|js|tsx|jsx)/;
9
+ const virtualConfigFileRegExp = /__virtual\.[mc]?[jt]s$/;
10
+ function isVirtualConfigFile(fileName) {
11
+ return virtualConfigFileRegExp.test(fileName);
12
+ }
9
13
  async function getRouteNodes(config, root) {
10
14
  const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } = config;
11
15
  const logger = logging({ disabled: config.disableLogging });
12
16
  const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? "", "g");
13
17
  const routeNodes = [];
18
+ const allPhysicalDirectories = [];
14
19
  async function recurse(dir) {
15
20
  const fullDir = path.resolve(config.routesDirectory, dir);
16
21
  let dirList = await fsp.readdir(fullDir, { withFileTypes: true });
@@ -19,6 +24,9 @@ async function getRouteNodes(config, root) {
19
24
  return false;
20
25
  }
21
26
  if (routeFilePrefix) {
27
+ if (routeFileIgnorePattern) {
28
+ return d.name.startsWith(routeFilePrefix) && !d.name.match(routeFileIgnoreRegExp);
29
+ }
22
30
  return d.name.startsWith(routeFilePrefix);
23
31
  }
24
32
  if (routeFileIgnorePattern) {
@@ -27,7 +35,7 @@ async function getRouteNodes(config, root) {
27
35
  return true;
28
36
  });
29
37
  const virtualConfigFile = dirList.find((dirent) => {
30
- return dirent.isFile() && dirent.name.match(/__virtual\.[mc]?[jt]s$/);
38
+ return dirent.isFile() && isVirtualConfigFile(dirent.name);
31
39
  });
32
40
  if (virtualConfigFile !== void 0) {
33
41
  const virtualRouteConfigExport = await loadConfigFile(
@@ -44,7 +52,7 @@ async function getRouteNodes(config, root) {
44
52
  file: "",
45
53
  children: virtualRouteSubtreeConfig
46
54
  };
47
- const { routeNodes: virtualRouteNodes } = await getRouteNodes$1(
55
+ const { routeNodes: virtualRouteNodes, physicalDirectories } = await getRouteNodes$1(
48
56
  {
49
57
  ...config,
50
58
  routesDirectory: fullDir,
@@ -52,6 +60,7 @@ async function getRouteNodes(config, root) {
52
60
  },
53
61
  root
54
62
  );
63
+ allPhysicalDirectories.push(...physicalDirectories);
55
64
  virtualRouteNodes.forEach((node) => {
56
65
  const filePath = replaceBackslash(path.join(dir, node.filePath));
57
66
  const routePath = `/${dir}${node.routePath}`;
@@ -66,7 +75,7 @@ async function getRouteNodes(config, root) {
66
75
  }
67
76
  await Promise.all(
68
77
  dirList.map(async (dirent) => {
69
- const fullPath = path.posix.join(fullDir, dirent.name);
78
+ const fullPath = replaceBackslash(path.join(fullDir, dirent.name));
70
79
  const relativePath = path.posix.join(dir, dirent.name);
71
80
  if (dirent.isDirectory()) {
72
81
  await recurse(relativePath);
@@ -131,7 +140,11 @@ async function getRouteNodes(config, root) {
131
140
  rootRouteNode._fsRouteType = "__root";
132
141
  rootRouteNode.variableName = "root";
133
142
  }
134
- return { rootRouteNode, routeNodes };
143
+ return {
144
+ rootRouteNode,
145
+ routeNodes,
146
+ physicalDirectories: allPhysicalDirectories
147
+ };
135
148
  }
136
149
  function getRouteMeta(routePath, config) {
137
150
  let fsRouteType = "static";
@@ -171,6 +184,7 @@ function isValidPathlessLayoutRoute(normalizedRoutePath, routeType, config) {
171
184
  }
172
185
  export {
173
186
  getRouteMeta,
174
- getRouteNodes
187
+ getRouteNodes,
188
+ isVirtualConfigFile
175
189
  };
176
190
  //# sourceMappingURL=getRouteNodes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n removeExt,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { logging } from '../../logger'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { FsRouteType, GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\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":["getRouteNodesVirtual"],"mappings":"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"}
1
+ {"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n determineInitialRoutePath,\n removeExt,\n replaceBackslash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { logging } from '../../logger'\nimport { rootPathId } from './rootPathId'\nimport type {\n VirtualRootRoute,\n VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { FsRouteType, GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx)/\n\nconst virtualConfigFileRegExp = /__virtual\\.[mc]?[jt]s$/\nexport function isVirtualConfigFile(fileName: string): boolean {\n return virtualConfigFileRegExp.test(fileName)\n}\n\nexport async function getRouteNodes(\n config: Pick<\n Config,\n | 'routesDirectory'\n | 'routeFilePrefix'\n | 'routeFileIgnorePrefix'\n | 'routeFileIgnorePattern'\n | 'disableLogging'\n | 'routeToken'\n | 'indexToken'\n >,\n root: string,\n): Promise<GetRouteNodesResult> {\n const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n config\n\n const logger = logging({ disabled: config.disableLogging })\n const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n const routeNodes: Array<RouteNode> = []\n const allPhysicalDirectories: Array<string> = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n dirList = dirList.filter((d) => {\n if (\n d.name.startsWith('.') ||\n (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n if (routeFileIgnorePattern) {\n return (\n d.name.startsWith(routeFilePrefix) &&\n !d.name.match(routeFileIgnoreRegExp)\n )\n }\n\n return d.name.startsWith(routeFilePrefix)\n }\n\n if (routeFileIgnorePattern) {\n return !d.name.match(routeFileIgnoreRegExp)\n }\n\n return true\n })\n\n const virtualConfigFile = dirList.find((dirent) => {\n return dirent.isFile() && isVirtualConfigFile(dirent.name)\n })\n\n if (virtualConfigFile !== undefined) {\n const virtualRouteConfigExport = await loadConfigFile(\n path.resolve(fullDir, virtualConfigFile.name),\n )\n let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n if (typeof virtualRouteConfigExport.default === 'function') {\n virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n } else {\n virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n }\n const dummyRoot: VirtualRootRoute = {\n type: 'root',\n file: '',\n children: virtualRouteSubtreeConfig,\n }\n const { routeNodes: virtualRouteNodes, physicalDirectories } =\n await getRouteNodesVirtual(\n {\n ...config,\n routesDirectory: fullDir,\n virtualRouteConfig: dummyRoot,\n },\n root,\n )\n allPhysicalDirectories.push(...physicalDirectories)\n virtualRouteNodes.forEach((node) => {\n const filePath = replaceBackslash(path.join(dir, node.filePath))\n const routePath = `/${dir}${node.routePath}`\n\n node.variableName = routePathToVariable(\n `${dir}/${removeExt(node.filePath)}`,\n )\n node.routePath = routePath\n node.filePath = filePath\n })\n\n routeNodes.push(...virtualRouteNodes)\n\n return\n }\n\n await Promise.all(\n dirList.map(async (dirent) => {\n const fullPath = replaceBackslash(path.join(fullDir, dirent.name))\n const relativePath = path.posix.join(dir, dirent.name)\n\n if (dirent.isDirectory()) {\n await recurse(relativePath)\n } else if (fullPath.match(/\\.(tsx|ts|jsx|js)$/)) {\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 {\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":["getRouteNodesVirtual"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../../../src/filesystem/virtual/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport type {\n LayoutRoute,\n PhysicalSubtree,\n Route,\n VirtualRootRoute,\n} from '@tanstack/virtual-file-routes'\n\nconst indexRouteSchema = z.object({\n type: z.literal('index'),\n file: z.string(),\n})\n\nconst layoutRouteSchema: z.ZodType<LayoutRoute> = z.object({\n type: z.literal('layout'),\n id: z.string().optional(),\n file: z.string(),\n children: z.array(z.lazy(() => virtualRouteNodeSchema)).optional(),\n})\n\nconst routeSchema: z.ZodType<Route> = z.object({\n type: z.literal('route'),\n file: z.string().optional(),\n path: z.string(),\n children: z.array(z.lazy(() => virtualRouteNodeSchema)).optional(),\n})\n\nconst physicalSubTreeSchema: z.ZodType<PhysicalSubtree> = z.object({\n type: z.literal('physical'),\n directory: z.string(),\n pathPrefix: z.string(),\n})\n\nconst virtualRouteNodeSchema = z.union([\n indexRouteSchema,\n layoutRouteSchema,\n routeSchema,\n physicalSubTreeSchema,\n])\n\nexport const virtualRootRouteSchema: z.ZodType<VirtualRootRoute> = z.object({\n type: z.literal('root'),\n file: z.string(),\n children: z.array(virtualRouteNodeSchema).optional(),\n})\n"],"names":[],"mappings":";AAQA,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,MAAM,EAAE,QAAQ,OAAO;AAAA,EACvB,MAAM,EAAE,OAAO;AACjB,CAAC;AAED,MAAM,oBAA4C,EAAE,OAAO;AAAA,EACzD,MAAM,EAAE,QAAQ,QAAQ;AAAA,EACxB,IAAI,EAAE,OAAO,EAAE,SAAS;AAAA,EACxB,MAAM,EAAE,OAAO;AAAA,EACf,UAAU,EAAE,MAAM,EAAE,KAAK,MAAM,sBAAsB,CAAC,EAAE,SAAS;AACnE,CAAC;AAED,MAAM,cAAgC,EAAE,OAAO;AAAA,EAC7C,MAAM,EAAE,QAAQ,OAAO;AAAA,EACvB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,MAAM,EAAE,OAAO;AAAA,EACf,UAAU,EAAE,MAAM,EAAE,KAAK,MAAM,sBAAsB,CAAC,EAAE,SAAS;AACnE,CAAC;AAED,MAAM,wBAAoD,EAAE,OAAO;AAAA,EACjE,MAAM,EAAE,QAAQ,UAAU;AAAA,EAC1B,WAAW,EAAE,OAAO;AAAA,EACpB,YAAY,EAAE,OAAO;AACvB,CAAC;AAED,MAAM,yBAAyB,EAAE,MAAM;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEY,MAAA,yBAAsD,EAAE,OAAO;AAAA,EAC1E,MAAM,EAAE,QAAQ,MAAM;AAAA,EACtB,MAAM,EAAE,OAAO;AAAA,EACf,UAAU,EAAE,MAAM,sBAAsB,EAAE,SAAS;AACrD,CAAC;"}
1
+ {"version":3,"file":"config.js","sources":["../../../../src/filesystem/virtual/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport type {\n LayoutRoute,\n PhysicalSubtree,\n Route,\n VirtualRootRoute,\n} from '@tanstack/virtual-file-routes'\n\nconst indexRouteSchema = z.object({\n type: z.literal('index'),\n file: z.string(),\n})\n\nconst layoutRouteSchema: z.ZodType<LayoutRoute> = z.object({\n type: z.literal('layout'),\n id: z.string().optional(),\n file: z.string(),\n children: z.array(z.lazy(() => virtualRouteNodeSchema)).optional(),\n})\n\nconst routeSchema: z.ZodType<Route> = z.object({\n type: z.literal('route'),\n file: z.string().optional(),\n path: z.string(),\n children: z.array(z.lazy(() => virtualRouteNodeSchema)).optional(),\n})\n\nconst physicalSubTreeSchema: z.ZodType<PhysicalSubtree> = z.object({\n type: z.literal('physical'),\n directory: z.string(),\n pathPrefix: z.string(),\n})\n\nconst virtualRouteNodeSchema = z.union([\n indexRouteSchema,\n layoutRouteSchema,\n routeSchema,\n physicalSubTreeSchema,\n])\n\nexport const virtualRootRouteSchema: z.ZodType<VirtualRootRoute> = z.object({\n type: z.literal('root'),\n file: z.string(),\n children: z.array(virtualRouteNodeSchema).optional(),\n})\n"],"names":[],"mappings":";AAQA,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,MAAM,EAAE,QAAQ,OAAO;AAAA,EACvB,MAAM,EAAE,OAAA;AACV,CAAC;AAED,MAAM,oBAA4C,EAAE,OAAO;AAAA,EACzD,MAAM,EAAE,QAAQ,QAAQ;AAAA,EACxB,IAAI,EAAE,OAAA,EAAS,SAAA;AAAA,EACf,MAAM,EAAE,OAAA;AAAA,EACR,UAAU,EAAE,MAAM,EAAE,KAAK,MAAM,sBAAsB,CAAC,EAAE,SAAA;AAC1D,CAAC;AAED,MAAM,cAAgC,EAAE,OAAO;AAAA,EAC7C,MAAM,EAAE,QAAQ,OAAO;AAAA,EACvB,MAAM,EAAE,OAAA,EAAS,SAAA;AAAA,EACjB,MAAM,EAAE,OAAA;AAAA,EACR,UAAU,EAAE,MAAM,EAAE,KAAK,MAAM,sBAAsB,CAAC,EAAE,SAAA;AAC1D,CAAC;AAED,MAAM,wBAAoD,EAAE,OAAO;AAAA,EACjE,MAAM,EAAE,QAAQ,UAAU;AAAA,EAC1B,WAAW,EAAE,OAAA;AAAA,EACb,YAAY,EAAE,OAAA;AAChB,CAAC;AAED,MAAM,yBAAyB,EAAE,MAAM;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,MAAM,yBAAsD,EAAE,OAAO;AAAA,EAC1E,MAAM,EAAE,QAAQ,MAAM;AAAA,EACtB,MAAM,EAAE,OAAA;AAAA,EACR,UAAU,EAAE,MAAM,sBAAsB,EAAE,SAAA;AAC5C,CAAC;"}
@@ -2,4 +2,7 @@ import { VirtualRouteNode } from '@tanstack/virtual-file-routes';
2
2
  import { GetRouteNodesResult, RouteNode } from '../../types.js';
3
3
  import { Config } from '../../config.js';
4
4
  export declare function getRouteNodes(tsrConfig: Pick<Config, 'routesDirectory' | 'virtualRouteConfig' | 'routeFileIgnorePrefix' | 'disableLogging' | 'indexToken' | 'routeToken'>, root: string): Promise<GetRouteNodesResult>;
5
- export declare function getRouteNodesRecursive(tsrConfig: Pick<Config, 'routesDirectory' | 'routeFileIgnorePrefix' | 'disableLogging' | 'indexToken' | 'routeToken'>, root: string, fullDir: string, nodes?: Array<VirtualRouteNode>, parent?: RouteNode): Promise<Array<RouteNode>>;
5
+ export declare function getRouteNodesRecursive(tsrConfig: Pick<Config, 'routesDirectory' | 'routeFileIgnorePrefix' | 'disableLogging' | 'indexToken' | 'routeToken'>, root: string, fullDir: string, nodes?: Array<VirtualRouteNode>, parent?: RouteNode): Promise<{
6
+ children: Array<RouteNode>;
7
+ physicalDirectories: Array<string>;
8
+ }>;
@@ -1,5 +1,5 @@
1
1
  import path, { resolve, join } from "node:path";
2
- import { routePathToVariable, removeExt, removeTrailingSlash, removeLeadingSlash } from "../../utils.js";
2
+ import { replaceBackslash, routePathToVariable, removeExt, removeTrailingSlash, removeLeadingSlash } from "../../utils.js";
3
3
  import { getRouteNodes as getRouteNodes$1 } from "../physical/getRouteNodes.js";
4
4
  import { rootPathId } from "../physical/rootPathId.js";
5
5
  import { virtualRootRouteSchema } from "./config.js";
@@ -26,7 +26,6 @@ async function getRouteNodes(tsrConfig, root) {
26
26
  throw new Error(`virtualRouteConfig is undefined`);
27
27
  }
28
28
  let virtualRouteConfig;
29
- let children = [];
30
29
  if (typeof tsrConfig.virtualRouteConfig === "string") {
31
30
  virtualRouteConfig = await getVirtualRouteConfigFromFileExport(
32
31
  tsrConfig,
@@ -35,7 +34,7 @@ async function getRouteNodes(tsrConfig, root) {
35
34
  } else {
36
35
  virtualRouteConfig = tsrConfig.virtualRouteConfig;
37
36
  }
38
- children = await getRouteNodesRecursive(
37
+ const { children, physicalDirectories } = await getRouteNodesRecursive(
39
38
  tsrConfig,
40
39
  root,
41
40
  fullDir,
@@ -44,14 +43,14 @@ async function getRouteNodes(tsrConfig, root) {
44
43
  const allNodes = flattenTree({
45
44
  children,
46
45
  filePath: virtualRouteConfig.file,
47
- fullPath: join(fullDir, virtualRouteConfig.file),
46
+ fullPath: replaceBackslash(join(fullDir, virtualRouteConfig.file)),
48
47
  variableName: "root",
49
48
  routePath: `/${rootPathId}`,
50
49
  _fsRouteType: "__root"
51
50
  });
52
51
  const rootRouteNode = allNodes[0];
53
52
  const routeNodes = allNodes.slice(1);
54
- return { rootRouteNode, routeNodes };
53
+ return { rootRouteNode, routeNodes, physicalDirectories };
55
54
  }
56
55
  async function getVirtualRouteConfigFromFileExport(tsrConfig, root) {
57
56
  if (tsrConfig.virtualRouteConfig === void 0 || typeof tsrConfig.virtualRouteConfig !== "string" || tsrConfig.virtualRouteConfig === "") {
@@ -68,23 +67,25 @@ async function getVirtualRouteConfigFromFileExport(tsrConfig, root) {
68
67
  }
69
68
  async function getRouteNodesRecursive(tsrConfig, root, fullDir, nodes, parent) {
70
69
  if (nodes === void 0) {
71
- return [];
70
+ return { children: [], physicalDirectories: [] };
72
71
  }
72
+ const allPhysicalDirectories = [];
73
73
  const children = await Promise.all(
74
74
  nodes.map(async (node) => {
75
75
  if (node.type === "physical") {
76
- const { routeNodes } = await getRouteNodes$1(
76
+ const { routeNodes, physicalDirectories } = await getRouteNodes$1(
77
77
  {
78
78
  ...tsrConfig,
79
79
  routesDirectory: resolve(fullDir, node.directory)
80
80
  },
81
81
  root
82
82
  );
83
+ allPhysicalDirectories.push(node.directory);
83
84
  routeNodes.forEach((subtreeNode) => {
84
85
  subtreeNode.variableName = routePathToVariable(
85
86
  `${node.pathPrefix}/${removeExt(subtreeNode.filePath)}`
86
87
  );
87
- subtreeNode.routePath = `${(parent == null ? void 0 : parent.routePath) ?? ""}${node.pathPrefix}${subtreeNode.routePath}`;
88
+ subtreeNode.routePath = `${parent?.routePath ?? ""}${node.pathPrefix}${subtreeNode.routePath}`;
88
89
  subtreeNode.filePath = `${node.directory}/${subtreeNode.filePath}`;
89
90
  });
90
91
  return routeNodes;
@@ -92,10 +93,10 @@ async function getRouteNodesRecursive(tsrConfig, root, fullDir, nodes, parent) {
92
93
  function getFile(file) {
93
94
  const filePath = file;
94
95
  const variableName = routePathToVariable(removeExt(filePath));
95
- const fullPath = join(fullDir, filePath);
96
+ const fullPath = replaceBackslash(join(fullDir, filePath));
96
97
  return { filePath, variableName, fullPath };
97
98
  }
98
- const parentRoutePath = removeTrailingSlash((parent == null ? void 0 : parent.routePath) ?? "/");
99
+ const parentRoutePath = removeTrailingSlash(parent?.routePath ?? "/");
99
100
  switch (node.type) {
100
101
  case "index": {
101
102
  const { filePath, variableName, fullPath } = getFile(node.file);
@@ -132,7 +133,7 @@ async function getRouteNodesRecursive(tsrConfig, root, fullDir, nodes, parent) {
132
133
  };
133
134
  }
134
135
  if (node.children !== void 0) {
135
- const children2 = await getRouteNodesRecursive(
136
+ const { children: children2, physicalDirectories } = await getRouteNodesRecursive(
136
137
  tsrConfig,
137
138
  root,
138
139
  fullDir,
@@ -140,6 +141,7 @@ async function getRouteNodesRecursive(tsrConfig, root, fullDir, nodes, parent) {
140
141
  routeNode
141
142
  );
142
143
  routeNode.children = children2;
144
+ allPhysicalDirectories.push(...physicalDirectories);
143
145
  routeNode._fsRouteType = "layout";
144
146
  }
145
147
  return routeNode;
@@ -163,7 +165,7 @@ async function getRouteNodesRecursive(tsrConfig, root, fullDir, nodes, parent) {
163
165
  _fsRouteType: "pathless_layout"
164
166
  };
165
167
  if (node.children !== void 0) {
166
- const children2 = await getRouteNodesRecursive(
168
+ const { children: children2, physicalDirectories } = await getRouteNodesRecursive(
167
169
  tsrConfig,
168
170
  root,
169
171
  fullDir,
@@ -171,13 +173,17 @@ async function getRouteNodesRecursive(tsrConfig, root, fullDir, nodes, parent) {
171
173
  routeNode
172
174
  );
173
175
  routeNode.children = children2;
176
+ allPhysicalDirectories.push(...physicalDirectories);
174
177
  }
175
178
  return routeNode;
176
179
  }
177
180
  }
178
181
  })
179
182
  );
180
- return children.flat();
183
+ return {
184
+ children: children.flat(),
185
+ physicalDirectories: allPhysicalDirectories
186
+ };
181
187
  }
182
188
  export {
183
189
  getRouteNodes,
@@ -1 +1 @@
1
- {"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n routePathToVariable,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesPhysical } from '../physical/getRouteNodes'\nimport { 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":["getRouteNodesPhysical","children"],"mappings":"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"}
1
+ {"version":3,"file":"getRouteNodes.js","sources":["../../../../src/filesystem/virtual/getRouteNodes.ts"],"sourcesContent":["import path, { join, resolve } from 'node:path'\nimport {\n removeExt,\n removeLeadingSlash,\n removeTrailingSlash,\n replaceBackslash,\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 if (typeof tsrConfig.virtualRouteConfig === 'string') {\n virtualRouteConfig = await getVirtualRouteConfigFromFileExport(\n tsrConfig,\n root,\n )\n } else {\n virtualRouteConfig = tsrConfig.virtualRouteConfig\n }\n const { children, physicalDirectories } = await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n virtualRouteConfig.children,\n )\n const allNodes = flattenTree({\n children,\n filePath: virtualRouteConfig.file,\n fullPath: replaceBackslash(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, physicalDirectories }\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<{ children: Array<RouteNode>; physicalDirectories: Array<string> }> {\n if (nodes === undefined) {\n return { children: [], physicalDirectories: [] }\n }\n const allPhysicalDirectories: Array<string> = []\n const children = await Promise.all(\n nodes.map(async (node) => {\n if (node.type === 'physical') {\n const { routeNodes, physicalDirectories } = await getRouteNodesPhysical(\n {\n ...tsrConfig,\n routesDirectory: resolve(fullDir, node.directory),\n },\n root,\n )\n allPhysicalDirectories.push(node.directory)\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 = replaceBackslash(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, physicalDirectories } =\n await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n allPhysicalDirectories.push(...physicalDirectories)\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, physicalDirectories } =\n await getRouteNodesRecursive(\n tsrConfig,\n root,\n fullDir,\n node.children,\n routeNode,\n )\n routeNode.children = children\n allPhysicalDirectories.push(...physicalDirectories)\n }\n return routeNode\n }\n }\n }),\n )\n return {\n children: children.flat(),\n physicalDirectories: allPhysicalDirectories,\n }\n}\n"],"names":["getRouteNodesPhysical","children"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loadConfigFile.js","sources":["../../../../src/filesystem/virtual/loadConfigFile.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url'\nimport { tsImport } from 'tsx/esm/api'\n\nexport async function loadConfigFile(filePath: string) {\n const fileURL = pathToFileURL(filePath).href\n const loaded = await tsImport(fileURL, './')\n return loaded\n}\n"],"names":[],"mappings":";;AAGA,eAAsB,eAAe,UAAkB;AAC/C,QAAA,UAAU,cAAc,QAAQ,EAAE;AACxC,QAAM,SAAS,MAAM,SAAS,SAAS,IAAI;AACpC,SAAA;AACT;"}
1
+ {"version":3,"file":"loadConfigFile.js","sources":["../../../../src/filesystem/virtual/loadConfigFile.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url'\nimport { tsImport } from 'tsx/esm/api'\n\nexport async function loadConfigFile(filePath: string) {\n const fileURL = pathToFileURL(filePath).href\n const loaded = await tsImport(fileURL, './')\n return loaded\n}\n"],"names":[],"mappings":";;AAGA,eAAsB,eAAe,UAAkB;AACrD,QAAM,UAAU,cAAc,QAAQ,EAAE;AACxC,QAAM,SAAS,MAAM,SAAS,SAAS,IAAI;AAC3C,SAAO;AACT;"}
@@ -1,11 +1,13 @@
1
1
  import { TargetTemplate } from './template.js';
2
- import { RouteNode } from './types.js';
2
+ import { GetRoutesByFileMapResult } from './types.js';
3
3
  import { Config } from './config.js';
4
4
  interface fs {
5
5
  stat: (filePath: string) => Promise<{
6
6
  mtimeMs: bigint;
7
+ mode: number;
8
+ uid: number;
9
+ gid: number;
7
10
  }>;
8
- mkdtempSync: (prefix: string) => string;
9
11
  rename: (oldPath: string, newPath: string) => Promise<void>;
10
12
  writeFile: (filePath: string, content: string) => Promise<void>;
11
13
  readFile: (filePath: string) => Promise<{
@@ -14,6 +16,8 @@ interface fs {
14
16
  };
15
17
  fileContent: string;
16
18
  } | 'file-not-existing'>;
19
+ chmod: (filePath: string, mode: number) => Promise<void>;
20
+ chown: (filePath: string, uid: number, gid: number) => Promise<void>;
17
21
  }
18
22
  export type FileEventType = 'create' | 'update' | 'delete';
19
23
  export type FileEvent = {
@@ -41,7 +45,7 @@ export declare class Generator {
41
45
  targetTemplate: TargetTemplate;
42
46
  private root;
43
47
  private routesDirectoryPath;
44
- private tmpDir;
48
+ private sessionId?;
45
49
  private fs;
46
50
  private logger;
47
51
  private generatedRouteTreePath;
@@ -51,14 +55,17 @@ export declare class Generator {
51
55
  private pluginsWithTransform;
52
56
  private transformPlugins;
53
57
  private routeGroupPatternRegex;
58
+ private physicalDirectories;
54
59
  constructor(opts: {
55
60
  config: Config;
56
61
  root: string;
57
62
  fs?: fs;
58
63
  });
59
64
  private getRoutesDirectoryPath;
65
+ getRoutesByFileMap(): GetRoutesByFileMapResult;
60
66
  run(event?: GeneratorEvent): Promise<void>;
61
67
  private generatorInternal;
68
+ private swapCaches;
62
69
  private buildRouteTreeFileContent;
63
70
  private getImportPath;
64
71
  private processRouteNodeFile;
@@ -69,11 +76,6 @@ export declare class Generator {
69
76
  private isRouteFileCacheFresh;
70
77
  private handleRootNode;
71
78
  private handleNode;
79
+ private isFileRelevantForRouteTreeGeneration;
72
80
  }
73
- export declare function buildFileRoutesByPathInterface(opts: {
74
- routeNodes: Array<RouteNode>;
75
- module: string;
76
- interfaceName: string;
77
- exportName: string;
78
- }): string;
79
81
  export {};