@tanstack/router-generator 1.166.9 → 1.166.11

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 (58) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/cjs/config.cjs +111 -147
  3. package/dist/cjs/config.cjs.map +1 -1
  4. package/dist/cjs/filesystem/physical/getRouteNodes.cjs +224 -303
  5. package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
  6. package/dist/cjs/filesystem/physical/rootPathId.cjs +5 -4
  7. package/dist/cjs/filesystem/physical/rootPathId.cjs.map +1 -1
  8. package/dist/cjs/filesystem/virtual/config.cjs +32 -30
  9. package/dist/cjs/filesystem/virtual/config.cjs.map +1 -1
  10. package/dist/cjs/filesystem/virtual/getRouteNodes.cjs +164 -209
  11. package/dist/cjs/filesystem/virtual/getRouteNodes.cjs.map +1 -1
  12. package/dist/cjs/filesystem/virtual/loadConfigFile.cjs +9 -8
  13. package/dist/cjs/filesystem/virtual/loadConfigFile.cjs.map +1 -1
  14. package/dist/cjs/generator.cjs +766 -1106
  15. package/dist/cjs/generator.cjs.map +1 -1
  16. package/dist/cjs/index.cjs +32 -34
  17. package/dist/cjs/logger.cjs +28 -34
  18. package/dist/cjs/logger.cjs.map +1 -1
  19. package/dist/cjs/template.cjs +144 -151
  20. package/dist/cjs/template.cjs.map +1 -1
  21. package/dist/cjs/transform/transform.cjs +287 -426
  22. package/dist/cjs/transform/transform.cjs.map +1 -1
  23. package/dist/cjs/transform/utils.cjs +31 -33
  24. package/dist/cjs/transform/utils.cjs.map +1 -1
  25. package/dist/cjs/utils.cjs +534 -544
  26. package/dist/cjs/utils.cjs.map +1 -1
  27. package/dist/cjs/validate-route-params.cjs +66 -51
  28. package/dist/cjs/validate-route-params.cjs.map +1 -1
  29. package/dist/esm/config.js +106 -147
  30. package/dist/esm/config.js.map +1 -1
  31. package/dist/esm/filesystem/physical/getRouteNodes.js +220 -286
  32. package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
  33. package/dist/esm/filesystem/physical/rootPathId.js +6 -5
  34. package/dist/esm/filesystem/physical/rootPathId.js.map +1 -1
  35. package/dist/esm/filesystem/virtual/config.js +31 -30
  36. package/dist/esm/filesystem/virtual/config.js.map +1 -1
  37. package/dist/esm/filesystem/virtual/getRouteNodes.js +161 -208
  38. package/dist/esm/filesystem/virtual/getRouteNodes.js.map +1 -1
  39. package/dist/esm/filesystem/virtual/loadConfigFile.js +7 -7
  40. package/dist/esm/filesystem/virtual/loadConfigFile.js.map +1 -1
  41. package/dist/esm/generator.js +756 -1083
  42. package/dist/esm/generator.js.map +1 -1
  43. package/dist/esm/index.js +4 -31
  44. package/dist/esm/logger.js +29 -35
  45. package/dist/esm/logger.js.map +1 -1
  46. package/dist/esm/template.js +144 -152
  47. package/dist/esm/template.js.map +1 -1
  48. package/dist/esm/transform/transform.js +285 -425
  49. package/dist/esm/transform/transform.js.map +1 -1
  50. package/dist/esm/transform/utils.js +31 -33
  51. package/dist/esm/transform/utils.js.map +1 -1
  52. package/dist/esm/utils.js +529 -564
  53. package/dist/esm/utils.js.map +1 -1
  54. package/dist/esm/validate-route-params.js +67 -52
  55. package/dist/esm/validate-route-params.js.map +1 -1
  56. package/package.json +5 -5
  57. package/dist/cjs/index.cjs.map +0 -1
  58. package/dist/esm/index.js.map +0 -1
@@ -1,1141 +1,801 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const path = require("node:path");
4
- const fsp = require("node:fs/promises");
5
- const node_fs = require("node:fs");
6
- const crypto = require("node:crypto");
7
- const routerCore = require("@tanstack/router-core");
8
- const logger = require("./logger.cjs");
9
- const getRouteNodes$1 = require("./filesystem/physical/getRouteNodes.cjs");
10
- const getRouteNodes = require("./filesystem/virtual/getRouteNodes.cjs");
11
- const rootPathId = require("./filesystem/physical/rootPathId.cjs");
12
- const utils = require("./utils.cjs");
13
- const template = require("./template.cjs");
14
- const transform = require("./transform/transform.cjs");
15
- const validateRouteParams = require("./validate-route-params.cjs");
16
- function _interopNamespaceDefault(e) {
17
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
18
- if (e) {
19
- for (const k in e) {
20
- if (k !== "default") {
21
- const d = Object.getOwnPropertyDescriptor(e, k);
22
- Object.defineProperty(n, k, d.get ? d : {
23
- enumerable: true,
24
- get: () => e[k]
25
- });
26
- }
27
- }
28
- }
29
- n.default = e;
30
- return Object.freeze(n);
31
- }
32
- const fsp__namespace = /* @__PURE__ */ _interopNamespaceDefault(fsp);
33
- const DefaultFileSystem = {
34
- stat: async (filePath) => {
35
- const res = await fsp__namespace.stat(filePath, { bigint: true });
36
- return {
37
- mtimeMs: res.mtimeMs,
38
- mode: Number(res.mode),
39
- uid: Number(res.uid),
40
- gid: Number(res.gid)
41
- };
42
- },
43
- rename: (oldPath, newPath) => fsp__namespace.rename(oldPath, newPath),
44
- writeFile: (filePath, content) => fsp__namespace.writeFile(filePath, content),
45
- readFile: async (filePath) => {
46
- try {
47
- const fileHandle = await fsp__namespace.open(filePath, "r");
48
- const stat = await fileHandle.stat({ bigint: true });
49
- const fileContent = (await fileHandle.readFile()).toString();
50
- await fileHandle.close();
51
- return { stat, fileContent };
52
- } catch (e) {
53
- if ("code" in e) {
54
- if (e.code === "ENOENT") {
55
- return "file-not-existing";
56
- }
57
- }
58
- throw e;
59
- }
60
- },
61
- chmod: (filePath, mode) => fsp__namespace.chmod(filePath, mode),
62
- chown: (filePath, uid, gid) => fsp__namespace.chown(filePath, uid, gid)
1
+ const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
+ const require_logger = require("./logger.cjs");
3
+ const require_rootPathId = require("./filesystem/physical/rootPathId.cjs");
4
+ const require_utils = require("./utils.cjs");
5
+ const require_getRouteNodes = require("./filesystem/virtual/getRouteNodes.cjs");
6
+ const require_getRouteNodes$1 = require("./filesystem/physical/getRouteNodes.cjs");
7
+ const require_template = require("./template.cjs");
8
+ const require_transform = require("./transform/transform.cjs");
9
+ const require_validate_route_params = require("./validate-route-params.cjs");
10
+ let node_path = require("node:path");
11
+ node_path = require_runtime.__toESM(node_path);
12
+ let node_fs = require("node:fs");
13
+ let node_fs_promises = require("node:fs/promises");
14
+ node_fs_promises = require_runtime.__toESM(node_fs_promises);
15
+ let node_crypto = require("node:crypto");
16
+ node_crypto = require_runtime.__toESM(node_crypto);
17
+ let _tanstack_router_core = require("@tanstack/router-core");
18
+ //#region src/generator.ts
19
+ var DefaultFileSystem = {
20
+ stat: async (filePath) => {
21
+ const res = await node_fs_promises.stat(filePath, { bigint: true });
22
+ return {
23
+ mtimeMs: res.mtimeMs,
24
+ mode: Number(res.mode),
25
+ uid: Number(res.uid),
26
+ gid: Number(res.gid)
27
+ };
28
+ },
29
+ rename: (oldPath, newPath) => node_fs_promises.rename(oldPath, newPath),
30
+ writeFile: (filePath, content) => node_fs_promises.writeFile(filePath, content),
31
+ readFile: async (filePath) => {
32
+ try {
33
+ const fileHandle = await node_fs_promises.open(filePath, "r");
34
+ const stat = await fileHandle.stat({ bigint: true });
35
+ const fileContent = (await fileHandle.readFile()).toString();
36
+ await fileHandle.close();
37
+ return {
38
+ stat,
39
+ fileContent
40
+ };
41
+ } catch (e) {
42
+ if ("code" in e) {
43
+ if (e.code === "ENOENT") return "file-not-existing";
44
+ }
45
+ throw e;
46
+ }
47
+ },
48
+ chmod: (filePath, mode) => node_fs_promises.chmod(filePath, mode),
49
+ chown: (filePath, uid, gid) => node_fs_promises.chown(filePath, uid, gid)
63
50
  };
64
51
  function rerun(opts) {
65
- const { event, ...rest } = opts;
66
- return { rerun: true, event: event ?? { type: "rerun" }, ...rest };
52
+ const { event, ...rest } = opts;
53
+ return {
54
+ rerun: true,
55
+ event: event ?? { type: "rerun" },
56
+ ...rest
57
+ };
67
58
  }
68
59
  function isRerun(result) {
69
- return typeof result === "object" && result !== null && "rerun" in result && result.rerun === true;
60
+ return typeof result === "object" && result !== null && "rerun" in result && result.rerun === true;
70
61
  }
71
- const _Generator = class _Generator {
72
- constructor(opts) {
73
- this.routeNodeCache = /* @__PURE__ */ new Map();
74
- this.routeNodeShadowCache = /* @__PURE__ */ new Map();
75
- this.fileEventQueue = [];
76
- this.plugins = [];
77
- this.physicalDirectories = [];
78
- this.config = opts.config;
79
- this.logger = logger.logging({ disabled: this.config.disableLogging });
80
- this.root = opts.root;
81
- this.fs = opts.fs || DefaultFileSystem;
82
- this.generatedRouteTreePath = this.getGeneratedRouteTreePath();
83
- this.targetTemplate = template.getTargetTemplate(this.config);
84
- this.routesDirectoryPath = this.getRoutesDirectoryPath();
85
- this.plugins.push(...opts.config.plugins || []);
86
- this.indexTokenFilenameRegex = utils.createTokenRegex(this.config.indexToken, {
87
- type: "filename"
88
- });
89
- this.routeTokenFilenameRegex = utils.createTokenRegex(this.config.routeToken, {
90
- type: "filename"
91
- });
92
- this.indexTokenSegmentRegex = utils.createTokenRegex(this.config.indexToken, {
93
- type: "segment"
94
- });
95
- this.routeTokenSegmentRegex = utils.createTokenRegex(this.config.routeToken, {
96
- type: "segment"
97
- });
98
- for (const plugin of this.plugins) {
99
- plugin.init?.({ generator: this });
100
- }
101
- }
102
- getGeneratedRouteTreePath() {
103
- const generatedRouteTreePath = path.isAbsolute(
104
- this.config.generatedRouteTree
105
- ) ? this.config.generatedRouteTree : path.resolve(this.root, this.config.generatedRouteTree);
106
- const generatedRouteTreeDir = path.dirname(generatedRouteTreePath);
107
- if (!node_fs.existsSync(generatedRouteTreeDir)) {
108
- node_fs.mkdirSync(generatedRouteTreeDir, { recursive: true });
109
- }
110
- return generatedRouteTreePath;
111
- }
112
- getRoutesDirectoryPath() {
113
- return path.isAbsolute(this.config.routesDirectory) ? this.config.routesDirectory : path.resolve(this.root, this.config.routesDirectory);
114
- }
115
- getRoutesByFileMap() {
116
- return new Map(
117
- [...this.routeNodeCache.entries()].map(([filePath, cacheEntry]) => [
118
- filePath,
119
- { routePath: cacheEntry.routeId }
120
- ])
121
- );
122
- }
123
- async run(event) {
124
- if (event && event.type !== "rerun" && !this.isFileRelevantForRouteTreeGeneration(event.path)) {
125
- return;
126
- }
127
- this.fileEventQueue.push(event ?? { type: "rerun" });
128
- if (this.runPromise) {
129
- return this.runPromise;
130
- }
131
- this.runPromise = (async () => {
132
- do {
133
- const tempQueue = this.fileEventQueue;
134
- this.fileEventQueue = [];
135
- const remainingEvents = (await Promise.all(
136
- tempQueue.map(async (e) => {
137
- if (e.type === "update") {
138
- let cacheEntry;
139
- if (e.path === this.generatedRouteTreePath) {
140
- cacheEntry = this.routeTreeFileCache;
141
- } else {
142
- cacheEntry = this.routeNodeCache.get(e.path);
143
- }
144
- const change = await this.didFileChangeComparedToCache(
145
- { path: e.path },
146
- cacheEntry
147
- );
148
- if (change.result === false) {
149
- return null;
150
- }
151
- }
152
- return e;
153
- })
154
- )).filter((e) => e !== null);
155
- if (remainingEvents.length === 0) {
156
- break;
157
- }
158
- try {
159
- await this.generatorInternal();
160
- } catch (err) {
161
- const errArray = !Array.isArray(err) ? [err] : err;
162
- const recoverableErrors = errArray.filter((e) => isRerun(e));
163
- if (recoverableErrors.length === errArray.length) {
164
- this.fileEventQueue.push(...recoverableErrors.map((e) => e.event));
165
- recoverableErrors.forEach((e) => {
166
- if (e.msg) {
167
- this.logger.info(e.msg);
168
- }
169
- });
170
- } else {
171
- const unrecoverableErrors = errArray.filter((e) => !isRerun(e));
172
- this.runPromise = void 0;
173
- throw new Error(
174
- unrecoverableErrors.map((e) => e.message).join()
175
- );
176
- }
177
- }
178
- } while (this.fileEventQueue.length);
179
- this.runPromise = void 0;
180
- })();
181
- return this.runPromise;
182
- }
183
- async generatorInternal() {
184
- let writeRouteTreeFile = false;
185
- let getRouteNodesResult;
186
- if (this.config.virtualRouteConfig) {
187
- getRouteNodesResult = await getRouteNodes.getRouteNodes(this.config, this.root, {
188
- indexTokenSegmentRegex: this.indexTokenSegmentRegex,
189
- routeTokenSegmentRegex: this.routeTokenSegmentRegex
190
- });
191
- } else {
192
- getRouteNodesResult = await getRouteNodes$1.getRouteNodes(
193
- this.config,
194
- this.root,
195
- {
196
- indexTokenSegmentRegex: this.indexTokenSegmentRegex,
197
- routeTokenSegmentRegex: this.routeTokenSegmentRegex
198
- }
199
- );
200
- }
201
- const {
202
- rootRouteNode,
203
- routeNodes: beforeRouteNodes,
204
- physicalDirectories
205
- } = getRouteNodesResult;
206
- if (rootRouteNode === void 0) {
207
- let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`;
208
- if (!this.config.virtualRouteConfig) {
209
- errorMessage += `
210
- Make sure that you add a "${rootPathId.rootPathId}.${this.config.disableTypes ? "js" : "tsx"}" file to your routes directory.
211
- Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this.config.disableTypes ? "js" : "tsx"}"`;
212
- }
213
- throw new Error(errorMessage);
214
- }
215
- this.physicalDirectories = physicalDirectories;
216
- await this.handleRootNode(rootRouteNode);
217
- const preRouteNodes = utils.multiSortBy(beforeRouteNodes, [
218
- (d) => d.routePath === "/" ? -1 : 1,
219
- (d) => d.routePath?.split("/").length,
220
- (d) => d.filePath.match(this.indexTokenFilenameRegex) ? 1 : -1,
221
- (d) => d.filePath.match(_Generator.componentPieceRegex) ? 1 : -1,
222
- (d) => d.filePath.match(this.routeTokenFilenameRegex) ? -1 : 1,
223
- (d) => d.routePath?.endsWith("/") ? -1 : 1,
224
- (d) => d.routePath
225
- ]).filter((d) => {
226
- if (d.routePath === `/${rootPathId.rootPathId}`) {
227
- return [
228
- "component",
229
- "errorComponent",
230
- "notFoundComponent",
231
- "pendingComponent",
232
- "loader",
233
- "lazy"
234
- ].includes(d._fsRouteType);
235
- }
236
- return true;
237
- });
238
- const routeFileAllResult = await Promise.allSettled(
239
- preRouteNodes.filter((n) => !n.isVirtualParentRoute && !n.isVirtual).map((n) => this.processRouteNodeFile(n))
240
- );
241
- const rejections = routeFileAllResult.filter(
242
- (result) => result.status === "rejected"
243
- );
244
- if (rejections.length > 0) {
245
- throw rejections.map((e) => e.reason);
246
- }
247
- const routeFileResult = routeFileAllResult.flatMap((result) => {
248
- if (result.status === "fulfilled" && result.value !== null) {
249
- if (result.value.shouldWriteTree) {
250
- writeRouteTreeFile = true;
251
- }
252
- return result.value.node;
253
- }
254
- return [];
255
- });
256
- routeFileResult.forEach((r) => r.children = void 0);
257
- const acc = {
258
- routeTree: [],
259
- routeNodes: [],
260
- routePiecesByPath: {},
261
- routeNodesByPath: /* @__PURE__ */ new Map()
262
- };
263
- const prefixMap = new utils.RoutePrefixMap(routeFileResult);
264
- for (const node of routeFileResult) {
265
- _Generator.handleNode(node, acc, prefixMap, this.config);
266
- }
267
- this.crawlingResult = { rootRouteNode, routeFileResult, acc };
268
- if (!this.routeTreeFileCache) {
269
- const routeTreeFile = await this.fs.readFile(this.generatedRouteTreePath);
270
- if (routeTreeFile !== "file-not-existing") {
271
- this.routeTreeFileCache = {
272
- fileContent: routeTreeFile.fileContent,
273
- mtimeMs: routeTreeFile.stat.mtimeMs
274
- };
275
- }
276
- writeRouteTreeFile = true;
277
- } else {
278
- const routeTreeFileChange = await this.didFileChangeComparedToCache(
279
- { path: this.generatedRouteTreePath },
280
- this.routeTreeFileCache
281
- );
282
- if (routeTreeFileChange.result !== false) {
283
- writeRouteTreeFile = "force";
284
- if (routeTreeFileChange.result === true) {
285
- const routeTreeFile = await this.fs.readFile(
286
- this.generatedRouteTreePath
287
- );
288
- if (routeTreeFile !== "file-not-existing") {
289
- this.routeTreeFileCache = {
290
- fileContent: routeTreeFile.fileContent,
291
- mtimeMs: routeTreeFile.stat.mtimeMs
292
- };
293
- }
294
- }
295
- }
296
- }
297
- if (!writeRouteTreeFile) {
298
- if (this.routeNodeCache.size !== this.routeNodeShadowCache.size) {
299
- writeRouteTreeFile = true;
300
- } else {
301
- for (const fullPath of this.routeNodeCache.keys()) {
302
- if (!this.routeNodeShadowCache.has(fullPath)) {
303
- writeRouteTreeFile = true;
304
- break;
305
- }
306
- }
307
- }
308
- }
309
- if (!writeRouteTreeFile) {
310
- this.swapCaches();
311
- return;
312
- }
313
- const buildResult = this.buildRouteTree({
314
- rootRouteNode,
315
- acc,
316
- routeFileResult
317
- });
318
- let routeTreeContent = buildResult.routeTreeContent;
319
- routeTreeContent = this.config.enableRouteTreeFormatting ? await utils.format(routeTreeContent, this.config) : routeTreeContent;
320
- let newMtimeMs;
321
- if (this.routeTreeFileCache) {
322
- if (writeRouteTreeFile !== "force" && this.routeTreeFileCache.fileContent === routeTreeContent) ;
323
- else {
324
- const newRouteTreeFileStat = await this.safeFileWrite({
325
- filePath: this.generatedRouteTreePath,
326
- newContent: routeTreeContent,
327
- strategy: {
328
- type: "mtime",
329
- expectedMtimeMs: this.routeTreeFileCache.mtimeMs
330
- }
331
- });
332
- newMtimeMs = newRouteTreeFileStat.mtimeMs;
333
- }
334
- } else {
335
- const newRouteTreeFileStat = await this.safeFileWrite({
336
- filePath: this.generatedRouteTreePath,
337
- newContent: routeTreeContent,
338
- strategy: {
339
- type: "new-file"
340
- }
341
- });
342
- newMtimeMs = newRouteTreeFileStat.mtimeMs;
343
- }
344
- if (newMtimeMs !== void 0) {
345
- this.routeTreeFileCache = {
346
- fileContent: routeTreeContent,
347
- mtimeMs: newMtimeMs
348
- };
349
- }
350
- this.plugins.map((plugin) => {
351
- return plugin.onRouteTreeChanged?.({
352
- routeTree: buildResult.routeTree,
353
- routeNodes: buildResult.routeNodes,
354
- acc,
355
- rootRouteNode
356
- });
357
- });
358
- this.swapCaches();
359
- }
360
- swapCaches() {
361
- this.routeNodeCache = this.routeNodeShadowCache;
362
- this.routeNodeShadowCache = /* @__PURE__ */ new Map();
363
- }
364
- buildRouteTree(opts) {
365
- const config = { ...this.config, ...opts.config || {} };
366
- const { rootRouteNode, acc } = opts;
367
- const indexTokenSegmentRegex = config.indexToken === this.config.indexToken ? this.indexTokenSegmentRegex : utils.createTokenRegex(config.indexToken, { type: "segment" });
368
- const sortedRouteNodes = utils.multiSortBy(acc.routeNodes, [
369
- (d) => d.routePath?.includes(`/${rootPathId.rootPathId}`) ? -1 : 1,
370
- (d) => d.routePath?.split("/").length,
371
- (d) => {
372
- const segments = d.routePath?.split("/").filter(Boolean) ?? [];
373
- const last = segments[segments.length - 1] ?? "";
374
- return indexTokenSegmentRegex.test(last) ? -1 : 1;
375
- },
376
- (d) => d
377
- ]);
378
- const routeImports = [];
379
- const virtualRouteNodes = [];
380
- for (const node of sortedRouteNodes) {
381
- if (node.isVirtual) {
382
- virtualRouteNodes.push(
383
- `const ${node.variableName}RouteImport = createFileRoute('${node.routePath}')()`
384
- );
385
- } else {
386
- routeImports.push(
387
- utils.getImportForRouteNode(
388
- node,
389
- config,
390
- this.generatedRouteTreePath,
391
- this.root
392
- )
393
- );
394
- }
395
- }
396
- const imports = [];
397
- if (virtualRouteNodes.length > 0) {
398
- imports.push({
399
- specifiers: [{ imported: "createFileRoute" }],
400
- source: this.targetTemplate.fullPkg
401
- });
402
- }
403
- let hasComponentPieces = false;
404
- let hasLoaderPieces = false;
405
- for (const node of sortedRouteNodes) {
406
- const pieces = acc.routePiecesByPath[node.routePath];
407
- if (pieces) {
408
- if (pieces.component || pieces.errorComponent || pieces.notFoundComponent || pieces.pendingComponent) {
409
- hasComponentPieces = true;
410
- }
411
- if (pieces.loader) {
412
- hasLoaderPieces = true;
413
- }
414
- if (hasComponentPieces && hasLoaderPieces) break;
415
- }
416
- }
417
- if (hasComponentPieces || hasLoaderPieces) {
418
- const runtimeImport = {
419
- specifiers: [],
420
- source: this.targetTemplate.fullPkg
421
- };
422
- if (hasComponentPieces) {
423
- runtimeImport.specifiers.push({ imported: "lazyRouteComponent" });
424
- }
425
- if (hasLoaderPieces) {
426
- runtimeImport.specifiers.push({ imported: "lazyFn" });
427
- }
428
- imports.push(runtimeImport);
429
- }
430
- if (config.verboseFileRoutes === false) {
431
- const typeImport = {
432
- specifiers: [],
433
- source: this.targetTemplate.fullPkg,
434
- importKind: "type"
435
- };
436
- let needsCreateFileRoute = false;
437
- let needsCreateLazyFileRoute = false;
438
- for (const node of sortedRouteNodes) {
439
- if (utils.isRouteNodeValidForAugmentation(node)) {
440
- if (node._fsRouteType !== "lazy") {
441
- needsCreateFileRoute = true;
442
- }
443
- if (acc.routePiecesByPath[node.routePath]?.lazy) {
444
- needsCreateLazyFileRoute = true;
445
- }
446
- }
447
- if (needsCreateFileRoute && needsCreateLazyFileRoute) break;
448
- }
449
- if (needsCreateFileRoute) {
450
- typeImport.specifiers.push({ imported: "CreateFileRoute" });
451
- }
452
- if (needsCreateLazyFileRoute) {
453
- typeImport.specifiers.push({ imported: "CreateLazyFileRoute" });
454
- }
455
- if (typeImport.specifiers.length > 0) {
456
- typeImport.specifiers.push({ imported: "FileRoutesByPath" });
457
- imports.push(typeImport);
458
- }
459
- }
460
- const routeTreeConfig = utils.buildRouteTreeConfig(
461
- acc.routeTree,
462
- config.disableTypes
463
- );
464
- const createUpdateRoutes = sortedRouteNodes.map((node) => {
465
- const pieces = acc.routePiecesByPath[node.routePath];
466
- const loaderNode = pieces?.loader;
467
- const componentNode = pieces?.component;
468
- const errorComponentNode = pieces?.errorComponent;
469
- const notFoundComponentNode = pieces?.notFoundComponent;
470
- const pendingComponentNode = pieces?.pendingComponent;
471
- const lazyComponentNode = pieces?.lazy;
472
- return [
473
- [
474
- `const ${node.variableName}Route = ${node.variableName}RouteImport.update({
62
+ var Generator = class Generator {
63
+ static {
64
+ this.routeGroupPatternRegex = /\(.+\)/;
65
+ }
66
+ static {
67
+ this.componentPieceRegex = /[./](component|errorComponent|notFoundComponent|pendingComponent|loader|lazy)[.]/;
68
+ }
69
+ constructor(opts) {
70
+ this.routeNodeCache = /* @__PURE__ */ new Map();
71
+ this.routeNodeShadowCache = /* @__PURE__ */ new Map();
72
+ this.fileEventQueue = [];
73
+ this.plugins = [];
74
+ this.physicalDirectories = [];
75
+ this.config = opts.config;
76
+ this.logger = require_logger.logging({ disabled: this.config.disableLogging });
77
+ this.root = opts.root;
78
+ this.fs = opts.fs || DefaultFileSystem;
79
+ this.generatedRouteTreePath = this.getGeneratedRouteTreePath();
80
+ this.targetTemplate = require_template.getTargetTemplate(this.config);
81
+ this.routesDirectoryPath = this.getRoutesDirectoryPath();
82
+ this.plugins.push(...opts.config.plugins || []);
83
+ this.indexTokenFilenameRegex = require_utils.createTokenRegex(this.config.indexToken, { type: "filename" });
84
+ this.routeTokenFilenameRegex = require_utils.createTokenRegex(this.config.routeToken, { type: "filename" });
85
+ this.indexTokenSegmentRegex = require_utils.createTokenRegex(this.config.indexToken, { type: "segment" });
86
+ this.routeTokenSegmentRegex = require_utils.createTokenRegex(this.config.routeToken, { type: "segment" });
87
+ for (const plugin of this.plugins) plugin.init?.({ generator: this });
88
+ }
89
+ getGeneratedRouteTreePath() {
90
+ const generatedRouteTreePath = node_path.default.isAbsolute(this.config.generatedRouteTree) ? this.config.generatedRouteTree : node_path.default.resolve(this.root, this.config.generatedRouteTree);
91
+ const generatedRouteTreeDir = node_path.default.dirname(generatedRouteTreePath);
92
+ if (!(0, node_fs.existsSync)(generatedRouteTreeDir)) (0, node_fs.mkdirSync)(generatedRouteTreeDir, { recursive: true });
93
+ return generatedRouteTreePath;
94
+ }
95
+ getRoutesDirectoryPath() {
96
+ return node_path.default.isAbsolute(this.config.routesDirectory) ? this.config.routesDirectory : node_path.default.resolve(this.root, this.config.routesDirectory);
97
+ }
98
+ getRoutesByFileMap() {
99
+ return new Map([...this.routeNodeCache.entries()].map(([filePath, cacheEntry]) => [filePath, { routePath: cacheEntry.routeId }]));
100
+ }
101
+ async run(event) {
102
+ if (event && event.type !== "rerun" && !this.isFileRelevantForRouteTreeGeneration(event.path)) return;
103
+ this.fileEventQueue.push(event ?? { type: "rerun" });
104
+ if (this.runPromise) return this.runPromise;
105
+ this.runPromise = (async () => {
106
+ do {
107
+ const tempQueue = this.fileEventQueue;
108
+ this.fileEventQueue = [];
109
+ if ((await Promise.all(tempQueue.map(async (e) => {
110
+ if (e.type === "update") {
111
+ let cacheEntry;
112
+ if (e.path === this.generatedRouteTreePath) cacheEntry = this.routeTreeFileCache;
113
+ else cacheEntry = this.routeNodeCache.get(e.path);
114
+ if ((await this.didFileChangeComparedToCache({ path: e.path }, cacheEntry)).result === false) return null;
115
+ }
116
+ return e;
117
+ }))).filter((e) => e !== null).length === 0) break;
118
+ try {
119
+ await this.generatorInternal();
120
+ } catch (err) {
121
+ const errArray = !Array.isArray(err) ? [err] : err;
122
+ const recoverableErrors = errArray.filter((e) => isRerun(e));
123
+ if (recoverableErrors.length === errArray.length) {
124
+ this.fileEventQueue.push(...recoverableErrors.map((e) => e.event));
125
+ recoverableErrors.forEach((e) => {
126
+ if (e.msg) this.logger.info(e.msg);
127
+ });
128
+ } else {
129
+ const unrecoverableErrors = errArray.filter((e) => !isRerun(e));
130
+ this.runPromise = void 0;
131
+ throw new Error(unrecoverableErrors.map((e) => e.message).join());
132
+ }
133
+ }
134
+ } while (this.fileEventQueue.length);
135
+ this.runPromise = void 0;
136
+ })();
137
+ return this.runPromise;
138
+ }
139
+ async generatorInternal() {
140
+ let writeRouteTreeFile = false;
141
+ let getRouteNodesResult;
142
+ if (this.config.virtualRouteConfig) getRouteNodesResult = await require_getRouteNodes.getRouteNodes(this.config, this.root, {
143
+ indexTokenSegmentRegex: this.indexTokenSegmentRegex,
144
+ routeTokenSegmentRegex: this.routeTokenSegmentRegex
145
+ });
146
+ else getRouteNodesResult = await require_getRouteNodes$1.getRouteNodes(this.config, this.root, {
147
+ indexTokenSegmentRegex: this.indexTokenSegmentRegex,
148
+ routeTokenSegmentRegex: this.routeTokenSegmentRegex
149
+ });
150
+ const { rootRouteNode, routeNodes: beforeRouteNodes, physicalDirectories } = getRouteNodesResult;
151
+ if (rootRouteNode === void 0) {
152
+ let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`;
153
+ if (!this.config.virtualRouteConfig) errorMessage += `\nMake sure that you add a "${require_rootPathId.rootPathId}.${this.config.disableTypes ? "js" : "tsx"}" file to your routes directory.\nAdd the file in: "${this.config.routesDirectory}/${require_rootPathId.rootPathId}.${this.config.disableTypes ? "js" : "tsx"}"`;
154
+ throw new Error(errorMessage);
155
+ }
156
+ this.physicalDirectories = physicalDirectories;
157
+ await this.handleRootNode(rootRouteNode);
158
+ const preRouteNodes = require_utils.multiSortBy(beforeRouteNodes, [
159
+ (d) => d.routePath === "/" ? -1 : 1,
160
+ (d) => d.routePath?.split("/").length,
161
+ (d) => d.filePath.match(this.indexTokenFilenameRegex) ? 1 : -1,
162
+ (d) => d.filePath.match(Generator.componentPieceRegex) ? 1 : -1,
163
+ (d) => d.filePath.match(this.routeTokenFilenameRegex) ? -1 : 1,
164
+ (d) => d.routePath?.endsWith("/") ? -1 : 1,
165
+ (d) => d.routePath
166
+ ]).filter((d) => {
167
+ if (d.routePath === `/__root`) return [
168
+ "component",
169
+ "errorComponent",
170
+ "notFoundComponent",
171
+ "pendingComponent",
172
+ "loader",
173
+ "lazy"
174
+ ].includes(d._fsRouteType);
175
+ return true;
176
+ });
177
+ const routeFileAllResult = await Promise.allSettled(preRouteNodes.filter((n) => !n.isVirtualParentRoute && !n.isVirtual).map((n) => this.processRouteNodeFile(n)));
178
+ const rejections = routeFileAllResult.filter((result) => result.status === "rejected");
179
+ if (rejections.length > 0) throw rejections.map((e) => e.reason);
180
+ const routeFileResult = routeFileAllResult.flatMap((result) => {
181
+ if (result.status === "fulfilled" && result.value !== null) {
182
+ if (result.value.shouldWriteTree) writeRouteTreeFile = true;
183
+ return result.value.node;
184
+ }
185
+ return [];
186
+ });
187
+ routeFileResult.forEach((r) => r.children = void 0);
188
+ const acc = {
189
+ routeTree: [],
190
+ routeNodes: [],
191
+ routePiecesByPath: {},
192
+ routeNodesByPath: /* @__PURE__ */ new Map()
193
+ };
194
+ const prefixMap = new require_utils.RoutePrefixMap(routeFileResult);
195
+ for (const node of routeFileResult) Generator.handleNode(node, acc, prefixMap, this.config);
196
+ this.crawlingResult = {
197
+ rootRouteNode,
198
+ routeFileResult,
199
+ acc
200
+ };
201
+ if (!this.routeTreeFileCache) {
202
+ const routeTreeFile = await this.fs.readFile(this.generatedRouteTreePath);
203
+ if (routeTreeFile !== "file-not-existing") this.routeTreeFileCache = {
204
+ fileContent: routeTreeFile.fileContent,
205
+ mtimeMs: routeTreeFile.stat.mtimeMs
206
+ };
207
+ writeRouteTreeFile = true;
208
+ } else {
209
+ const routeTreeFileChange = await this.didFileChangeComparedToCache({ path: this.generatedRouteTreePath }, this.routeTreeFileCache);
210
+ if (routeTreeFileChange.result !== false) {
211
+ writeRouteTreeFile = "force";
212
+ if (routeTreeFileChange.result === true) {
213
+ const routeTreeFile = await this.fs.readFile(this.generatedRouteTreePath);
214
+ if (routeTreeFile !== "file-not-existing") this.routeTreeFileCache = {
215
+ fileContent: routeTreeFile.fileContent,
216
+ mtimeMs: routeTreeFile.stat.mtimeMs
217
+ };
218
+ }
219
+ }
220
+ }
221
+ if (!writeRouteTreeFile) {
222
+ if (this.routeNodeCache.size !== this.routeNodeShadowCache.size) writeRouteTreeFile = true;
223
+ else for (const fullPath of this.routeNodeCache.keys()) if (!this.routeNodeShadowCache.has(fullPath)) {
224
+ writeRouteTreeFile = true;
225
+ break;
226
+ }
227
+ }
228
+ if (!writeRouteTreeFile) {
229
+ this.swapCaches();
230
+ return;
231
+ }
232
+ const buildResult = this.buildRouteTree({
233
+ rootRouteNode,
234
+ acc,
235
+ routeFileResult
236
+ });
237
+ let routeTreeContent = buildResult.routeTreeContent;
238
+ routeTreeContent = this.config.enableRouteTreeFormatting ? await require_utils.format(routeTreeContent, this.config) : routeTreeContent;
239
+ let newMtimeMs;
240
+ if (this.routeTreeFileCache) if (writeRouteTreeFile !== "force" && this.routeTreeFileCache.fileContent === routeTreeContent) {} else newMtimeMs = (await this.safeFileWrite({
241
+ filePath: this.generatedRouteTreePath,
242
+ newContent: routeTreeContent,
243
+ strategy: {
244
+ type: "mtime",
245
+ expectedMtimeMs: this.routeTreeFileCache.mtimeMs
246
+ }
247
+ })).mtimeMs;
248
+ else newMtimeMs = (await this.safeFileWrite({
249
+ filePath: this.generatedRouteTreePath,
250
+ newContent: routeTreeContent,
251
+ strategy: { type: "new-file" }
252
+ })).mtimeMs;
253
+ if (newMtimeMs !== void 0) this.routeTreeFileCache = {
254
+ fileContent: routeTreeContent,
255
+ mtimeMs: newMtimeMs
256
+ };
257
+ this.plugins.map((plugin) => {
258
+ return plugin.onRouteTreeChanged?.({
259
+ routeTree: buildResult.routeTree,
260
+ routeNodes: buildResult.routeNodes,
261
+ acc,
262
+ rootRouteNode
263
+ });
264
+ });
265
+ this.swapCaches();
266
+ }
267
+ swapCaches() {
268
+ this.routeNodeCache = this.routeNodeShadowCache;
269
+ this.routeNodeShadowCache = /* @__PURE__ */ new Map();
270
+ }
271
+ buildRouteTree(opts) {
272
+ const config = {
273
+ ...this.config,
274
+ ...opts.config || {}
275
+ };
276
+ const { rootRouteNode, acc } = opts;
277
+ const indexTokenSegmentRegex = config.indexToken === this.config.indexToken ? this.indexTokenSegmentRegex : require_utils.createTokenRegex(config.indexToken, { type: "segment" });
278
+ const sortedRouteNodes = require_utils.multiSortBy(acc.routeNodes, [
279
+ (d) => d.routePath?.includes(`/__root`) ? -1 : 1,
280
+ (d) => d.routePath?.split("/").length,
281
+ (d) => {
282
+ const segments = d.routePath?.split("/").filter(Boolean) ?? [];
283
+ const last = segments[segments.length - 1] ?? "";
284
+ return indexTokenSegmentRegex.test(last) ? -1 : 1;
285
+ },
286
+ (d) => d
287
+ ]);
288
+ const routeImports = [];
289
+ const virtualRouteNodes = [];
290
+ for (const node of sortedRouteNodes) if (node.isVirtual) virtualRouteNodes.push(`const ${node.variableName}RouteImport = createFileRoute('${node.routePath}')()`);
291
+ else routeImports.push(require_utils.getImportForRouteNode(node, config, this.generatedRouteTreePath, this.root));
292
+ const imports = [];
293
+ if (virtualRouteNodes.length > 0) imports.push({
294
+ specifiers: [{ imported: "createFileRoute" }],
295
+ source: this.targetTemplate.fullPkg
296
+ });
297
+ let hasComponentPieces = false;
298
+ let hasLoaderPieces = false;
299
+ for (const node of sortedRouteNodes) {
300
+ const pieces = acc.routePiecesByPath[node.routePath];
301
+ if (pieces) {
302
+ if (pieces.component || pieces.errorComponent || pieces.notFoundComponent || pieces.pendingComponent) hasComponentPieces = true;
303
+ if (pieces.loader) hasLoaderPieces = true;
304
+ if (hasComponentPieces && hasLoaderPieces) break;
305
+ }
306
+ }
307
+ if (hasComponentPieces || hasLoaderPieces) {
308
+ const runtimeImport = {
309
+ specifiers: [],
310
+ source: this.targetTemplate.fullPkg
311
+ };
312
+ if (hasComponentPieces) runtimeImport.specifiers.push({ imported: "lazyRouteComponent" });
313
+ if (hasLoaderPieces) runtimeImport.specifiers.push({ imported: "lazyFn" });
314
+ imports.push(runtimeImport);
315
+ }
316
+ if (config.verboseFileRoutes === false) {
317
+ const typeImport = {
318
+ specifiers: [],
319
+ source: this.targetTemplate.fullPkg,
320
+ importKind: "type"
321
+ };
322
+ let needsCreateFileRoute = false;
323
+ let needsCreateLazyFileRoute = false;
324
+ for (const node of sortedRouteNodes) {
325
+ if (require_utils.isRouteNodeValidForAugmentation(node)) {
326
+ if (node._fsRouteType !== "lazy") needsCreateFileRoute = true;
327
+ if (acc.routePiecesByPath[node.routePath]?.lazy) needsCreateLazyFileRoute = true;
328
+ }
329
+ if (needsCreateFileRoute && needsCreateLazyFileRoute) break;
330
+ }
331
+ if (needsCreateFileRoute) typeImport.specifiers.push({ imported: "CreateFileRoute" });
332
+ if (needsCreateLazyFileRoute) typeImport.specifiers.push({ imported: "CreateLazyFileRoute" });
333
+ if (typeImport.specifiers.length > 0) {
334
+ typeImport.specifiers.push({ imported: "FileRoutesByPath" });
335
+ imports.push(typeImport);
336
+ }
337
+ }
338
+ const routeTreeConfig = require_utils.buildRouteTreeConfig(acc.routeTree, config.disableTypes);
339
+ const createUpdateRoutes = sortedRouteNodes.map((node) => {
340
+ const pieces = acc.routePiecesByPath[node.routePath];
341
+ const loaderNode = pieces?.loader;
342
+ const componentNode = pieces?.component;
343
+ const errorComponentNode = pieces?.errorComponent;
344
+ const notFoundComponentNode = pieces?.notFoundComponent;
345
+ const pendingComponentNode = pieces?.pendingComponent;
346
+ const lazyComponentNode = pieces?.lazy;
347
+ return [[
348
+ `const ${node.variableName}Route = ${node.variableName}RouteImport.update({
475
349
  ${[
476
- `id: '${node.path}'`,
477
- !node.isNonPath || node._fsRouteType === "pathless_layout" && node.cleanedPath ? `path: '${node.cleanedPath}'` : void 0,
478
- `getParentRoute: () => ${utils.findParent(node)}`
479
- ].filter(Boolean).join(",")}
350
+ `id: '${node.path}'`,
351
+ !node.isNonPath || node._fsRouteType === "pathless_layout" && node.cleanedPath ? `path: '${node.cleanedPath}'` : void 0,
352
+ `getParentRoute: () => ${require_utils.findParent(node)}`
353
+ ].filter(Boolean).join(",")}
480
354
  }${config.disableTypes ? "" : "as any"})`,
481
- loaderNode ? `.updateLoader({ loader: lazyFn(() => import('./${utils.replaceBackslash(
482
- utils.removeExt(
483
- path.relative(
484
- path.dirname(config.generatedRouteTree),
485
- path.resolve(config.routesDirectory, loaderNode.filePath)
486
- ),
487
- config.addExtensions
488
- )
489
- )}'), 'loader') })` : "",
490
- componentNode || errorComponentNode || notFoundComponentNode || pendingComponentNode ? `.update({
355
+ loaderNode ? `.updateLoader({ loader: lazyFn(() => import('./${require_utils.replaceBackslash(require_utils.removeExt(node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, loaderNode.filePath)), config.addExtensions))}'), 'loader') })` : "",
356
+ componentNode || errorComponentNode || notFoundComponentNode || pendingComponentNode ? `.update({
491
357
  ${[
492
- ["component", componentNode],
493
- ["errorComponent", errorComponentNode],
494
- ["notFoundComponent", notFoundComponentNode],
495
- ["pendingComponent", pendingComponentNode]
496
- ].filter((d) => d[1]).map((d) => {
497
- const isVueFile = d[1].filePath.endsWith(".vue");
498
- const exportName = isVueFile ? "default" : d[0];
499
- const importPath = utils.replaceBackslash(
500
- isVueFile ? path.relative(
501
- path.dirname(config.generatedRouteTree),
502
- path.resolve(
503
- config.routesDirectory,
504
- d[1].filePath
505
- )
506
- ) : utils.removeExt(
507
- path.relative(
508
- path.dirname(config.generatedRouteTree),
509
- path.resolve(
510
- config.routesDirectory,
511
- d[1].filePath
512
- )
513
- ),
514
- config.addExtensions
515
- )
516
- );
517
- return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`;
518
- }).join("\n,")}
358
+ ["component", componentNode],
359
+ ["errorComponent", errorComponentNode],
360
+ ["notFoundComponent", notFoundComponentNode],
361
+ ["pendingComponent", pendingComponentNode]
362
+ ].filter((d) => d[1]).map((d) => {
363
+ const isVueFile = d[1].filePath.endsWith(".vue");
364
+ const exportName = isVueFile ? "default" : d[0];
365
+ const importPath = require_utils.replaceBackslash(isVueFile ? node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, d[1].filePath)) : require_utils.removeExt(node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, d[1].filePath)), config.addExtensions));
366
+ return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`;
367
+ }).join("\n,")}
519
368
  })` : "",
520
- lazyComponentNode ? (() => {
521
- const isVueFile = lazyComponentNode.filePath.endsWith(".vue");
522
- const exportAccessor = isVueFile ? "d.default" : "d.Route";
523
- const importPath = utils.replaceBackslash(
524
- isVueFile ? path.relative(
525
- path.dirname(config.generatedRouteTree),
526
- path.resolve(
527
- config.routesDirectory,
528
- lazyComponentNode.filePath
529
- )
530
- ) : utils.removeExt(
531
- path.relative(
532
- path.dirname(config.generatedRouteTree),
533
- path.resolve(
534
- config.routesDirectory,
535
- lazyComponentNode.filePath
536
- )
537
- ),
538
- config.addExtensions
539
- )
540
- );
541
- return `.lazy(() => import('./${importPath}').then((d) => ${exportAccessor}))`;
542
- })() : ""
543
- ].join("")
544
- ].join("\n\n");
545
- });
546
- const rootRoutePath = `/${rootPathId.rootPathId}`;
547
- const rootPieces = acc.routePiecesByPath[rootRoutePath];
548
- const rootComponentNode = rootPieces?.component;
549
- const rootErrorComponentNode = rootPieces?.errorComponent;
550
- const rootNotFoundComponentNode = rootPieces?.notFoundComponent;
551
- const rootPendingComponentNode = rootPieces?.pendingComponent;
552
- let rootRouteUpdate = "";
553
- if (rootComponentNode || rootErrorComponentNode || rootNotFoundComponentNode || rootPendingComponentNode) {
554
- rootRouteUpdate = `const rootRouteWithChildren = rootRouteImport${rootComponentNode || rootErrorComponentNode || rootNotFoundComponentNode || rootPendingComponentNode ? `.update({
369
+ lazyComponentNode ? (() => {
370
+ const isVueFile = lazyComponentNode.filePath.endsWith(".vue");
371
+ const exportAccessor = isVueFile ? "d.default" : "d.Route";
372
+ return `.lazy(() => import('./${require_utils.replaceBackslash(isVueFile ? node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, lazyComponentNode.filePath)) : require_utils.removeExt(node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, lazyComponentNode.filePath)), config.addExtensions))}').then((d) => ${exportAccessor}))`;
373
+ })() : ""
374
+ ].join("")].join("\n\n");
375
+ });
376
+ const rootRoutePath = `/${require_rootPathId.rootPathId}`;
377
+ const rootPieces = acc.routePiecesByPath[rootRoutePath];
378
+ const rootComponentNode = rootPieces?.component;
379
+ const rootErrorComponentNode = rootPieces?.errorComponent;
380
+ const rootNotFoundComponentNode = rootPieces?.notFoundComponent;
381
+ const rootPendingComponentNode = rootPieces?.pendingComponent;
382
+ let rootRouteUpdate = "";
383
+ if (rootComponentNode || rootErrorComponentNode || rootNotFoundComponentNode || rootPendingComponentNode) rootRouteUpdate = `const rootRouteWithChildren = rootRouteImport${rootComponentNode || rootErrorComponentNode || rootNotFoundComponentNode || rootPendingComponentNode ? `.update({
555
384
  ${[
556
- ["component", rootComponentNode],
557
- ["errorComponent", rootErrorComponentNode],
558
- ["notFoundComponent", rootNotFoundComponentNode],
559
- ["pendingComponent", rootPendingComponentNode]
560
- ].filter((d) => d[1]).map((d) => {
561
- const isVueFile = d[1].filePath.endsWith(".vue");
562
- const exportName = isVueFile ? "default" : d[0];
563
- const importPath = utils.replaceBackslash(
564
- isVueFile ? path.relative(
565
- path.dirname(config.generatedRouteTree),
566
- path.resolve(config.routesDirectory, d[1].filePath)
567
- ) : utils.removeExt(
568
- path.relative(
569
- path.dirname(config.generatedRouteTree),
570
- path.resolve(
571
- config.routesDirectory,
572
- d[1].filePath
573
- )
574
- ),
575
- config.addExtensions
576
- )
577
- );
578
- return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`;
579
- }).join("\n,")}
385
+ ["component", rootComponentNode],
386
+ ["errorComponent", rootErrorComponentNode],
387
+ ["notFoundComponent", rootNotFoundComponentNode],
388
+ ["pendingComponent", rootPendingComponentNode]
389
+ ].filter((d) => d[1]).map((d) => {
390
+ const isVueFile = d[1].filePath.endsWith(".vue");
391
+ const exportName = isVueFile ? "default" : d[0];
392
+ const importPath = require_utils.replaceBackslash(isVueFile ? node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, d[1].filePath)) : require_utils.removeExt(node_path.default.relative(node_path.default.dirname(config.generatedRouteTree), node_path.default.resolve(config.routesDirectory, d[1].filePath)), config.addExtensions));
393
+ return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`;
394
+ }).join("\n,")}
580
395
  })` : ""}._addFileChildren(rootRouteChildren)${config.disableTypes ? "" : `._addFileTypes<FileRouteTypes>()`}`;
581
- }
582
- let fileRoutesByPathInterface = "";
583
- let fileRoutesByFullPath = "";
584
- if (!config.disableTypes) {
585
- const routeNodesByFullPath = utils.createRouteNodesByFullPath(acc.routeNodes);
586
- const routeNodesByTo = utils.createRouteNodesByTo(acc.routeNodes);
587
- const routeNodesById = utils.createRouteNodesById(acc.routeNodes);
588
- fileRoutesByFullPath = [
589
- `export interface FileRoutesByFullPath {
396
+ let fileRoutesByPathInterface = "";
397
+ let fileRoutesByFullPath = "";
398
+ if (!config.disableTypes) {
399
+ const routeNodesByFullPath = require_utils.createRouteNodesByFullPath(acc.routeNodes);
400
+ const routeNodesByTo = require_utils.createRouteNodesByTo(acc.routeNodes);
401
+ const routeNodesById = require_utils.createRouteNodesById(acc.routeNodes);
402
+ fileRoutesByFullPath = [
403
+ `export interface FileRoutesByFullPath {
590
404
  ${[...routeNodesByFullPath.entries()].filter(([fullPath]) => fullPath).map(([fullPath, routeNode]) => {
591
- return `'${fullPath}': typeof ${utils.getResolvedRouteNodeVariableName(routeNode)}`;
592
- })}
405
+ return `'${fullPath}': typeof ${require_utils.getResolvedRouteNodeVariableName(routeNode)}`;
406
+ })}
593
407
  }`,
594
- `export interface FileRoutesByTo {
408
+ `export interface FileRoutesByTo {
595
409
  ${[...routeNodesByTo.entries()].filter(([to]) => to).map(([to, routeNode]) => {
596
- return `'${to}': typeof ${utils.getResolvedRouteNodeVariableName(routeNode)}`;
597
- })}
410
+ return `'${to}': typeof ${require_utils.getResolvedRouteNodeVariableName(routeNode)}`;
411
+ })}
598
412
  }`,
599
- `export interface FileRoutesById {
600
- '${routerCore.rootRouteId}': typeof rootRouteImport,
413
+ `export interface FileRoutesById {
414
+ '${_tanstack_router_core.rootRouteId}': typeof rootRouteImport,
601
415
  ${[...routeNodesById.entries()].map(([id, routeNode]) => {
602
- return `'${id}': typeof ${utils.getResolvedRouteNodeVariableName(routeNode)}`;
603
- })}
416
+ return `'${id}': typeof ${require_utils.getResolvedRouteNodeVariableName(routeNode)}`;
417
+ })}
604
418
  }`,
605
- `export interface FileRouteTypes {
419
+ `export interface FileRouteTypes {
606
420
  fileRoutesByFullPath: FileRoutesByFullPath
607
421
  fullPaths: ${acc.routeNodes.length > 0 ? [...routeNodesByFullPath.keys()].filter((fullPath) => fullPath).map((fullPath) => `'${fullPath}'`).join("|") : "never"}
608
422
  fileRoutesByTo: FileRoutesByTo
609
423
  to: ${acc.routeNodes.length > 0 ? [...routeNodesByTo.keys()].filter((to) => to).map((to) => `'${to}'`).join("|") : "never"}
610
- id: ${[`'${routerCore.rootRouteId}'`, ...[...routeNodesById.keys()].map((id) => `'${id}'`)].join("|")}
424
+ id: ${[`'${_tanstack_router_core.rootRouteId}'`, ...[...routeNodesById.keys()].map((id) => `'${id}'`)].join("|")}
611
425
  fileRoutesById: FileRoutesById
612
426
  }`,
613
- `export interface RootRouteChildren {
614
- ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${utils.getResolvedRouteNodeVariableName(child)}`).join(",")}
427
+ `export interface RootRouteChildren {
428
+ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${require_utils.getResolvedRouteNodeVariableName(child)}`).join(",")}
615
429
  }`
616
- ].join("\n");
617
- fileRoutesByPathInterface = utils.buildFileRoutesByPathInterface({
618
- module: this.targetTemplate.fullPkg,
619
- interfaceName: "FileRoutesByPath",
620
- routeNodes: sortedRouteNodes
621
- });
622
- }
623
- const routeTree = [
624
- `const rootRouteChildren${config.disableTypes ? "" : `: RootRouteChildren`} = {
625
- ${acc.routeTree.map(
626
- (child) => `${child.variableName}Route: ${utils.getResolvedRouteNodeVariableName(child)}`
627
- ).join(",")}
628
- }`,
629
- rootRouteUpdate ? rootRouteUpdate.replace(
630
- "const rootRouteWithChildren = ",
631
- "export const routeTree = "
632
- ) : `export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)${config.disableTypes ? "" : `._addFileTypes<FileRouteTypes>()`}`
633
- ].join("\n");
634
- utils.checkRouteFullPathUniqueness(
635
- sortedRouteNodes.filter(
636
- (d) => d.children === void 0 && "lazy" !== d._fsRouteType
637
- ),
638
- config
639
- );
640
- let mergedImports = utils.mergeImportDeclarations(imports);
641
- if (config.disableTypes) {
642
- mergedImports = mergedImports.filter((d) => d.importKind !== "type");
643
- }
644
- const importStatements = mergedImports.map(utils.buildImportString);
645
- let moduleAugmentation = "";
646
- if (config.verboseFileRoutes === false && !config.disableTypes) {
647
- moduleAugmentation = opts.routeFileResult.map((node) => {
648
- const getModuleDeclaration = (routeNode) => {
649
- if (!utils.isRouteNodeValidForAugmentation(routeNode)) {
650
- return "";
651
- }
652
- let moduleAugmentation2 = "";
653
- if (routeNode._fsRouteType === "lazy") {
654
- moduleAugmentation2 = `const createLazyFileRoute: CreateLazyFileRoute<FileRoutesByPath['${routeNode.routePath}']['preLoaderRoute']>`;
655
- } else {
656
- moduleAugmentation2 = `const createFileRoute: CreateFileRoute<'${routeNode.routePath}',
430
+ ].join("\n");
431
+ fileRoutesByPathInterface = require_utils.buildFileRoutesByPathInterface({
432
+ module: this.targetTemplate.fullPkg,
433
+ interfaceName: "FileRoutesByPath",
434
+ routeNodes: sortedRouteNodes,
435
+ config
436
+ });
437
+ }
438
+ const routeTree = [`const rootRouteChildren${config.disableTypes ? "" : `: RootRouteChildren`} = {
439
+ ${acc.routeTree.map((child) => `${child.variableName}Route: ${require_utils.getResolvedRouteNodeVariableName(child)}`).join(",")}
440
+ }`, rootRouteUpdate ? rootRouteUpdate.replace("const rootRouteWithChildren = ", "export const routeTree = ") : `export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)${config.disableTypes ? "" : `._addFileTypes<FileRouteTypes>()`}`].join("\n");
441
+ require_utils.checkRouteFullPathUniqueness(sortedRouteNodes.filter((d) => d.children === void 0 && "lazy" !== d._fsRouteType), config);
442
+ let mergedImports = require_utils.mergeImportDeclarations(imports);
443
+ if (config.disableTypes) mergedImports = mergedImports.filter((d) => d.importKind !== "type");
444
+ const importStatements = mergedImports.map(require_utils.buildImportString);
445
+ let moduleAugmentation = "";
446
+ if (config.verboseFileRoutes === false && !config.disableTypes) moduleAugmentation = opts.routeFileResult.map((node) => {
447
+ const getModuleDeclaration = (routeNode) => {
448
+ if (!require_utils.isRouteNodeValidForAugmentation(routeNode)) return "";
449
+ let moduleAugmentation = "";
450
+ if (routeNode._fsRouteType === "lazy") moduleAugmentation = `const createLazyFileRoute: CreateLazyFileRoute<FileRoutesByPath['${routeNode.routePath}']['preLoaderRoute']>`;
451
+ else moduleAugmentation = `const createFileRoute: CreateFileRoute<'${routeNode.routePath}',
657
452
  FileRoutesByPath['${routeNode.routePath}']['parentRoute'],
658
453
  FileRoutesByPath['${routeNode.routePath}']['id'],
659
454
  FileRoutesByPath['${routeNode.routePath}']['path'],
660
455
  FileRoutesByPath['${routeNode.routePath}']['fullPath']
661
456
  >
662
457
  `;
663
- }
664
- return `declare module './${utils.getImportPath(routeNode, config, this.generatedRouteTreePath)}' {
665
- ${moduleAugmentation2}
458
+ return `declare module './${require_utils.getImportPath(routeNode, config, this.generatedRouteTreePath)}' {
459
+ ${moduleAugmentation}
666
460
  }`;
667
- };
668
- return getModuleDeclaration(node);
669
- }).join("\n");
670
- }
671
- const rootRouteImport = utils.getImportForRouteNode(
672
- rootRouteNode,
673
- config,
674
- this.generatedRouteTreePath,
675
- this.root
676
- );
677
- routeImports.unshift(rootRouteImport);
678
- let footer = [];
679
- if (config.routeTreeFileFooter) {
680
- if (Array.isArray(config.routeTreeFileFooter)) {
681
- footer = config.routeTreeFileFooter;
682
- } else {
683
- footer = config.routeTreeFileFooter();
684
- }
685
- }
686
- const routeTreeContent = [
687
- ...config.routeTreeFileHeader,
688
- `// This file was automatically generated by TanStack Router.
461
+ };
462
+ return getModuleDeclaration(node);
463
+ }).join("\n");
464
+ const rootRouteImport = require_utils.getImportForRouteNode(rootRouteNode, config, this.generatedRouteTreePath, this.root);
465
+ routeImports.unshift(rootRouteImport);
466
+ let footer = [];
467
+ if (config.routeTreeFileFooter) if (Array.isArray(config.routeTreeFileFooter)) footer = config.routeTreeFileFooter;
468
+ else footer = config.routeTreeFileFooter();
469
+ return {
470
+ routeTreeContent: [
471
+ ...config.routeTreeFileHeader,
472
+ `// This file was automatically generated by TanStack Router.
689
473
  // You should NOT make any changes in this file as it will be overwritten.
690
474
  // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.`,
691
- [...importStatements].join("\n"),
692
- utils.mergeImportDeclarations(routeImports).map(utils.buildImportString).join("\n"),
693
- virtualRouteNodes.join("\n"),
694
- createUpdateRoutes.join("\n"),
695
- fileRoutesByFullPath,
696
- fileRoutesByPathInterface,
697
- moduleAugmentation,
698
- routeTreeConfig.join("\n"),
699
- routeTree,
700
- ...footer
701
- ].filter(Boolean).join("\n\n");
702
- return {
703
- routeTreeContent,
704
- routeTree: acc.routeTree,
705
- routeNodes: acc.routeNodes
706
- };
707
- }
708
- async processRouteNodeFile(node) {
709
- const result = await this.isRouteFileCacheFresh(node);
710
- if (result.status === "fresh") {
711
- return {
712
- node: result.cacheEntry.node,
713
- shouldWriteTree: false,
714
- cacheEntry: result.cacheEntry
715
- };
716
- }
717
- const previousCacheEntry = result.cacheEntry;
718
- const existingRouteFile = await this.fs.readFile(node.fullPath);
719
- if (existingRouteFile === "file-not-existing") {
720
- throw new Error(`⚠️ File ${node.fullPath} does not exist`);
721
- }
722
- if (node.routePath) {
723
- validateRouteParams.validateRouteParams(node.routePath, node.filePath, this.logger);
724
- }
725
- const updatedCacheEntry = {
726
- fileContent: existingRouteFile.fileContent,
727
- mtimeMs: existingRouteFile.stat.mtimeMs,
728
- routeId: node.routePath ?? "$$TSR_NO_ROUTE_PATH_ASSIGNED$$",
729
- node
730
- };
731
- const escapedRoutePath = node.routePath?.replaceAll("$", "$$") ?? "";
732
- let shouldWriteRouteFile = false;
733
- let shouldWriteTree = false;
734
- if (!existingRouteFile.fileContent) {
735
- shouldWriteRouteFile = true;
736
- shouldWriteTree = true;
737
- if (node._fsRouteType === "lazy") {
738
- const tLazyRouteTemplate = this.targetTemplate.lazyRoute;
739
- updatedCacheEntry.fileContent = await template.fillTemplate(
740
- this.config,
741
- (this.config.customScaffolding?.lazyRouteTemplate || this.config.customScaffolding?.routeTemplate) ?? tLazyRouteTemplate.template(),
742
- {
743
- tsrImports: tLazyRouteTemplate.imports.tsrImports(),
744
- tsrPath: escapedRoutePath.replaceAll(/\{(.+?)\}/gm, "$1"),
745
- tsrExportStart: tLazyRouteTemplate.imports.tsrExportStart(escapedRoutePath),
746
- tsrExportEnd: tLazyRouteTemplate.imports.tsrExportEnd()
747
- }
748
- );
749
- } else if (
750
- // Creating a new normal route file
751
- ["layout", "static"].some(
752
- (d) => d === node._fsRouteType
753
- ) || [
754
- "component",
755
- "pendingComponent",
756
- "errorComponent",
757
- "notFoundComponent",
758
- "loader"
759
- ].every((d) => d !== node._fsRouteType)
760
- ) {
761
- const tRouteTemplate = this.targetTemplate.route;
762
- updatedCacheEntry.fileContent = await template.fillTemplate(
763
- this.config,
764
- this.config.customScaffolding?.routeTemplate ?? tRouteTemplate.template(),
765
- {
766
- tsrImports: tRouteTemplate.imports.tsrImports(),
767
- tsrPath: escapedRoutePath.replaceAll(/\{(.+?)\}/gm, "$1"),
768
- tsrExportStart: tRouteTemplate.imports.tsrExportStart(escapedRoutePath),
769
- tsrExportEnd: tRouteTemplate.imports.tsrExportEnd()
770
- }
771
- );
772
- } else {
773
- return null;
774
- }
775
- }
776
- const isVueFile = node.filePath.endsWith(".vue");
777
- if (!isVueFile) {
778
- const transformResult = await transform.transform({
779
- source: updatedCacheEntry.fileContent,
780
- ctx: {
781
- target: this.config.target,
782
- routeId: escapedRoutePath,
783
- lazy: node._fsRouteType === "lazy",
784
- verboseFileRoutes: !(this.config.verboseFileRoutes === false)
785
- },
786
- node
787
- });
788
- if (transformResult.result === "no-route-export") {
789
- const fileName = path.basename(node.fullPath);
790
- const dirName = path.dirname(node.fullPath);
791
- const ignorePrefix = this.config.routeFileIgnorePrefix;
792
- const ignorePattern = this.config.routeFileIgnorePattern;
793
- const suggestedFileName = `${ignorePrefix}${fileName}`;
794
- const suggestedFullPath = path.join(dirName, suggestedFileName);
795
- let message = `Warning: Route file "${node.fullPath}" does not export a Route. This file will not be included in the route tree.`;
796
- message += `
797
-
798
- If this file is not intended to be a route, you can exclude it using one of these options:`;
799
- message += `
800
- 1. Rename the file to "${suggestedFullPath}" (prefix with "${ignorePrefix}")`;
801
- message += `
802
- 2. Use 'routeFileIgnorePattern' in your config to match this file`;
803
- message += `
804
-
805
- Current configuration:`;
806
- message += `
807
- routeFileIgnorePrefix: "${ignorePrefix}"`;
808
- message += `
809
- routeFileIgnorePattern: ${ignorePattern ? `"${ignorePattern}"` : "undefined"}`;
810
- this.logger.warn(message);
811
- return null;
812
- }
813
- if (transformResult.result === "error") {
814
- throw new Error(
815
- `Error transforming route file ${node.fullPath}: ${transformResult.error}`
816
- );
817
- }
818
- if (transformResult.result === "modified") {
819
- updatedCacheEntry.fileContent = transformResult.output;
820
- shouldWriteRouteFile = true;
821
- }
822
- }
823
- for (const plugin of this.plugins) {
824
- plugin.afterTransform?.({ node, prevNode: previousCacheEntry?.node });
825
- }
826
- if (shouldWriteRouteFile) {
827
- const stats = await this.safeFileWrite({
828
- filePath: node.fullPath,
829
- newContent: updatedCacheEntry.fileContent,
830
- strategy: {
831
- type: "mtime",
832
- expectedMtimeMs: updatedCacheEntry.mtimeMs
833
- }
834
- });
835
- updatedCacheEntry.mtimeMs = stats.mtimeMs;
836
- }
837
- this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry);
838
- return {
839
- node,
840
- shouldWriteTree,
841
- cacheEntry: updatedCacheEntry
842
- };
843
- }
844
- async didRouteFileChangeComparedToCache(file, cache) {
845
- const cacheEntry = this[cache].get(file.path);
846
- return this.didFileChangeComparedToCache(file, cacheEntry);
847
- }
848
- async didFileChangeComparedToCache(file, cacheEntry) {
849
- if (!cacheEntry) {
850
- return { result: "file-not-in-cache" };
851
- }
852
- let mtimeMs = file.mtimeMs;
853
- if (mtimeMs === void 0) {
854
- try {
855
- const currentStat = await this.fs.stat(file.path);
856
- mtimeMs = currentStat.mtimeMs;
857
- } catch {
858
- return { result: "cannot-stat-file" };
859
- }
860
- }
861
- return { result: mtimeMs !== cacheEntry.mtimeMs, mtimeMs, cacheEntry };
862
- }
863
- async safeFileWrite(opts) {
864
- const tmpPath = this.getTempFileName(opts.filePath);
865
- await this.fs.writeFile(tmpPath, opts.newContent);
866
- if (opts.strategy.type === "mtime") {
867
- const beforeStat = await this.fs.stat(opts.filePath);
868
- if (beforeStat.mtimeMs !== opts.strategy.expectedMtimeMs) {
869
- throw rerun({
870
- msg: `File ${opts.filePath} was modified by another process during processing.`,
871
- event: { type: "update", path: opts.filePath }
872
- });
873
- }
874
- const newFileState = await this.fs.stat(tmpPath);
875
- if (newFileState.mode !== beforeStat.mode) {
876
- await this.fs.chmod(tmpPath, beforeStat.mode);
877
- }
878
- if (newFileState.uid !== beforeStat.uid || newFileState.gid !== beforeStat.gid) {
879
- try {
880
- await this.fs.chown(tmpPath, beforeStat.uid, beforeStat.gid);
881
- } catch (err) {
882
- if (typeof err === "object" && err !== null && "code" in err && err.code === "EPERM") {
883
- console.warn(
884
- `[safeFileWrite] chown failed: ${err.message}`
885
- );
886
- } else {
887
- throw err;
888
- }
889
- }
890
- }
891
- } else {
892
- if (await utils.checkFileExists(opts.filePath)) {
893
- throw rerun({
894
- msg: `File ${opts.filePath} already exists. Cannot overwrite.`,
895
- event: { type: "update", path: opts.filePath }
896
- });
897
- }
898
- }
899
- const stat = await this.fs.stat(tmpPath);
900
- await this.fs.rename(tmpPath, opts.filePath);
901
- return stat;
902
- }
903
- getTempFileName(filePath) {
904
- const absPath = path.resolve(filePath);
905
- const hash = crypto.createHash("md5").update(absPath).digest("hex");
906
- if (!this.sessionId) {
907
- node_fs.mkdirSync(this.config.tmpDir, { recursive: true });
908
- this.sessionId = crypto.randomBytes(4).toString("hex");
909
- }
910
- return path.join(this.config.tmpDir, `${this.sessionId}-${hash}`);
911
- }
912
- async isRouteFileCacheFresh(node) {
913
- const fileChangedCache = await this.didRouteFileChangeComparedToCache(
914
- { path: node.fullPath },
915
- "routeNodeCache"
916
- );
917
- if (fileChangedCache.result === false) {
918
- this.routeNodeShadowCache.set(node.fullPath, fileChangedCache.cacheEntry);
919
- return {
920
- status: "fresh",
921
- cacheEntry: fileChangedCache.cacheEntry
922
- };
923
- }
924
- if (fileChangedCache.result === "cannot-stat-file") {
925
- throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`);
926
- }
927
- const mtimeMs = fileChangedCache.result === true ? fileChangedCache.mtimeMs : void 0;
928
- const shadowCacheFileChange = await this.didRouteFileChangeComparedToCache(
929
- { path: node.fullPath, mtimeMs },
930
- "routeNodeShadowCache"
931
- );
932
- if (shadowCacheFileChange.result === "cannot-stat-file") {
933
- throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`);
934
- }
935
- if (shadowCacheFileChange.result === false) {
936
- if (fileChangedCache.result === true) {
937
- return {
938
- status: "fresh",
939
- cacheEntry: shadowCacheFileChange.cacheEntry
940
- };
941
- }
942
- }
943
- if (fileChangedCache.result === "file-not-in-cache") {
944
- return {
945
- status: "stale"
946
- };
947
- }
948
- return { status: "stale", cacheEntry: fileChangedCache.cacheEntry };
949
- }
950
- async handleRootNode(node) {
951
- const result = await this.isRouteFileCacheFresh(node);
952
- if (result.status === "fresh") {
953
- this.routeNodeShadowCache.set(node.fullPath, result.cacheEntry);
954
- }
955
- const rootNodeFile = await this.fs.readFile(node.fullPath);
956
- if (rootNodeFile === "file-not-existing") {
957
- throw new Error(`⚠️ expected root route to exist at ${node.fullPath}`);
958
- }
959
- const updatedCacheEntry = {
960
- fileContent: rootNodeFile.fileContent,
961
- mtimeMs: rootNodeFile.stat.mtimeMs,
962
- routeId: node.routePath ?? "$$TSR_NO_ROOT_ROUTE_PATH_ASSIGNED$$",
963
- node
964
- };
965
- if (!rootNodeFile.fileContent) {
966
- const rootTemplate = this.targetTemplate.rootRoute;
967
- const rootRouteContent = await template.fillTemplate(
968
- this.config,
969
- rootTemplate.template(),
970
- {
971
- tsrImports: rootTemplate.imports.tsrImports(),
972
- tsrPath: rootPathId.rootPathId,
973
- tsrExportStart: rootTemplate.imports.tsrExportStart(),
974
- tsrExportEnd: rootTemplate.imports.tsrExportEnd()
975
- }
976
- );
977
- this.logger.log(`🟡 Creating ${node.fullPath}`);
978
- const stats = await this.safeFileWrite({
979
- filePath: node.fullPath,
980
- newContent: rootRouteContent,
981
- strategy: {
982
- type: "mtime",
983
- expectedMtimeMs: rootNodeFile.stat.mtimeMs
984
- }
985
- });
986
- updatedCacheEntry.fileContent = rootRouteContent;
987
- updatedCacheEntry.mtimeMs = stats.mtimeMs;
988
- }
989
- this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry);
990
- }
991
- async getCrawlingResult() {
992
- await this.runPromise;
993
- return this.crawlingResult;
994
- }
995
- static handleNode(node, acc, prefixMap, config) {
996
- let parentRoute = utils.hasParentRoute(prefixMap, node, node.routePath);
997
- if (node.routePath) {
998
- let searchPath = node.routePath;
999
- while (searchPath.length > 0) {
1000
- const lastSlash = searchPath.lastIndexOf("/");
1001
- if (lastSlash <= 0) break;
1002
- searchPath = searchPath.substring(0, lastSlash);
1003
- const candidate = acc.routeNodesByPath.get(searchPath);
1004
- if (candidate && candidate.routePath !== node.routePath) {
1005
- if (candidate !== parentRoute) {
1006
- if (!parentRoute || (candidate.routePath?.length ?? 0) > (parentRoute.routePath?.length ?? 0)) {
1007
- parentRoute = candidate;
1008
- }
1009
- }
1010
- break;
1011
- }
1012
- }
1013
- }
1014
- if (node._virtualParentRoutePath !== void 0) {
1015
- const explicitParent = acc.routeNodesByPath.get(
1016
- node._virtualParentRoutePath
1017
- );
1018
- if (explicitParent) {
1019
- parentRoute = explicitParent;
1020
- } else if (node._virtualParentRoutePath === `/${rootPathId.rootPathId}`) {
1021
- parentRoute = null;
1022
- }
1023
- }
1024
- if (parentRoute) node.parent = parentRoute;
1025
- node.path = utils.determineNodePath(node);
1026
- const trimmedPath = utils.trimPathLeft(node.path ?? "");
1027
- const trimmedOriginalPath = utils.trimPathLeft(
1028
- node.originalRoutePath?.replace(
1029
- node.parent?.originalRoutePath ?? "",
1030
- ""
1031
- ) ?? ""
1032
- );
1033
- const split = trimmedPath.split("/");
1034
- const originalSplit = trimmedOriginalPath.split("/");
1035
- const lastRouteSegment = split[split.length - 1] ?? trimmedPath;
1036
- const lastOriginalSegment = originalSplit[originalSplit.length - 1] ?? trimmedOriginalPath;
1037
- node.isNonPath = utils.isSegmentPathless(lastRouteSegment, lastOriginalSegment) || split.every((part) => this.routeGroupPatternRegex.test(part));
1038
- node.cleanedPath = utils.removeGroups(
1039
- utils.removeUnderscoresWithEscape(
1040
- utils.removeLayoutSegmentsWithEscape(node.path, node.originalRoutePath),
1041
- node.originalRoutePath
1042
- )
1043
- );
1044
- if (node._fsRouteType === "layout" || node._fsRouteType === "pathless_layout") {
1045
- node.cleanedPath = utils.removeTrailingSlash(node.cleanedPath);
1046
- }
1047
- if (!node.isVirtual && [
1048
- "lazy",
1049
- "loader",
1050
- "component",
1051
- "pendingComponent",
1052
- "errorComponent",
1053
- "notFoundComponent"
1054
- ].some((d) => d === node._fsRouteType)) {
1055
- acc.routePiecesByPath[node.routePath] = acc.routePiecesByPath[node.routePath] || {};
1056
- const pieceKey = node._fsRouteType === "lazy" ? "lazy" : node._fsRouteType;
1057
- acc.routePiecesByPath[node.routePath][pieceKey] = node;
1058
- const anchorRoute = acc.routeNodesByPath.get(node.routePath);
1059
- if (!anchorRoute && node.routePath !== `/${rootPathId.rootPathId}`) {
1060
- this.handleNode(
1061
- {
1062
- ...node,
1063
- isVirtual: true,
1064
- _fsRouteType: "static"
1065
- },
1066
- acc,
1067
- prefixMap,
1068
- config
1069
- );
1070
- }
1071
- return;
1072
- }
1073
- const isPathlessLayoutWithPath = node._fsRouteType === "pathless_layout" && node.cleanedPath && node.cleanedPath.length > 0;
1074
- if (!node.isVirtual && isPathlessLayoutWithPath) {
1075
- const immediateParentPath = utils.removeLastSegmentFromPath(node.routePath) || "/";
1076
- const immediateParentOriginalPath = utils.removeLastSegmentFromPath(node.originalRoutePath) || "/";
1077
- let searchPath = immediateParentPath;
1078
- while (searchPath) {
1079
- const candidate = acc.routeNodesByPath.get(searchPath);
1080
- if (candidate && !candidate.isVirtual && candidate.path !== "/") {
1081
- node.parent = candidate;
1082
- node.path = node.routePath?.replace(candidate.routePath ?? "", "") || "/";
1083
- const pathRelativeToParent = immediateParentPath.replace(candidate.routePath ?? "", "") || "/";
1084
- const originalPathRelativeToParent = immediateParentOriginalPath.replace(
1085
- candidate.originalRoutePath ?? "",
1086
- ""
1087
- ) || "/";
1088
- node.cleanedPath = utils.removeGroups(
1089
- utils.removeUnderscoresWithEscape(
1090
- utils.removeLayoutSegmentsWithEscape(
1091
- pathRelativeToParent,
1092
- originalPathRelativeToParent
1093
- ),
1094
- originalPathRelativeToParent
1095
- )
1096
- );
1097
- break;
1098
- }
1099
- if (searchPath === "/") break;
1100
- searchPath = utils.removeLastSegmentFromPath(searchPath) || "/";
1101
- }
1102
- }
1103
- if (node.parent) {
1104
- node.parent.children = node.parent.children ?? [];
1105
- node.parent.children.push(node);
1106
- } else {
1107
- acc.routeTree.push(node);
1108
- }
1109
- acc.routeNodes.push(node);
1110
- if (node.routePath) {
1111
- acc.routeNodesByPath.set(node.routePath, node);
1112
- }
1113
- }
1114
- // only process files that are relevant for the route tree generation
1115
- isFileRelevantForRouteTreeGeneration(filePath) {
1116
- if (filePath === this.generatedRouteTreePath) {
1117
- return true;
1118
- }
1119
- if (filePath.startsWith(this.routesDirectoryPath)) {
1120
- return true;
1121
- }
1122
- if (typeof this.config.virtualRouteConfig === "string" && filePath === this.config.virtualRouteConfig) {
1123
- return true;
1124
- }
1125
- if (this.routeNodeCache.has(filePath)) {
1126
- return true;
1127
- }
1128
- if (getRouteNodes$1.isVirtualConfigFile(path.basename(filePath))) {
1129
- return true;
1130
- }
1131
- if (this.physicalDirectories.some((dir) => filePath.startsWith(dir))) {
1132
- return true;
1133
- }
1134
- return false;
1135
- }
475
+ [...importStatements].join("\n"),
476
+ require_utils.mergeImportDeclarations(routeImports).map(require_utils.buildImportString).join("\n"),
477
+ virtualRouteNodes.join("\n"),
478
+ createUpdateRoutes.join("\n"),
479
+ fileRoutesByFullPath,
480
+ fileRoutesByPathInterface,
481
+ moduleAugmentation,
482
+ routeTreeConfig.join("\n"),
483
+ routeTree,
484
+ ...footer
485
+ ].filter(Boolean).join("\n\n"),
486
+ routeTree: acc.routeTree,
487
+ routeNodes: acc.routeNodes
488
+ };
489
+ }
490
+ async processRouteNodeFile(node) {
491
+ const result = await this.isRouteFileCacheFresh(node);
492
+ if (result.status === "fresh") return {
493
+ node: result.cacheEntry.node,
494
+ shouldWriteTree: false,
495
+ cacheEntry: result.cacheEntry
496
+ };
497
+ const previousCacheEntry = result.cacheEntry;
498
+ const existingRouteFile = await this.fs.readFile(node.fullPath);
499
+ if (existingRouteFile === "file-not-existing") throw new Error(`⚠️ File ${node.fullPath} does not exist`);
500
+ if (node.routePath) require_validate_route_params.validateRouteParams(node.routePath, node.filePath, this.logger);
501
+ const updatedCacheEntry = {
502
+ fileContent: existingRouteFile.fileContent,
503
+ mtimeMs: existingRouteFile.stat.mtimeMs,
504
+ routeId: node.routePath ?? "$$TSR_NO_ROUTE_PATH_ASSIGNED$$",
505
+ node
506
+ };
507
+ const escapedRoutePath = node.routePath?.replaceAll("$", "$$") ?? "";
508
+ let shouldWriteRouteFile = false;
509
+ let shouldWriteTree = false;
510
+ if (!existingRouteFile.fileContent) {
511
+ shouldWriteRouteFile = true;
512
+ shouldWriteTree = true;
513
+ if (node._fsRouteType === "lazy") {
514
+ const tLazyRouteTemplate = this.targetTemplate.lazyRoute;
515
+ updatedCacheEntry.fileContent = await require_template.fillTemplate(this.config, (this.config.customScaffolding?.lazyRouteTemplate || this.config.customScaffolding?.routeTemplate) ?? tLazyRouteTemplate.template(), {
516
+ tsrImports: tLazyRouteTemplate.imports.tsrImports(),
517
+ tsrPath: escapedRoutePath.replaceAll(/\{(.+?)\}/gm, "$1"),
518
+ tsrExportStart: tLazyRouteTemplate.imports.tsrExportStart(escapedRoutePath),
519
+ tsrExportEnd: tLazyRouteTemplate.imports.tsrExportEnd()
520
+ });
521
+ } else if (["layout", "static"].some((d) => d === node._fsRouteType) || [
522
+ "component",
523
+ "pendingComponent",
524
+ "errorComponent",
525
+ "notFoundComponent",
526
+ "loader"
527
+ ].every((d) => d !== node._fsRouteType)) {
528
+ const tRouteTemplate = this.targetTemplate.route;
529
+ updatedCacheEntry.fileContent = await require_template.fillTemplate(this.config, this.config.customScaffolding?.routeTemplate ?? tRouteTemplate.template(), {
530
+ tsrImports: tRouteTemplate.imports.tsrImports(),
531
+ tsrPath: escapedRoutePath.replaceAll(/\{(.+?)\}/gm, "$1"),
532
+ tsrExportStart: tRouteTemplate.imports.tsrExportStart(escapedRoutePath),
533
+ tsrExportEnd: tRouteTemplate.imports.tsrExportEnd()
534
+ });
535
+ } else return null;
536
+ }
537
+ if (!node.filePath.endsWith(".vue")) {
538
+ const transformResult = await require_transform.transform({
539
+ source: updatedCacheEntry.fileContent,
540
+ ctx: {
541
+ target: this.config.target,
542
+ routeId: escapedRoutePath,
543
+ lazy: node._fsRouteType === "lazy",
544
+ verboseFileRoutes: !(this.config.verboseFileRoutes === false)
545
+ },
546
+ node
547
+ });
548
+ if (transformResult.result === "no-route-export") {
549
+ const fileName = node_path.default.basename(node.fullPath);
550
+ const dirName = node_path.default.dirname(node.fullPath);
551
+ const ignorePrefix = this.config.routeFileIgnorePrefix;
552
+ const ignorePattern = this.config.routeFileIgnorePattern;
553
+ const suggestedFileName = `${ignorePrefix}${fileName}`;
554
+ const suggestedFullPath = node_path.default.join(dirName, suggestedFileName);
555
+ let message = `Warning: Route file "${node.fullPath}" does not export a Route. This file will not be included in the route tree.`;
556
+ message += `\n\nIf this file is not intended to be a route, you can exclude it using one of these options:`;
557
+ message += `\n 1. Rename the file to "${suggestedFullPath}" (prefix with "${ignorePrefix}")`;
558
+ message += `\n 2. Use 'routeFileIgnorePattern' in your config to match this file`;
559
+ message += `\n\nCurrent configuration:`;
560
+ message += `\n routeFileIgnorePrefix: "${ignorePrefix}"`;
561
+ message += `\n routeFileIgnorePattern: ${ignorePattern ? `"${ignorePattern}"` : "undefined"}`;
562
+ this.logger.warn(message);
563
+ return null;
564
+ }
565
+ if (transformResult.result === "error") throw new Error(`Error transforming route file ${node.fullPath}: ${transformResult.error}`);
566
+ if (transformResult.result === "modified") {
567
+ updatedCacheEntry.fileContent = transformResult.output;
568
+ shouldWriteRouteFile = true;
569
+ }
570
+ }
571
+ for (const plugin of this.plugins) plugin.afterTransform?.({
572
+ node,
573
+ prevNode: previousCacheEntry?.node
574
+ });
575
+ if (shouldWriteRouteFile) updatedCacheEntry.mtimeMs = (await this.safeFileWrite({
576
+ filePath: node.fullPath,
577
+ newContent: updatedCacheEntry.fileContent,
578
+ strategy: {
579
+ type: "mtime",
580
+ expectedMtimeMs: updatedCacheEntry.mtimeMs
581
+ }
582
+ })).mtimeMs;
583
+ this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry);
584
+ return {
585
+ node,
586
+ shouldWriteTree,
587
+ cacheEntry: updatedCacheEntry
588
+ };
589
+ }
590
+ async didRouteFileChangeComparedToCache(file, cache) {
591
+ const cacheEntry = this[cache].get(file.path);
592
+ return this.didFileChangeComparedToCache(file, cacheEntry);
593
+ }
594
+ async didFileChangeComparedToCache(file, cacheEntry) {
595
+ if (!cacheEntry) return { result: "file-not-in-cache" };
596
+ let mtimeMs = file.mtimeMs;
597
+ if (mtimeMs === void 0) try {
598
+ mtimeMs = (await this.fs.stat(file.path)).mtimeMs;
599
+ } catch {
600
+ return { result: "cannot-stat-file" };
601
+ }
602
+ return {
603
+ result: mtimeMs !== cacheEntry.mtimeMs,
604
+ mtimeMs,
605
+ cacheEntry
606
+ };
607
+ }
608
+ async safeFileWrite(opts) {
609
+ const tmpPath = this.getTempFileName(opts.filePath);
610
+ await this.fs.writeFile(tmpPath, opts.newContent);
611
+ if (opts.strategy.type === "mtime") {
612
+ const beforeStat = await this.fs.stat(opts.filePath);
613
+ if (beforeStat.mtimeMs !== opts.strategy.expectedMtimeMs) throw rerun({
614
+ msg: `File ${opts.filePath} was modified by another process during processing.`,
615
+ event: {
616
+ type: "update",
617
+ path: opts.filePath
618
+ }
619
+ });
620
+ const newFileState = await this.fs.stat(tmpPath);
621
+ if (newFileState.mode !== beforeStat.mode) await this.fs.chmod(tmpPath, beforeStat.mode);
622
+ if (newFileState.uid !== beforeStat.uid || newFileState.gid !== beforeStat.gid) try {
623
+ await this.fs.chown(tmpPath, beforeStat.uid, beforeStat.gid);
624
+ } catch (err) {
625
+ if (typeof err === "object" && err !== null && "code" in err && err.code === "EPERM") console.warn(`[safeFileWrite] chown failed: ${err.message}`);
626
+ else throw err;
627
+ }
628
+ } else if (await require_utils.checkFileExists(opts.filePath)) throw rerun({
629
+ msg: `File ${opts.filePath} already exists. Cannot overwrite.`,
630
+ event: {
631
+ type: "update",
632
+ path: opts.filePath
633
+ }
634
+ });
635
+ const stat = await this.fs.stat(tmpPath);
636
+ await this.fs.rename(tmpPath, opts.filePath);
637
+ return stat;
638
+ }
639
+ getTempFileName(filePath) {
640
+ const absPath = node_path.default.resolve(filePath);
641
+ const hash = node_crypto.default.createHash("md5").update(absPath).digest("hex");
642
+ if (!this.sessionId) {
643
+ (0, node_fs.mkdirSync)(this.config.tmpDir, { recursive: true });
644
+ this.sessionId = node_crypto.default.randomBytes(4).toString("hex");
645
+ }
646
+ return node_path.default.join(this.config.tmpDir, `${this.sessionId}-${hash}`);
647
+ }
648
+ async isRouteFileCacheFresh(node) {
649
+ const fileChangedCache = await this.didRouteFileChangeComparedToCache({ path: node.fullPath }, "routeNodeCache");
650
+ if (fileChangedCache.result === false) {
651
+ this.routeNodeShadowCache.set(node.fullPath, fileChangedCache.cacheEntry);
652
+ return {
653
+ status: "fresh",
654
+ cacheEntry: fileChangedCache.cacheEntry
655
+ };
656
+ }
657
+ if (fileChangedCache.result === "cannot-stat-file") throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`);
658
+ const mtimeMs = fileChangedCache.result === true ? fileChangedCache.mtimeMs : void 0;
659
+ const shadowCacheFileChange = await this.didRouteFileChangeComparedToCache({
660
+ path: node.fullPath,
661
+ mtimeMs
662
+ }, "routeNodeShadowCache");
663
+ if (shadowCacheFileChange.result === "cannot-stat-file") throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`);
664
+ if (shadowCacheFileChange.result === false) {
665
+ if (fileChangedCache.result === true) return {
666
+ status: "fresh",
667
+ cacheEntry: shadowCacheFileChange.cacheEntry
668
+ };
669
+ }
670
+ if (fileChangedCache.result === "file-not-in-cache") return { status: "stale" };
671
+ return {
672
+ status: "stale",
673
+ cacheEntry: fileChangedCache.cacheEntry
674
+ };
675
+ }
676
+ async handleRootNode(node) {
677
+ const result = await this.isRouteFileCacheFresh(node);
678
+ if (result.status === "fresh") this.routeNodeShadowCache.set(node.fullPath, result.cacheEntry);
679
+ const rootNodeFile = await this.fs.readFile(node.fullPath);
680
+ if (rootNodeFile === "file-not-existing") throw new Error(`⚠️ expected root route to exist at ${node.fullPath}`);
681
+ const updatedCacheEntry = {
682
+ fileContent: rootNodeFile.fileContent,
683
+ mtimeMs: rootNodeFile.stat.mtimeMs,
684
+ routeId: node.routePath ?? "$$TSR_NO_ROOT_ROUTE_PATH_ASSIGNED$$",
685
+ node
686
+ };
687
+ if (!rootNodeFile.fileContent) {
688
+ const rootTemplate = this.targetTemplate.rootRoute;
689
+ const rootRouteContent = await require_template.fillTemplate(this.config, rootTemplate.template(), {
690
+ tsrImports: rootTemplate.imports.tsrImports(),
691
+ tsrPath: require_rootPathId.rootPathId,
692
+ tsrExportStart: rootTemplate.imports.tsrExportStart(),
693
+ tsrExportEnd: rootTemplate.imports.tsrExportEnd()
694
+ });
695
+ this.logger.log(`🟡 Creating ${node.fullPath}`);
696
+ const stats = await this.safeFileWrite({
697
+ filePath: node.fullPath,
698
+ newContent: rootRouteContent,
699
+ strategy: {
700
+ type: "mtime",
701
+ expectedMtimeMs: rootNodeFile.stat.mtimeMs
702
+ }
703
+ });
704
+ updatedCacheEntry.fileContent = rootRouteContent;
705
+ updatedCacheEntry.mtimeMs = stats.mtimeMs;
706
+ }
707
+ this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry);
708
+ }
709
+ async getCrawlingResult() {
710
+ await this.runPromise;
711
+ return this.crawlingResult;
712
+ }
713
+ static handleNode(node, acc, prefixMap, config) {
714
+ let parentRoute = require_utils.hasParentRoute(prefixMap, node, node.routePath);
715
+ if (node.routePath) {
716
+ let searchPath = node.routePath;
717
+ while (searchPath.length > 0) {
718
+ const lastSlash = searchPath.lastIndexOf("/");
719
+ if (lastSlash <= 0) break;
720
+ searchPath = searchPath.substring(0, lastSlash);
721
+ const candidate = acc.routeNodesByPath.get(searchPath);
722
+ if (candidate && candidate.routePath !== node.routePath) {
723
+ if (candidate !== parentRoute) {
724
+ if (!parentRoute || (candidate.routePath?.length ?? 0) > (parentRoute.routePath?.length ?? 0)) parentRoute = candidate;
725
+ }
726
+ break;
727
+ }
728
+ }
729
+ }
730
+ if (node._virtualParentRoutePath !== void 0) {
731
+ const explicitParent = acc.routeNodesByPath.get(node._virtualParentRoutePath);
732
+ if (explicitParent) parentRoute = explicitParent;
733
+ else if (node._virtualParentRoutePath === `/__root`) parentRoute = null;
734
+ }
735
+ if (parentRoute) node.parent = parentRoute;
736
+ node.path = require_utils.determineNodePath(node);
737
+ const trimmedPath = require_utils.trimPathLeft(node.path ?? "");
738
+ const trimmedOriginalPath = require_utils.trimPathLeft(node.originalRoutePath?.replace(node.parent?.originalRoutePath ?? "", "") ?? "");
739
+ const split = trimmedPath.split("/");
740
+ const originalSplit = trimmedOriginalPath.split("/");
741
+ node.isNonPath = require_utils.isSegmentPathless(split[split.length - 1] ?? trimmedPath, originalSplit[originalSplit.length - 1] ?? trimmedOriginalPath) || split.every((part) => this.routeGroupPatternRegex.test(part));
742
+ node.cleanedPath = require_utils.removeGroups(require_utils.removeUnderscoresWithEscape(require_utils.removeLayoutSegmentsWithEscape(node.path, node.originalRoutePath), node.originalRoutePath));
743
+ if (node._fsRouteType === "layout" || node._fsRouteType === "pathless_layout") node.cleanedPath = require_utils.removeTrailingSlash(node.cleanedPath);
744
+ if (!node.isVirtual && [
745
+ "lazy",
746
+ "loader",
747
+ "component",
748
+ "pendingComponent",
749
+ "errorComponent",
750
+ "notFoundComponent"
751
+ ].some((d) => d === node._fsRouteType)) {
752
+ acc.routePiecesByPath[node.routePath] = acc.routePiecesByPath[node.routePath] || {};
753
+ const pieceKey = node._fsRouteType === "lazy" ? "lazy" : node._fsRouteType;
754
+ acc.routePiecesByPath[node.routePath][pieceKey] = node;
755
+ if (!acc.routeNodesByPath.get(node.routePath) && node.routePath !== `/__root`) this.handleNode({
756
+ ...node,
757
+ isVirtual: true,
758
+ _fsRouteType: "static"
759
+ }, acc, prefixMap, config);
760
+ return;
761
+ }
762
+ const isPathlessLayoutWithPath = node._fsRouteType === "pathless_layout" && node.cleanedPath && node.cleanedPath.length > 0;
763
+ if (!node.isVirtual && isPathlessLayoutWithPath) {
764
+ const immediateParentPath = require_utils.removeLastSegmentFromPath(node.routePath) || "/";
765
+ const immediateParentOriginalPath = require_utils.removeLastSegmentFromPath(node.originalRoutePath) || "/";
766
+ let searchPath = immediateParentPath;
767
+ while (searchPath) {
768
+ const candidate = acc.routeNodesByPath.get(searchPath);
769
+ if (candidate && !candidate.isVirtual && candidate.path !== "/") {
770
+ node.parent = candidate;
771
+ node.path = node.routePath?.replace(candidate.routePath ?? "", "") || "/";
772
+ const pathRelativeToParent = immediateParentPath.replace(candidate.routePath ?? "", "") || "/";
773
+ const originalPathRelativeToParent = immediateParentOriginalPath.replace(candidate.originalRoutePath ?? "", "") || "/";
774
+ node.cleanedPath = require_utils.removeGroups(require_utils.removeUnderscoresWithEscape(require_utils.removeLayoutSegmentsWithEscape(pathRelativeToParent, originalPathRelativeToParent), originalPathRelativeToParent));
775
+ break;
776
+ }
777
+ if (searchPath === "/") break;
778
+ searchPath = require_utils.removeLastSegmentFromPath(searchPath) || "/";
779
+ }
780
+ }
781
+ if (node.parent) {
782
+ node.parent.children = node.parent.children ?? [];
783
+ node.parent.children.push(node);
784
+ } else acc.routeTree.push(node);
785
+ acc.routeNodes.push(node);
786
+ if (node.routePath) acc.routeNodesByPath.set(node.routePath, node);
787
+ }
788
+ isFileRelevantForRouteTreeGeneration(filePath) {
789
+ if (filePath === this.generatedRouteTreePath) return true;
790
+ if (filePath.startsWith(this.routesDirectoryPath)) return true;
791
+ if (typeof this.config.virtualRouteConfig === "string" && filePath === this.config.virtualRouteConfig) return true;
792
+ if (this.routeNodeCache.has(filePath)) return true;
793
+ if (require_getRouteNodes$1.isVirtualConfigFile(node_path.default.basename(filePath))) return true;
794
+ if (this.physicalDirectories.some((dir) => filePath.startsWith(dir))) return true;
795
+ return false;
796
+ }
1136
797
  };
1137
- _Generator.routeGroupPatternRegex = /\(.+\)/;
1138
- _Generator.componentPieceRegex = /[./](component|errorComponent|notFoundComponent|pendingComponent|loader|lazy)[.]/;
1139
- let Generator = _Generator;
798
+ //#endregion
1140
799
  exports.Generator = Generator;
1141
- //# sourceMappingURL=generator.cjs.map
800
+
801
+ //# sourceMappingURL=generator.cjs.map