@tanstack/router-generator 1.132.0-alpha.9 → 1.132.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/config.cjs +6 -2
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.cts +12 -9
- package/dist/cjs/generator.cjs +264 -316
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/generator.d.cts +20 -7
- package/dist/cjs/index.cjs +0 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +4 -4
- package/dist/cjs/plugin/types.d.cts +10 -38
- package/dist/cjs/transform/transform.cjs +108 -40
- package/dist/cjs/transform/transform.cjs.map +1 -1
- package/dist/cjs/transform/transform.d.cts +1 -1
- package/dist/cjs/transform/types.d.cts +4 -18
- package/dist/cjs/types.d.cts +1 -1
- package/dist/cjs/utils.cjs +55 -39
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +5 -5
- package/dist/esm/config.d.ts +12 -9
- package/dist/esm/config.js +6 -2
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/generator.d.ts +20 -7
- package/dist/esm/generator.js +266 -318
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/index.d.ts +4 -4
- package/dist/esm/index.js +1 -2
- package/dist/esm/plugin/types.d.ts +10 -38
- package/dist/esm/transform/transform.d.ts +1 -1
- package/dist/esm/transform/transform.js +106 -38
- package/dist/esm/transform/transform.js.map +1 -1
- package/dist/esm/transform/types.d.ts +4 -18
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/utils.d.ts +5 -5
- package/dist/esm/utils.js +55 -39
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/config.ts +7 -1
- package/src/generator.ts +306 -366
- package/src/index.ts +2 -7
- package/src/plugin/types.ts +11 -44
- package/src/transform/transform.ts +118 -53
- package/src/transform/types.ts +5 -18
- package/src/types.ts +1 -1
- package/src/utils.ts +85 -70
- package/dist/cjs/plugin/default-generator-plugin.cjs +0 -94
- package/dist/cjs/plugin/default-generator-plugin.cjs.map +0 -1
- package/dist/cjs/plugin/default-generator-plugin.d.cts +0 -2
- package/dist/cjs/transform/default-transform-plugin.cjs +0 -97
- package/dist/cjs/transform/default-transform-plugin.cjs.map +0 -1
- package/dist/cjs/transform/default-transform-plugin.d.cts +0 -2
- package/dist/esm/plugin/default-generator-plugin.d.ts +0 -2
- package/dist/esm/plugin/default-generator-plugin.js +0 -94
- package/dist/esm/plugin/default-generator-plugin.js.map +0 -1
- package/dist/esm/transform/default-transform-plugin.d.ts +0 -2
- package/dist/esm/transform/default-transform-plugin.js +0 -97
- package/dist/esm/transform/default-transform-plugin.js.map +0 -1
- package/src/plugin/default-generator-plugin.ts +0 -109
- package/src/transform/default-transform-plugin.ts +0 -106
package/dist/cjs/generator.cjs
CHANGED
|
@@ -12,7 +12,6 @@ const rootPathId = require("./filesystem/physical/rootPathId.cjs");
|
|
|
12
12
|
const utils = require("./utils.cjs");
|
|
13
13
|
const template = require("./template.cjs");
|
|
14
14
|
const transform = require("./transform/transform.cjs");
|
|
15
|
-
const defaultGeneratorPlugin = require("./plugin/default-generator-plugin.cjs");
|
|
16
15
|
function _interopNamespaceDefault(e) {
|
|
17
16
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
18
17
|
if (e) {
|
|
@@ -68,15 +67,12 @@ function rerun(opts) {
|
|
|
68
67
|
function isRerun(result) {
|
|
69
68
|
return typeof result === "object" && result !== null && "rerun" in result && result.rerun === true;
|
|
70
69
|
}
|
|
71
|
-
class
|
|
70
|
+
const _Generator = class _Generator {
|
|
72
71
|
constructor(opts) {
|
|
73
72
|
this.routeNodeCache = /* @__PURE__ */ new Map();
|
|
74
73
|
this.routeNodeShadowCache = /* @__PURE__ */ new Map();
|
|
75
74
|
this.fileEventQueue = [];
|
|
76
|
-
this.plugins = [
|
|
77
|
-
this.pluginsWithTransform = [];
|
|
78
|
-
this.transformPlugins = [];
|
|
79
|
-
this.routeGroupPatternRegex = /\(.+\)/g;
|
|
75
|
+
this.plugins = [];
|
|
80
76
|
this.physicalDirectories = [];
|
|
81
77
|
this.config = opts.config;
|
|
82
78
|
this.logger = logger.logging({ disabled: this.config.disableLogging });
|
|
@@ -86,17 +82,9 @@ class Generator {
|
|
|
86
82
|
this.targetTemplate = template.getTargetTemplate(this.config);
|
|
87
83
|
this.routesDirectoryPath = this.getRoutesDirectoryPath();
|
|
88
84
|
this.plugins.push(...opts.config.plugins || []);
|
|
89
|
-
this.plugins
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
throw new Error(
|
|
93
|
-
`Plugin with name "${plugin.name}" is already registered for export ${plugin.transformPlugin.exportName}!`
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
this.pluginsWithTransform.push(plugin);
|
|
97
|
-
this.transformPlugins.push(plugin.transformPlugin);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
85
|
+
for (const plugin of this.plugins) {
|
|
86
|
+
plugin.init?.({ generator: this });
|
|
87
|
+
}
|
|
100
88
|
}
|
|
101
89
|
getGeneratedRouteTreePath() {
|
|
102
90
|
const generatedRouteTreePath = path.isAbsolute(
|
|
@@ -155,12 +143,7 @@ class Generator {
|
|
|
155
143
|
break;
|
|
156
144
|
}
|
|
157
145
|
try {
|
|
158
|
-
const start = performance.now();
|
|
159
146
|
await this.generatorInternal();
|
|
160
|
-
const end = performance.now();
|
|
161
|
-
this.logger.info(
|
|
162
|
-
`Generated route tree in ${Math.round(end - start)}ms`
|
|
163
|
-
);
|
|
164
147
|
} catch (err) {
|
|
165
148
|
const errArray = !Array.isArray(err) ? [err] : err;
|
|
166
149
|
const recoverableErrors = errArray.filter((e) => isRerun(e));
|
|
@@ -207,7 +190,7 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
207
190
|
throw new Error(errorMessage);
|
|
208
191
|
}
|
|
209
192
|
this.physicalDirectories = physicalDirectories;
|
|
210
|
-
|
|
193
|
+
await this.handleRootNode(rootRouteNode);
|
|
211
194
|
const preRouteNodes = utils.multiSortBy(beforeRouteNodes, [
|
|
212
195
|
(d) => d.routePath === "/" ? -1 : 1,
|
|
213
196
|
(d) => d.routePath?.split("/").length,
|
|
@@ -230,20 +213,23 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
230
213
|
}
|
|
231
214
|
const routeFileResult = routeFileAllResult.flatMap((result) => {
|
|
232
215
|
if (result.status === "fulfilled" && result.value !== null) {
|
|
233
|
-
|
|
216
|
+
if (result.value.shouldWriteTree) {
|
|
217
|
+
writeRouteTreeFile = true;
|
|
218
|
+
}
|
|
219
|
+
return result.value.node;
|
|
234
220
|
}
|
|
235
221
|
return [];
|
|
236
222
|
});
|
|
237
|
-
routeFileResult.forEach((
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
writeRouteTreeFile = true;
|
|
223
|
+
routeFileResult.forEach((r) => r.children = void 0);
|
|
224
|
+
const acc = {
|
|
225
|
+
routeTree: [],
|
|
226
|
+
routeNodes: [],
|
|
227
|
+
routePiecesByPath: {}
|
|
228
|
+
};
|
|
229
|
+
for (const node of routeFileResult) {
|
|
230
|
+
_Generator.handleNode(node, acc);
|
|
246
231
|
}
|
|
232
|
+
this.crawlingResult = { rootRouteNode, routeFileResult, acc };
|
|
247
233
|
if (!this.routeTreeFileCache) {
|
|
248
234
|
const routeTreeFile = await this.fs.readFile(this.generatedRouteTreePath);
|
|
249
235
|
if (routeTreeFile !== "file-not-existing") {
|
|
@@ -274,10 +260,14 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
274
260
|
}
|
|
275
261
|
}
|
|
276
262
|
if (!writeRouteTreeFile) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
263
|
+
if (this.routeNodeCache.size !== this.routeNodeShadowCache.size) {
|
|
264
|
+
writeRouteTreeFile = true;
|
|
265
|
+
} else {
|
|
266
|
+
for (const fullPath of this.routeNodeCache.keys()) {
|
|
267
|
+
if (!this.routeNodeShadowCache.has(fullPath)) {
|
|
268
|
+
writeRouteTreeFile = true;
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
281
271
|
}
|
|
282
272
|
}
|
|
283
273
|
}
|
|
@@ -285,11 +275,12 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
285
275
|
this.swapCaches();
|
|
286
276
|
return;
|
|
287
277
|
}
|
|
288
|
-
|
|
278
|
+
const buildResult = this.buildRouteTree({
|
|
289
279
|
rootRouteNode,
|
|
290
|
-
|
|
280
|
+
acc,
|
|
291
281
|
routeFileResult
|
|
292
|
-
);
|
|
282
|
+
});
|
|
283
|
+
let routeTreeContent = buildResult.routeTreeContent;
|
|
293
284
|
routeTreeContent = this.config.enableRouteTreeFormatting ? await utils.format(routeTreeContent, this.config) : routeTreeContent;
|
|
294
285
|
let newMtimeMs;
|
|
295
286
|
if (this.routeTreeFileCache) {
|
|
@@ -321,281 +312,258 @@ Add the file in: "${this.config.routesDirectory}/${rootPathId.rootPathId}.${this
|
|
|
321
312
|
mtimeMs: newMtimeMs
|
|
322
313
|
};
|
|
323
314
|
}
|
|
315
|
+
this.plugins.map((plugin) => {
|
|
316
|
+
return plugin.onRouteTreeChanged?.({
|
|
317
|
+
routeTree: buildResult.routeTree,
|
|
318
|
+
routeNodes: buildResult.routeNodes,
|
|
319
|
+
acc,
|
|
320
|
+
rootRouteNode
|
|
321
|
+
});
|
|
322
|
+
});
|
|
324
323
|
this.swapCaches();
|
|
325
324
|
}
|
|
326
325
|
swapCaches() {
|
|
327
326
|
this.routeNodeCache = this.routeNodeShadowCache;
|
|
328
327
|
this.routeNodeShadowCache = /* @__PURE__ */ new Map();
|
|
329
328
|
}
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
329
|
+
buildRouteTree(opts) {
|
|
330
|
+
const config = { ...this.config, ...opts.config || {} };
|
|
331
|
+
const { rootRouteNode, acc } = opts;
|
|
332
|
+
const sortedRouteNodes = utils.multiSortBy(acc.routeNodes, [
|
|
333
|
+
(d) => d.routePath?.includes(`/${rootPathId.rootPathId}`) ? -1 : 1,
|
|
334
|
+
(d) => d.routePath?.split("/").length,
|
|
335
|
+
(d) => d.routePath?.endsWith(config.indexToken) ? -1 : 1,
|
|
336
|
+
(d) => d
|
|
337
|
+
]);
|
|
338
|
+
const routeImports = sortedRouteNodes.filter((d) => !d.isVirtual).flatMap(
|
|
339
|
+
(node) => utils.getImportForRouteNode(
|
|
340
|
+
node,
|
|
341
|
+
config,
|
|
342
|
+
this.generatedRouteTreePath,
|
|
343
|
+
this.root
|
|
344
|
+
)
|
|
345
|
+
);
|
|
346
|
+
const virtualRouteNodes = sortedRouteNodes.filter((d) => d.isVirtual).map((node) => {
|
|
347
|
+
return `const ${node.variableName}RouteImport = createFileRoute('${node.routePath}')()`;
|
|
348
|
+
});
|
|
349
|
+
const imports = [];
|
|
350
|
+
if (acc.routeNodes.some((n) => n.isVirtual)) {
|
|
351
|
+
imports.push({
|
|
352
|
+
specifiers: [{ imported: "createFileRoute" }],
|
|
353
|
+
source: this.targetTemplate.fullPkg
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
if (config.verboseFileRoutes === false) {
|
|
357
|
+
const typeImport = {
|
|
358
|
+
specifiers: [],
|
|
359
|
+
source: this.targetTemplate.fullPkg,
|
|
360
|
+
importKind: "type"
|
|
351
361
|
};
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
362
|
+
if (sortedRouteNodes.some(
|
|
363
|
+
(d) => utils.isRouteNodeValidForAugmentation(d) && d._fsRouteType !== "lazy"
|
|
364
|
+
)) {
|
|
365
|
+
typeImport.specifiers.push({ imported: "CreateFileRoute" });
|
|
356
366
|
}
|
|
357
|
-
|
|
358
|
-
(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
(d) => d
|
|
362
|
-
]);
|
|
363
|
-
const pluginConfig = plugin.config({
|
|
364
|
-
generator: this,
|
|
365
|
-
rootRouteNode,
|
|
366
|
-
sortedRouteNodes
|
|
367
|
-
});
|
|
368
|
-
const routeImports2 = sortedRouteNodes.filter((d) => !d.isVirtual).flatMap((node) => getImportForRouteNode(node, exportName) ?? []);
|
|
369
|
-
const hasMatchingRouteFiles = acc.routeNodes.length > 0 || rootRouteNode.exports?.includes(exportName);
|
|
370
|
-
const virtualRouteNodes = sortedRouteNodes.filter((d) => d.isVirtual).map((node) => {
|
|
371
|
-
return `const ${node.variableName}${exportName}Import = ${plugin.createVirtualRouteCode({ node })}`;
|
|
372
|
-
});
|
|
373
|
-
if (!rootRouteNode.exports?.includes(exportName) && pluginConfig.virtualRootRoute) {
|
|
374
|
-
virtualRouteNodes.unshift(
|
|
375
|
-
`const ${rootRouteNode.variableName}${exportName}Import = ${plugin.createRootRouteCode()}`
|
|
376
|
-
);
|
|
367
|
+
if (sortedRouteNodes.some(
|
|
368
|
+
(node) => acc.routePiecesByPath[node.routePath]?.lazy && utils.isRouteNodeValidForAugmentation(node)
|
|
369
|
+
)) {
|
|
370
|
+
typeImport.specifiers.push({ imported: "CreateLazyFileRoute" });
|
|
377
371
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
[
|
|
397
|
-
`const ${node.variableName}${exportName} = ${node.variableName}${exportName}Import.update({
|
|
372
|
+
if (typeImport.specifiers.length > 0) {
|
|
373
|
+
typeImport.specifiers.push({ imported: "FileRoutesByPath" });
|
|
374
|
+
imports.push(typeImport);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const routeTreeConfig = utils.buildRouteTreeConfig(
|
|
378
|
+
acc.routeTree,
|
|
379
|
+
config.disableTypes
|
|
380
|
+
);
|
|
381
|
+
const createUpdateRoutes = sortedRouteNodes.map((node) => {
|
|
382
|
+
const loaderNode = acc.routePiecesByPath[node.routePath]?.loader;
|
|
383
|
+
const componentNode = acc.routePiecesByPath[node.routePath]?.component;
|
|
384
|
+
const errorComponentNode = acc.routePiecesByPath[node.routePath]?.errorComponent;
|
|
385
|
+
const pendingComponentNode = acc.routePiecesByPath[node.routePath]?.pendingComponent;
|
|
386
|
+
const lazyComponentNode = acc.routePiecesByPath[node.routePath]?.lazy;
|
|
387
|
+
return [
|
|
388
|
+
[
|
|
389
|
+
`const ${node.variableName}Route = ${node.variableName}RouteImport.update({
|
|
398
390
|
${[
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}${
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
)
|
|
415
|
-
)}'), 'loader') })` : "",
|
|
416
|
-
componentNode || errorComponentNode || pendingComponentNode ? `.update({
|
|
391
|
+
`id: '${node.path}'`,
|
|
392
|
+
!node.isNonPath ? `path: '${node.cleanedPath}'` : void 0,
|
|
393
|
+
`getParentRoute: () => ${utils.findParent(node)}`
|
|
394
|
+
].filter(Boolean).join(",")}
|
|
395
|
+
}${config.disableTypes ? "" : "as any"})`,
|
|
396
|
+
loaderNode ? `.updateLoader({ loader: lazyFn(() => import('./${utils.replaceBackslash(
|
|
397
|
+
utils.removeExt(
|
|
398
|
+
path.relative(
|
|
399
|
+
path.dirname(config.generatedRouteTree),
|
|
400
|
+
path.resolve(config.routesDirectory, loaderNode.filePath)
|
|
401
|
+
),
|
|
402
|
+
config.addExtensions
|
|
403
|
+
)
|
|
404
|
+
)}'), 'loader') })` : "",
|
|
405
|
+
componentNode || errorComponentNode || pendingComponentNode ? `.update({
|
|
417
406
|
${[
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
utils.removeExt(
|
|
424
|
-
path.relative(
|
|
425
|
-
path.dirname(this.config.generatedRouteTree),
|
|
426
|
-
path.resolve(
|
|
427
|
-
this.config.routesDirectory,
|
|
428
|
-
d[1].filePath
|
|
429
|
-
)
|
|
430
|
-
),
|
|
431
|
-
this.config.addExtensions
|
|
432
|
-
)
|
|
433
|
-
)}'), '${d[0]}')`;
|
|
434
|
-
}).join("\n,")}
|
|
435
|
-
})` : "",
|
|
436
|
-
lazyComponentNode ? `.lazy(() => import('./${utils.replaceBackslash(
|
|
407
|
+
["component", componentNode],
|
|
408
|
+
["errorComponent", errorComponentNode],
|
|
409
|
+
["pendingComponent", pendingComponentNode]
|
|
410
|
+
].filter((d) => d[1]).map((d) => {
|
|
411
|
+
return `${d[0]}: lazyRouteComponent(() => import('./${utils.replaceBackslash(
|
|
437
412
|
utils.removeExt(
|
|
438
413
|
path.relative(
|
|
439
|
-
path.dirname(
|
|
440
|
-
path.resolve(
|
|
441
|
-
this.config.routesDirectory,
|
|
442
|
-
lazyComponentNode.filePath
|
|
443
|
-
)
|
|
414
|
+
path.dirname(config.generatedRouteTree),
|
|
415
|
+
path.resolve(config.routesDirectory, d[1].filePath)
|
|
444
416
|
),
|
|
445
|
-
|
|
417
|
+
config.addExtensions
|
|
446
418
|
)
|
|
447
|
-
)}')
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
419
|
+
)}'), '${d[0]}')`;
|
|
420
|
+
}).join("\n,")}
|
|
421
|
+
})` : "",
|
|
422
|
+
lazyComponentNode ? `.lazy(() => import('./${utils.replaceBackslash(
|
|
423
|
+
utils.removeExt(
|
|
424
|
+
path.relative(
|
|
425
|
+
path.dirname(config.generatedRouteTree),
|
|
426
|
+
path.resolve(
|
|
427
|
+
config.routesDirectory,
|
|
428
|
+
lazyComponentNode.filePath
|
|
429
|
+
)
|
|
430
|
+
),
|
|
431
|
+
config.addExtensions
|
|
432
|
+
)
|
|
433
|
+
)}').then((d) => d.Route))` : ""
|
|
434
|
+
].join("")
|
|
435
|
+
].join("\n\n");
|
|
436
|
+
});
|
|
437
|
+
let fileRoutesByPathInterface = "";
|
|
438
|
+
let fileRoutesByFullPath = "";
|
|
439
|
+
if (!config.disableTypes) {
|
|
440
|
+
fileRoutesByFullPath = [
|
|
441
|
+
`export interface FileRoutesByFullPath {
|
|
456
442
|
${[...utils.createRouteNodesByFullPath(acc.routeNodes).entries()].filter(([fullPath]) => fullPath).map(([fullPath, routeNode]) => {
|
|
457
|
-
|
|
458
|
-
|
|
443
|
+
return `'${fullPath}': typeof ${utils.getResolvedRouteNodeVariableName(routeNode)}`;
|
|
444
|
+
})}
|
|
459
445
|
}`,
|
|
460
|
-
|
|
446
|
+
`export interface FileRoutesByTo {
|
|
461
447
|
${[...utils.createRouteNodesByTo(acc.routeNodes).entries()].filter(([to]) => to).map(([to, routeNode]) => {
|
|
462
|
-
|
|
463
|
-
|
|
448
|
+
return `'${to}': typeof ${utils.getResolvedRouteNodeVariableName(routeNode)}`;
|
|
449
|
+
})}
|
|
464
450
|
}`,
|
|
465
|
-
|
|
466
|
-
'${routerCore.rootRouteId}': typeof
|
|
451
|
+
`export interface FileRoutesById {
|
|
452
|
+
'${routerCore.rootRouteId}': typeof rootRouteImport,
|
|
467
453
|
${[...utils.createRouteNodesById(acc.routeNodes).entries()].map(([id, routeNode]) => {
|
|
468
|
-
|
|
469
|
-
|
|
454
|
+
return `'${id}': typeof ${utils.getResolvedRouteNodeVariableName(routeNode)}`;
|
|
455
|
+
})}
|
|
470
456
|
}`,
|
|
471
|
-
|
|
472
|
-
|
|
457
|
+
`export interface FileRouteTypes {
|
|
458
|
+
fileRoutesByFullPath: FileRoutesByFullPath
|
|
473
459
|
fullPaths: ${acc.routeNodes.length > 0 ? [...utils.createRouteNodesByFullPath(acc.routeNodes).keys()].filter((fullPath) => fullPath).map((fullPath) => `'${fullPath}'`).join("|") : "never"}
|
|
474
|
-
|
|
460
|
+
fileRoutesByTo: FileRoutesByTo
|
|
475
461
|
to: ${acc.routeNodes.length > 0 ? [...utils.createRouteNodesByTo(acc.routeNodes).keys()].filter((to) => to).map((to) => `'${to}'`).join("|") : "never"}
|
|
476
462
|
id: ${[`'${routerCore.rootRouteId}'`, ...[...utils.createRouteNodesById(acc.routeNodes).keys()].map((id) => `'${id}'`)].join("|")}
|
|
477
|
-
|
|
463
|
+
fileRoutesById: FileRoutesById
|
|
478
464
|
}`,
|
|
479
|
-
|
|
480
|
-
${acc.routeTree.map((child) => `${child.variableName}
|
|
465
|
+
`export interface RootRouteChildren {
|
|
466
|
+
${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${utils.getResolvedRouteNodeVariableName(child)}`).join(",")}
|
|
481
467
|
}`
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
let routeTree = "";
|
|
493
|
-
if (hasMatchingRouteFiles) {
|
|
494
|
-
routeTree = [
|
|
495
|
-
`const root${exportName}Children${this.config.disableTypes ? "" : `: Root${exportName}Children`} = {
|
|
468
|
+
].join("\n");
|
|
469
|
+
fileRoutesByPathInterface = utils.buildFileRoutesByPathInterface({
|
|
470
|
+
module: this.targetTemplate.fullPkg,
|
|
471
|
+
interfaceName: "FileRoutesByPath",
|
|
472
|
+
routeNodes: sortedRouteNodes
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
const routeTree = [
|
|
476
|
+
`const rootRouteChildren${config.disableTypes ? "" : `: RootRouteChildren`} = {
|
|
496
477
|
${acc.routeTree.map(
|
|
497
|
-
|
|
498
|
-
|
|
478
|
+
(child) => `${child.variableName}Route: ${utils.getResolvedRouteNodeVariableName(child)}`
|
|
479
|
+
).join(",")}
|
|
499
480
|
}`,
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
virtualRouteNodes,
|
|
508
|
-
routeTreeConfig,
|
|
509
|
-
routeTree,
|
|
510
|
-
imports,
|
|
511
|
-
createUpdateRoutes,
|
|
512
|
-
fileRoutesByFullPathPerPlugin,
|
|
513
|
-
fileRoutesByPathInterfacePerPlugin
|
|
514
|
-
};
|
|
515
|
-
};
|
|
516
|
-
const routeTrees = this.pluginsWithTransform.map((plugin) => ({
|
|
517
|
-
exportName: plugin.transformPlugin.exportName,
|
|
518
|
-
...buildRouteTreeForExport(plugin)
|
|
519
|
-
}));
|
|
520
|
-
this.plugins.map((plugin) => {
|
|
521
|
-
return plugin.onRouteTreesChanged?.({
|
|
522
|
-
routeTrees,
|
|
523
|
-
rootRouteNode,
|
|
524
|
-
generator: this
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
let mergedImports = utils.mergeImportDeclarations(
|
|
528
|
-
routeTrees.flatMap((d) => d.imports)
|
|
481
|
+
`export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)${config.disableTypes ? "" : `._addFileTypes<FileRouteTypes>()`}`
|
|
482
|
+
].join("\n");
|
|
483
|
+
utils.checkRouteFullPathUniqueness(
|
|
484
|
+
sortedRouteNodes.filter(
|
|
485
|
+
(d) => d.children === void 0 && "lazy" !== d._fsRouteType
|
|
486
|
+
),
|
|
487
|
+
config
|
|
529
488
|
);
|
|
530
|
-
|
|
489
|
+
let mergedImports = utils.mergeImportDeclarations(imports);
|
|
490
|
+
if (config.disableTypes) {
|
|
531
491
|
mergedImports = mergedImports.filter((d) => d.importKind !== "type");
|
|
532
492
|
}
|
|
533
493
|
const importStatements = mergedImports.map(utils.buildImportString);
|
|
534
494
|
let moduleAugmentation = "";
|
|
535
|
-
if (
|
|
536
|
-
moduleAugmentation = routeFileResult.map((
|
|
495
|
+
if (config.verboseFileRoutes === false && !config.disableTypes) {
|
|
496
|
+
moduleAugmentation = opts.routeFileResult.map((node) => {
|
|
537
497
|
const getModuleDeclaration = (routeNode) => {
|
|
538
498
|
if (!utils.isRouteNodeValidForAugmentation(routeNode)) {
|
|
539
499
|
return "";
|
|
540
500
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
501
|
+
let moduleAugmentation2 = "";
|
|
502
|
+
if (routeNode._fsRouteType === "lazy") {
|
|
503
|
+
moduleAugmentation2 = `const createLazyFileRoute: CreateLazyFileRoute<FileRoutesByPath['${routeNode.routePath}']['preLoaderRoute']>`;
|
|
504
|
+
} else {
|
|
505
|
+
moduleAugmentation2 = `const createFileRoute: CreateFileRoute<'${routeNode.routePath}',
|
|
506
|
+
FileRoutesByPath['${routeNode.routePath}']['parentRoute'],
|
|
507
|
+
FileRoutesByPath['${routeNode.routePath}']['id'],
|
|
508
|
+
FileRoutesByPath['${routeNode.routePath}']['path'],
|
|
509
|
+
FileRoutesByPath['${routeNode.routePath}']['fullPath']
|
|
510
|
+
>
|
|
511
|
+
`;
|
|
512
|
+
}
|
|
513
|
+
return `declare module './${utils.getImportPath(routeNode, config, this.generatedRouteTreePath)}' {
|
|
547
514
|
${moduleAugmentation2}
|
|
548
515
|
}`;
|
|
549
516
|
};
|
|
550
517
|
return getModuleDeclaration(node);
|
|
551
518
|
}).join("\n");
|
|
552
519
|
}
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
520
|
+
const rootRouteImport = utils.getImportForRouteNode(
|
|
521
|
+
rootRouteNode,
|
|
522
|
+
config,
|
|
523
|
+
this.generatedRouteTreePath,
|
|
524
|
+
this.root
|
|
556
525
|
);
|
|
557
|
-
|
|
558
|
-
|
|
526
|
+
routeImports.unshift(rootRouteImport);
|
|
527
|
+
let footer = [];
|
|
528
|
+
if (config.routeTreeFileFooter) {
|
|
529
|
+
if (Array.isArray(config.routeTreeFileFooter)) {
|
|
530
|
+
footer = config.routeTreeFileFooter;
|
|
531
|
+
} else {
|
|
532
|
+
footer = config.routeTreeFileFooter();
|
|
533
|
+
}
|
|
559
534
|
}
|
|
560
535
|
const routeTreeContent = [
|
|
561
|
-
...
|
|
536
|
+
...config.routeTreeFileHeader,
|
|
562
537
|
`// This file was automatically generated by TanStack Router.
|
|
563
538
|
// You should NOT make any changes in this file as it will be overwritten.
|
|
564
539
|
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.`,
|
|
565
540
|
[...importStatements].join("\n"),
|
|
566
541
|
utils.mergeImportDeclarations(routeImports).map(utils.buildImportString).join("\n"),
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
542
|
+
virtualRouteNodes.join("\n"),
|
|
543
|
+
createUpdateRoutes.join("\n"),
|
|
544
|
+
fileRoutesByFullPath,
|
|
545
|
+
fileRoutesByPathInterface,
|
|
571
546
|
moduleAugmentation,
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
...
|
|
547
|
+
routeTreeConfig.join("\n"),
|
|
548
|
+
routeTree,
|
|
549
|
+
...footer
|
|
575
550
|
].filter(Boolean).join("\n\n");
|
|
576
|
-
return
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
path.relative(
|
|
582
|
-
path.dirname(this.config.generatedRouteTree),
|
|
583
|
-
path.resolve(this.config.routesDirectory, node.filePath)
|
|
584
|
-
),
|
|
585
|
-
this.config.addExtensions
|
|
586
|
-
)
|
|
587
|
-
);
|
|
551
|
+
return {
|
|
552
|
+
routeTreeContent,
|
|
553
|
+
routeTree: acc.routeTree,
|
|
554
|
+
routeNodes: acc.routeNodes
|
|
555
|
+
};
|
|
588
556
|
}
|
|
589
557
|
async processRouteNodeFile(node) {
|
|
590
558
|
const result = await this.isRouteFileCacheFresh(node);
|
|
591
559
|
if (result.status === "fresh") {
|
|
592
|
-
node.exports = result.cacheEntry.exports;
|
|
593
560
|
return {
|
|
594
|
-
node,
|
|
595
|
-
shouldWriteTree:
|
|
561
|
+
node: result.cacheEntry.node,
|
|
562
|
+
shouldWriteTree: false,
|
|
596
563
|
cacheEntry: result.cacheEntry
|
|
597
564
|
};
|
|
598
565
|
}
|
|
566
|
+
const previousCacheEntry = result.cacheEntry;
|
|
599
567
|
const existingRouteFile = await this.fs.readFile(node.fullPath);
|
|
600
568
|
if (existingRouteFile === "file-not-existing") {
|
|
601
569
|
throw new Error(`⚠️ File ${node.fullPath} does not exist`);
|
|
@@ -603,13 +571,15 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
603
571
|
const updatedCacheEntry = {
|
|
604
572
|
fileContent: existingRouteFile.fileContent,
|
|
605
573
|
mtimeMs: existingRouteFile.stat.mtimeMs,
|
|
606
|
-
|
|
607
|
-
|
|
574
|
+
routeId: node.routePath ?? "$$TSR_NO_ROUTE_PATH_ASSIGNED$$",
|
|
575
|
+
node
|
|
608
576
|
};
|
|
609
577
|
const escapedRoutePath = node.routePath?.replaceAll("$", "$$") ?? "";
|
|
610
578
|
let shouldWriteRouteFile = false;
|
|
579
|
+
let shouldWriteTree = false;
|
|
611
580
|
if (!existingRouteFile.fileContent) {
|
|
612
581
|
shouldWriteRouteFile = true;
|
|
582
|
+
shouldWriteTree = true;
|
|
613
583
|
if (node._fsRouteType === "lazy") {
|
|
614
584
|
const tLazyRouteTemplate = this.targetTemplate.lazyRoute;
|
|
615
585
|
updatedCacheEntry.fileContent = await template.fillTemplate(
|
|
@@ -622,7 +592,6 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
622
592
|
tsrExportEnd: tLazyRouteTemplate.imports.tsrExportEnd()
|
|
623
593
|
}
|
|
624
594
|
);
|
|
625
|
-
updatedCacheEntry.exports = ["Route"];
|
|
626
595
|
} else if (
|
|
627
596
|
// Creating a new normal route file
|
|
628
597
|
["layout", "static"].some(
|
|
@@ -645,31 +614,37 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
645
614
|
tsrExportEnd: tRouteTemplate.imports.tsrExportEnd()
|
|
646
615
|
}
|
|
647
616
|
);
|
|
648
|
-
updatedCacheEntry.exports = ["Route"];
|
|
649
617
|
} else {
|
|
650
618
|
return null;
|
|
651
619
|
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
620
|
+
}
|
|
621
|
+
const transformResult = await transform.transform({
|
|
622
|
+
source: updatedCacheEntry.fileContent,
|
|
623
|
+
ctx: {
|
|
624
|
+
target: this.config.target,
|
|
625
|
+
routeId: escapedRoutePath,
|
|
626
|
+
lazy: node._fsRouteType === "lazy",
|
|
627
|
+
verboseFileRoutes: !(this.config.verboseFileRoutes === false)
|
|
628
|
+
},
|
|
629
|
+
node
|
|
630
|
+
});
|
|
631
|
+
if (transformResult.result === "no-route-export") {
|
|
632
|
+
this.logger.warn(
|
|
633
|
+
`Route file "${node.fullPath}" does not contain any route piece. This is likely a mistake.`
|
|
634
|
+
);
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
if (transformResult.result === "error") {
|
|
638
|
+
throw new Error(
|
|
639
|
+
`Error transforming route file ${node.fullPath}: ${transformResult.error}`
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
if (transformResult.result === "modified") {
|
|
643
|
+
updatedCacheEntry.fileContent = transformResult.output;
|
|
644
|
+
shouldWriteRouteFile = true;
|
|
645
|
+
}
|
|
646
|
+
for (const plugin of this.plugins) {
|
|
647
|
+
plugin.afterTransform?.({ node, prevNode: previousCacheEntry?.node });
|
|
673
648
|
}
|
|
674
649
|
if (shouldWriteRouteFile) {
|
|
675
650
|
const stats = await this.safeFileWrite({
|
|
@@ -683,11 +658,6 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
683
658
|
updatedCacheEntry.mtimeMs = stats.mtimeMs;
|
|
684
659
|
}
|
|
685
660
|
this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry);
|
|
686
|
-
node.exports = updatedCacheEntry.exports;
|
|
687
|
-
const shouldWriteTree = !routerCore.deepEqual(
|
|
688
|
-
result.cacheEntry?.exports,
|
|
689
|
-
updatedCacheEntry.exports
|
|
690
|
-
);
|
|
691
661
|
return {
|
|
692
662
|
node,
|
|
693
663
|
shouldWriteTree,
|
|
@@ -771,7 +741,6 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
771
741
|
this.routeNodeShadowCache.set(node.fullPath, fileChangedCache.cacheEntry);
|
|
772
742
|
return {
|
|
773
743
|
status: "fresh",
|
|
774
|
-
exportsChanged: false,
|
|
775
744
|
cacheEntry: fileChangedCache.cacheEntry
|
|
776
745
|
};
|
|
777
746
|
}
|
|
@@ -788,19 +757,8 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
788
757
|
}
|
|
789
758
|
if (shadowCacheFileChange.result === false) {
|
|
790
759
|
if (fileChangedCache.result === true) {
|
|
791
|
-
if (routerCore.deepEqual(
|
|
792
|
-
fileChangedCache.cacheEntry.exports,
|
|
793
|
-
shadowCacheFileChange.cacheEntry.exports
|
|
794
|
-
)) {
|
|
795
|
-
return {
|
|
796
|
-
status: "fresh",
|
|
797
|
-
exportsChanged: false,
|
|
798
|
-
cacheEntry: shadowCacheFileChange.cacheEntry
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
760
|
return {
|
|
802
761
|
status: "fresh",
|
|
803
|
-
exportsChanged: true,
|
|
804
762
|
cacheEntry: shadowCacheFileChange.cacheEntry
|
|
805
763
|
};
|
|
806
764
|
}
|
|
@@ -815,9 +773,7 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
815
773
|
async handleRootNode(node) {
|
|
816
774
|
const result = await this.isRouteFileCacheFresh(node);
|
|
817
775
|
if (result.status === "fresh") {
|
|
818
|
-
node.exports = result.cacheEntry.exports;
|
|
819
776
|
this.routeNodeShadowCache.set(node.fullPath, result.cacheEntry);
|
|
820
|
-
return result.exportsChanged;
|
|
821
777
|
}
|
|
822
778
|
const rootNodeFile = await this.fs.readFile(node.fullPath);
|
|
823
779
|
if (rootNodeFile === "file-not-existing") {
|
|
@@ -826,8 +782,8 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
826
782
|
const updatedCacheEntry = {
|
|
827
783
|
fileContent: rootNodeFile.fileContent,
|
|
828
784
|
mtimeMs: rootNodeFile.stat.mtimeMs,
|
|
829
|
-
|
|
830
|
-
|
|
785
|
+
routeId: node.routePath ?? "$$TSR_NO_ROOT_ROUTE_PATH_ASSIGNED$$",
|
|
786
|
+
node
|
|
831
787
|
};
|
|
832
788
|
if (!rootNodeFile.fileContent) {
|
|
833
789
|
const rootTemplate = this.targetTemplate.rootRoute;
|
|
@@ -853,23 +809,13 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
853
809
|
updatedCacheEntry.fileContent = rootRouteContent;
|
|
854
810
|
updatedCacheEntry.mtimeMs = stats.mtimeMs;
|
|
855
811
|
}
|
|
856
|
-
const rootRouteExports = [];
|
|
857
|
-
for (const plugin of this.pluginsWithTransform) {
|
|
858
|
-
const exportName = plugin.transformPlugin.exportName;
|
|
859
|
-
if (rootNodeFile.fileContent.includes(`export const ${exportName}`)) {
|
|
860
|
-
rootRouteExports.push(exportName);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
updatedCacheEntry.exports = rootRouteExports;
|
|
864
|
-
node.exports = rootRouteExports;
|
|
865
812
|
this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry);
|
|
866
|
-
const shouldWriteTree = !routerCore.deepEqual(
|
|
867
|
-
result.cacheEntry?.exports,
|
|
868
|
-
rootRouteExports
|
|
869
|
-
);
|
|
870
|
-
return shouldWriteTree;
|
|
871
813
|
}
|
|
872
|
-
|
|
814
|
+
async getCrawlingResult() {
|
|
815
|
+
await this.runPromise;
|
|
816
|
+
return this.crawlingResult;
|
|
817
|
+
}
|
|
818
|
+
static handleNode(node, acc) {
|
|
873
819
|
utils.resetRegex(this.routeGroupPatternRegex);
|
|
874
820
|
let parentRoute = utils.hasParentRoute(acc.routeNodes, node, node.routePath);
|
|
875
821
|
if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {
|
|
@@ -983,6 +929,8 @@ ${acc.routeTree.map((child) => `${child.variableName}${exportName}: typeof ${uti
|
|
|
983
929
|
}
|
|
984
930
|
return false;
|
|
985
931
|
}
|
|
986
|
-
}
|
|
932
|
+
};
|
|
933
|
+
_Generator.routeGroupPatternRegex = /\(.+\)/g;
|
|
934
|
+
let Generator = _Generator;
|
|
987
935
|
exports.Generator = Generator;
|
|
988
936
|
//# sourceMappingURL=generator.cjs.map
|