@tanstack/router-generator 1.166.8 → 1.166.10
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/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/cjs/config.cjs +111 -147
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +224 -303
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/filesystem/physical/rootPathId.cjs +5 -4
- package/dist/cjs/filesystem/physical/rootPathId.cjs.map +1 -1
- package/dist/cjs/filesystem/virtual/config.cjs +32 -30
- package/dist/cjs/filesystem/virtual/config.cjs.map +1 -1
- package/dist/cjs/filesystem/virtual/getRouteNodes.cjs +164 -209
- package/dist/cjs/filesystem/virtual/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/filesystem/virtual/loadConfigFile.cjs +9 -8
- package/dist/cjs/filesystem/virtual/loadConfigFile.cjs.map +1 -1
- package/dist/cjs/generator.cjs +766 -1106
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/index.cjs +32 -34
- package/dist/cjs/logger.cjs +28 -34
- package/dist/cjs/logger.cjs.map +1 -1
- package/dist/cjs/template.cjs +144 -151
- package/dist/cjs/template.cjs.map +1 -1
- package/dist/cjs/transform/transform.cjs +287 -426
- package/dist/cjs/transform/transform.cjs.map +1 -1
- package/dist/cjs/transform/utils.cjs +31 -33
- package/dist/cjs/transform/utils.cjs.map +1 -1
- package/dist/cjs/utils.cjs +534 -544
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/validate-route-params.cjs +66 -51
- package/dist/cjs/validate-route-params.cjs.map +1 -1
- package/dist/esm/config.js +106 -147
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js +220 -286
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/dist/esm/filesystem/physical/rootPathId.js +6 -5
- package/dist/esm/filesystem/physical/rootPathId.js.map +1 -1
- package/dist/esm/filesystem/virtual/config.js +31 -30
- package/dist/esm/filesystem/virtual/config.js.map +1 -1
- package/dist/esm/filesystem/virtual/getRouteNodes.js +161 -208
- package/dist/esm/filesystem/virtual/getRouteNodes.js.map +1 -1
- package/dist/esm/filesystem/virtual/loadConfigFile.js +7 -7
- package/dist/esm/filesystem/virtual/loadConfigFile.js.map +1 -1
- package/dist/esm/generator.js +756 -1083
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/index.js +4 -31
- package/dist/esm/logger.js +29 -35
- package/dist/esm/logger.js.map +1 -1
- package/dist/esm/template.js +144 -152
- package/dist/esm/template.js.map +1 -1
- package/dist/esm/transform/transform.js +285 -425
- package/dist/esm/transform/transform.js.map +1 -1
- package/dist/esm/transform/utils.js +31 -33
- package/dist/esm/transform/utils.js.map +1 -1
- package/dist/esm/utils.js +529 -564
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/validate-route-params.js +67 -52
- package/dist/esm/validate-route-params.js.map +1 -1
- package/package.json +5 -5
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/esm/index.js.map +0 -1
package/dist/cjs/utils.cjs
CHANGED
|
@@ -1,618 +1,613 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return parent;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Check if a route exists at the given path.
|
|
63
|
-
*/
|
|
64
|
-
has(routePath) {
|
|
65
|
-
return this.prefixToRoute.has(routePath);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Get a route by exact path.
|
|
69
|
-
*/
|
|
70
|
-
get(routePath) {
|
|
71
|
-
return this.prefixToRoute.get(routePath);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
1
|
+
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
require("./filesystem/physical/rootPathId.cjs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
node_path = require_runtime.__toESM(node_path);
|
|
5
|
+
let node_fs_promises = require("node:fs/promises");
|
|
6
|
+
node_fs_promises = require_runtime.__toESM(node_fs_promises);
|
|
7
|
+
let prettier = require("prettier");
|
|
8
|
+
prettier = require_runtime.__toESM(prettier);
|
|
9
|
+
//#region src/utils.ts
|
|
10
|
+
/**
|
|
11
|
+
* Prefix map for O(1) parent route lookups.
|
|
12
|
+
* Maps each route path prefix to the route node that owns that prefix.
|
|
13
|
+
* Enables finding longest matching parent without linear search.
|
|
14
|
+
*/
|
|
15
|
+
var RoutePrefixMap = class {
|
|
16
|
+
constructor(routes) {
|
|
17
|
+
this.prefixToRoute = /* @__PURE__ */ new Map();
|
|
18
|
+
this.layoutRoutes = [];
|
|
19
|
+
for (const route of routes) {
|
|
20
|
+
if (!route.routePath || route.routePath === `/__root`) continue;
|
|
21
|
+
if (route._fsRouteType === "lazy" || route._fsRouteType === "loader" || route._fsRouteType === "component" || route._fsRouteType === "pendingComponent" || route._fsRouteType === "errorComponent" || route._fsRouteType === "notFoundComponent") continue;
|
|
22
|
+
this.prefixToRoute.set(route.routePath, route);
|
|
23
|
+
if (route._fsRouteType === "pathless_layout" || route._fsRouteType === "layout" || route._fsRouteType === "__root") this.layoutRoutes.push(route);
|
|
24
|
+
}
|
|
25
|
+
this.layoutRoutes.sort((a, b) => (b.routePath?.length ?? 0) - (a.routePath?.length ?? 0));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Find the longest matching parent route for a given path.
|
|
29
|
+
* O(k) where k is the number of path segments, not O(n) routes.
|
|
30
|
+
*/
|
|
31
|
+
findParent(routePath) {
|
|
32
|
+
if (!routePath || routePath === "/") return null;
|
|
33
|
+
let searchPath = routePath;
|
|
34
|
+
while (searchPath.length > 0) {
|
|
35
|
+
const lastSlash = searchPath.lastIndexOf("/");
|
|
36
|
+
if (lastSlash <= 0) break;
|
|
37
|
+
searchPath = searchPath.substring(0, lastSlash);
|
|
38
|
+
const parent = this.prefixToRoute.get(searchPath);
|
|
39
|
+
if (parent && parent.routePath !== routePath) return parent;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a route exists at the given path.
|
|
45
|
+
*/
|
|
46
|
+
has(routePath) {
|
|
47
|
+
return this.prefixToRoute.has(routePath);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get a route by exact path.
|
|
51
|
+
*/
|
|
52
|
+
get(routePath) {
|
|
53
|
+
return this.prefixToRoute.get(routePath);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
74
56
|
function multiSortBy(arr, accessors = [(d) => d]) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return path2 === "/" ? path2 : path2.replace(/^\/{1,}/, "");
|
|
113
|
-
}
|
|
114
|
-
function removeLeadingSlash(path2) {
|
|
115
|
-
return path2.replace(/^\//, "");
|
|
57
|
+
const len = arr.length;
|
|
58
|
+
const indexed = new Array(len);
|
|
59
|
+
for (let i = 0; i < len; i++) {
|
|
60
|
+
const item = arr[i];
|
|
61
|
+
const keys = new Array(accessors.length);
|
|
62
|
+
for (let j = 0; j < accessors.length; j++) keys[j] = accessors[j](item);
|
|
63
|
+
indexed[i] = {
|
|
64
|
+
item,
|
|
65
|
+
index: i,
|
|
66
|
+
keys
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
indexed.sort((a, b) => {
|
|
70
|
+
for (let j = 0; j < accessors.length; j++) {
|
|
71
|
+
const ao = a.keys[j];
|
|
72
|
+
const bo = b.keys[j];
|
|
73
|
+
if (typeof ao === "undefined") {
|
|
74
|
+
if (typeof bo === "undefined") continue;
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
if (ao === bo) continue;
|
|
78
|
+
return ao > bo ? 1 : -1;
|
|
79
|
+
}
|
|
80
|
+
return a.index - b.index;
|
|
81
|
+
});
|
|
82
|
+
const result = new Array(len);
|
|
83
|
+
for (let i = 0; i < len; i++) result[i] = indexed[i].item;
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
function cleanPath(path) {
|
|
87
|
+
return path.replace(/\/{2,}/g, "/");
|
|
88
|
+
}
|
|
89
|
+
function trimPathLeft(path) {
|
|
90
|
+
return path === "/" ? path : path.replace(/^\/{1,}/, "");
|
|
91
|
+
}
|
|
92
|
+
function removeLeadingSlash(path) {
|
|
93
|
+
return path.replace(/^\//, "");
|
|
116
94
|
}
|
|
117
95
|
function removeTrailingSlash(s) {
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
96
|
+
return s.replace(/\/$/, "");
|
|
97
|
+
}
|
|
98
|
+
var BRACKET_CONTENT_RE = /\[(.*?)\]/g;
|
|
99
|
+
var SPLIT_REGEX = /(?<!\[)\.(?!\])/g;
|
|
100
|
+
/**
|
|
101
|
+
* Characters that cannot be escaped in square brackets.
|
|
102
|
+
* These are characters that would cause issues in URLs or file systems.
|
|
103
|
+
*/
|
|
104
|
+
var DISALLOWED_ESCAPE_CHARS = new Set([
|
|
105
|
+
"/",
|
|
106
|
+
"\\",
|
|
107
|
+
"?",
|
|
108
|
+
"#",
|
|
109
|
+
":",
|
|
110
|
+
"*",
|
|
111
|
+
"<",
|
|
112
|
+
">",
|
|
113
|
+
"|",
|
|
114
|
+
"!",
|
|
115
|
+
"$",
|
|
116
|
+
"%"
|
|
135
117
|
]);
|
|
136
118
|
function determineInitialRoutePath(routePath) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
159
|
-
const final = cleanPath(`/${escapedParts.join("/")}`) || "";
|
|
160
|
-
return {
|
|
161
|
-
routePath: final,
|
|
162
|
-
originalRoutePath
|
|
163
|
-
};
|
|
164
|
-
}
|
|
119
|
+
const originalRoutePath = cleanPath(`/${(cleanPath(routePath) || "").split(SPLIT_REGEX).join("/")}`) || "";
|
|
120
|
+
return {
|
|
121
|
+
routePath: cleanPath(`/${routePath.split(SPLIT_REGEX).map((part) => {
|
|
122
|
+
let match;
|
|
123
|
+
while ((match = BRACKET_CONTENT_RE.exec(part)) !== null) {
|
|
124
|
+
const character = match[1];
|
|
125
|
+
if (character === void 0) continue;
|
|
126
|
+
if (DISALLOWED_ESCAPE_CHARS.has(character)) {
|
|
127
|
+
console.error(`Error: Disallowed character "${character}" found in square brackets in route path "${routePath}".\nYou cannot use any of the following characters in square brackets: ${Array.from(DISALLOWED_ESCAPE_CHARS).join(", ")}\nPlease remove and/or replace them.`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return part.replace(BRACKET_CONTENT_RE, "$1");
|
|
132
|
+
}).join("/")}`) || "",
|
|
133
|
+
originalRoutePath
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Checks if a segment is fully escaped (entirely wrapped in brackets with no nested brackets).
|
|
138
|
+
* E.g., "[index]" -> true, "[_layout]" -> true, "foo[.]bar" -> false, "index" -> false
|
|
139
|
+
*/
|
|
165
140
|
function isFullyEscapedSegment(originalSegment) {
|
|
166
|
-
|
|
167
|
-
}
|
|
141
|
+
return originalSegment.startsWith("[") && originalSegment.endsWith("]") && !originalSegment.slice(1, -1).includes("[") && !originalSegment.slice(1, -1).includes("]");
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Checks if the leading underscore in a segment is escaped.
|
|
145
|
+
* Returns true if:
|
|
146
|
+
* - Segment starts with [_] pattern: "[_]layout" -> "_layout"
|
|
147
|
+
* - Segment is fully escaped and content starts with _: "[_1nd3x]" -> "_1nd3x"
|
|
148
|
+
*/
|
|
168
149
|
function hasEscapedLeadingUnderscore(originalSegment) {
|
|
169
|
-
|
|
170
|
-
}
|
|
150
|
+
return originalSegment.startsWith("[_]") || originalSegment.startsWith("[_") && isFullyEscapedSegment(originalSegment);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Checks if the trailing underscore in a segment is escaped.
|
|
154
|
+
* Returns true if:
|
|
155
|
+
* - Segment ends with [_] pattern: "blog[_]" -> "blog_"
|
|
156
|
+
* - Segment is fully escaped and content ends with _: "[_r0ut3_]" -> "_r0ut3_"
|
|
157
|
+
*/
|
|
171
158
|
function hasEscapedTrailingUnderscore(originalSegment) {
|
|
172
|
-
|
|
159
|
+
return originalSegment.endsWith("[_]") || originalSegment.endsWith("_]") && isFullyEscapedSegment(originalSegment);
|
|
173
160
|
}
|
|
174
|
-
|
|
161
|
+
var backslashRegex = /\\/g;
|
|
175
162
|
function replaceBackslash(s) {
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
case "(":
|
|
197
|
-
return "";
|
|
198
|
-
// Removed since route groups use parentheses
|
|
199
|
-
case ")":
|
|
200
|
-
return "";
|
|
201
|
-
// Removed since route groups use parentheses
|
|
202
|
-
case " ":
|
|
203
|
-
return "";
|
|
204
|
-
// Remove spaces
|
|
205
|
-
default:
|
|
206
|
-
return `Char${char.charCodeAt(0)}`;
|
|
207
|
-
}
|
|
163
|
+
return s.replace(backslashRegex, "/");
|
|
164
|
+
}
|
|
165
|
+
var alphanumericRegex = /[a-zA-Z0-9_]/;
|
|
166
|
+
var splatSlashRegex = /\/\$\//g;
|
|
167
|
+
var trailingSplatRegex = /\$$/g;
|
|
168
|
+
var bracketSplatRegex = /\$\{\$\}/g;
|
|
169
|
+
var dollarSignRegex = /\$/g;
|
|
170
|
+
var splitPathRegex = /[/-]/g;
|
|
171
|
+
var leadingDigitRegex = /^(\d)/g;
|
|
172
|
+
var toVariableSafeChar = (char) => {
|
|
173
|
+
if (alphanumericRegex.test(char)) return char;
|
|
174
|
+
switch (char) {
|
|
175
|
+
case ".": return "Dot";
|
|
176
|
+
case "-": return "Dash";
|
|
177
|
+
case "@": return "At";
|
|
178
|
+
case "(": return "";
|
|
179
|
+
case ")": return "";
|
|
180
|
+
case " ": return "";
|
|
181
|
+
default: return `Char${char.charCodeAt(0)}`;
|
|
182
|
+
}
|
|
208
183
|
};
|
|
209
184
|
function routePathToVariable(routePath) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const underscoreStartEndRegex = /(^_|_$)/gi;
|
|
224
|
-
const underscoreSlashRegex = /(\/_|_\/)/gi;
|
|
185
|
+
const cleaned = removeUnderscores(routePath);
|
|
186
|
+
if (!cleaned) return "";
|
|
187
|
+
const parts = cleaned.replace(splatSlashRegex, "/splat/").replace(trailingSplatRegex, "splat").replace(bracketSplatRegex, "splat").replace(dollarSignRegex, "").split(splitPathRegex);
|
|
188
|
+
let result = "";
|
|
189
|
+
for (let i = 0; i < parts.length; i++) {
|
|
190
|
+
const part = parts[i];
|
|
191
|
+
const segment = i > 0 ? capitalize(part) : part;
|
|
192
|
+
for (let j = 0; j < segment.length; j++) result += toVariableSafeChar(segment[j]);
|
|
193
|
+
}
|
|
194
|
+
return result.replace(leadingDigitRegex, "R$1");
|
|
195
|
+
}
|
|
196
|
+
var underscoreStartEndRegex = /(^_|_$)/gi;
|
|
197
|
+
var underscoreSlashRegex = /(\/_|_\/)/gi;
|
|
225
198
|
function removeUnderscores(s) {
|
|
226
|
-
|
|
227
|
-
}
|
|
199
|
+
return s?.replace(underscoreStartEndRegex, "").replace(underscoreSlashRegex, "/");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Removes underscores from a path, but preserves underscores that were escaped
|
|
203
|
+
* in the original path (indicated by [_] syntax).
|
|
204
|
+
*
|
|
205
|
+
* @param routePath - The path with brackets removed
|
|
206
|
+
* @param originalPath - The original path that may contain [_] escape sequences
|
|
207
|
+
* @returns The path with non-escaped underscores removed
|
|
208
|
+
*/
|
|
228
209
|
function removeUnderscoresWithEscape(routePath, originalPath) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
210
|
+
if (!routePath) return "";
|
|
211
|
+
if (!originalPath) return removeUnderscores(routePath) ?? "";
|
|
212
|
+
const routeSegments = routePath.split("/");
|
|
213
|
+
const originalSegments = originalPath.split("/");
|
|
214
|
+
return routeSegments.map((segment, i) => {
|
|
215
|
+
const originalSegment = originalSegments[i] || "";
|
|
216
|
+
const leadingEscaped = hasEscapedLeadingUnderscore(originalSegment);
|
|
217
|
+
const trailingEscaped = hasEscapedTrailingUnderscore(originalSegment);
|
|
218
|
+
let result = segment;
|
|
219
|
+
if (result.startsWith("_") && !leadingEscaped) result = result.slice(1);
|
|
220
|
+
if (result.endsWith("_") && !trailingEscaped) result = result.slice(0, -1);
|
|
221
|
+
return result;
|
|
222
|
+
}).join("/");
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Removes layout segments (segments starting with underscore) from a path,
|
|
226
|
+
* but preserves segments where the underscore was escaped.
|
|
227
|
+
*
|
|
228
|
+
* @param routePath - The path with brackets removed
|
|
229
|
+
* @param originalPath - The original path that may contain [_] escape sequences
|
|
230
|
+
* @returns The path with non-escaped layout segments removed
|
|
231
|
+
*/
|
|
248
232
|
function removeLayoutSegmentsWithEscape(routePath = "/", originalPath) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
233
|
+
if (!originalPath) return removeLayoutSegments(routePath);
|
|
234
|
+
const routeSegments = routePath.split("/");
|
|
235
|
+
const originalSegments = originalPath.split("/");
|
|
236
|
+
return routeSegments.filter((segment, i) => {
|
|
237
|
+
return !isSegmentPathless(segment, originalSegments[i] || "");
|
|
238
|
+
}).join("/");
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Checks if a segment should be treated as a pathless/layout segment.
|
|
242
|
+
* A segment is pathless if it starts with underscore and the underscore is not escaped.
|
|
243
|
+
*
|
|
244
|
+
* @param segment - The segment from routePath (brackets removed)
|
|
245
|
+
* @param originalSegment - The segment from originalRoutePath (may contain brackets)
|
|
246
|
+
* @returns true if the segment is pathless (has non-escaped leading underscore)
|
|
247
|
+
*/
|
|
258
248
|
function isSegmentPathless(segment, originalSegment) {
|
|
259
|
-
|
|
260
|
-
|
|
249
|
+
if (!segment.startsWith("_")) return false;
|
|
250
|
+
return !hasEscapedLeadingUnderscore(originalSegment);
|
|
261
251
|
}
|
|
262
252
|
function escapeRegExp(s) {
|
|
263
|
-
|
|
253
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
264
254
|
}
|
|
265
255
|
function sanitizeTokenFlags(flags) {
|
|
266
|
-
|
|
267
|
-
|
|
256
|
+
if (!flags) return flags;
|
|
257
|
+
return flags.replace(/[gy]/g, "");
|
|
268
258
|
}
|
|
269
259
|
function createTokenRegex(token, opts) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
);
|
|
290
|
-
} catch (e) {
|
|
291
|
-
if (e instanceof SyntaxError) {
|
|
292
|
-
const pattern = typeof token === "string" ? token : token instanceof RegExp ? token.source : token.regex;
|
|
293
|
-
throw new Error(
|
|
294
|
-
`Invalid regex pattern in token config: "${pattern}". ${e.message}`
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
throw e;
|
|
298
|
-
}
|
|
260
|
+
if (token === void 0 || token === null) throw new Error(`createTokenRegex: token is ${token}. This usually means the config was not properly parsed with defaults.`);
|
|
261
|
+
try {
|
|
262
|
+
if (typeof token === "string") return opts.type === "segment" ? new RegExp(`^${escapeRegExp(token)}$`) : new RegExp(`[./]${escapeRegExp(token)}[.]`);
|
|
263
|
+
if (token instanceof RegExp) {
|
|
264
|
+
const flags = sanitizeTokenFlags(token.flags);
|
|
265
|
+
return opts.type === "segment" ? new RegExp(`^(?:${token.source})$`, flags) : new RegExp(`[./](?:${token.source})[.]`, flags);
|
|
266
|
+
}
|
|
267
|
+
if (typeof token === "object" && "regex" in token) {
|
|
268
|
+
const flags = sanitizeTokenFlags(token.flags);
|
|
269
|
+
return opts.type === "segment" ? new RegExp(`^(?:${token.regex})$`, flags) : new RegExp(`[./](?:${token.regex})[.]`, flags);
|
|
270
|
+
}
|
|
271
|
+
throw new Error(`createTokenRegex: invalid token type. Expected string, RegExp, or { regex, flags } object, got: ${typeof token}`);
|
|
272
|
+
} catch (e) {
|
|
273
|
+
if (e instanceof SyntaxError) {
|
|
274
|
+
const pattern = typeof token === "string" ? token : token instanceof RegExp ? token.source : token.regex;
|
|
275
|
+
throw new Error(`Invalid regex pattern in token config: "${pattern}". ${e.message}`);
|
|
276
|
+
}
|
|
277
|
+
throw e;
|
|
278
|
+
}
|
|
299
279
|
}
|
|
300
280
|
function isBracketWrappedSegment(segment) {
|
|
301
|
-
|
|
281
|
+
return segment.startsWith("[") && segment.endsWith("]");
|
|
302
282
|
}
|
|
303
283
|
function unwrapBracketWrappedSegment(segment) {
|
|
304
|
-
|
|
284
|
+
return isBracketWrappedSegment(segment) ? segment.slice(1, -1) : segment;
|
|
305
285
|
}
|
|
306
286
|
function capitalize(s) {
|
|
307
|
-
|
|
308
|
-
|
|
287
|
+
if (typeof s !== "string") return "";
|
|
288
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
309
289
|
}
|
|
310
290
|
function removeExt(d, addExtensions = false) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
291
|
+
if (typeof addExtensions === "string") {
|
|
292
|
+
const dotIndex = d.lastIndexOf(".");
|
|
293
|
+
if (dotIndex === -1) return d;
|
|
294
|
+
return d.substring(0, dotIndex) + addExtensions;
|
|
295
|
+
}
|
|
296
|
+
return addExtensions ? d : d.substring(0, d.lastIndexOf(".")) || d;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* This function writes to a file if the content is different.
|
|
300
|
+
*
|
|
301
|
+
* @param filepath The path to the file
|
|
302
|
+
* @param content Original content
|
|
303
|
+
* @param incomingContent New content
|
|
304
|
+
* @param callbacks Callbacks to run before and after writing
|
|
305
|
+
* @returns Whether the file was written
|
|
306
|
+
*/
|
|
318
307
|
async function writeIfDifferent(filepath, content, incomingContent, callbacks) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
308
|
+
if (content !== incomingContent) {
|
|
309
|
+
callbacks?.beforeWrite?.();
|
|
310
|
+
await node_fs_promises.writeFile(filepath, incomingContent);
|
|
311
|
+
callbacks?.afterWrite?.();
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* This function formats the source code using the default formatter (Prettier).
|
|
318
|
+
*
|
|
319
|
+
* @param source The content to format
|
|
320
|
+
* @param config The configuration object
|
|
321
|
+
* @returns The formatted content
|
|
322
|
+
*/
|
|
327
323
|
async function format(source, config) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
324
|
+
const prettierOptions = {
|
|
325
|
+
semi: config.semicolons,
|
|
326
|
+
singleQuote: config.quoteStyle === "single",
|
|
327
|
+
parser: "typescript"
|
|
328
|
+
};
|
|
329
|
+
return prettier.format(source, prettierOptions);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* This function resets the regex index to 0 so that it can be reused
|
|
333
|
+
* without having to create a new regex object or worry about the last
|
|
334
|
+
* state when using the global flag.
|
|
335
|
+
*
|
|
336
|
+
* @param regex The regex object to reset
|
|
337
|
+
* @returns
|
|
338
|
+
*/
|
|
335
339
|
function resetRegex(regex) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
regex.lastIndex = 0;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* This function checks if a file exists.
|
|
344
|
+
*
|
|
345
|
+
* @param file The path to the file
|
|
346
|
+
* @returns Whether the file exists
|
|
347
|
+
*/
|
|
339
348
|
async function checkFileExists(file) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
349
|
+
try {
|
|
350
|
+
await node_fs_promises.access(file, node_fs_promises.constants.F_OK);
|
|
351
|
+
return true;
|
|
352
|
+
} catch {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
var possiblyNestedRouteGroupPatternRegex = /\([^/]+\)\/?/g;
|
|
348
357
|
function removeGroups(s) {
|
|
349
|
-
|
|
350
|
-
}
|
|
358
|
+
return s.replace(possiblyNestedRouteGroupPatternRegex, "");
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Removes all segments from a given path that start with an underscore ('_').
|
|
362
|
+
*
|
|
363
|
+
* @param {string} routePath - The path from which to remove segments. Defaults to '/'.
|
|
364
|
+
* @returns {string} The path with all underscore-prefixed segments removed.
|
|
365
|
+
* @example
|
|
366
|
+
* removeLayoutSegments('/workspace/_auth/foo') // '/workspace/foo'
|
|
367
|
+
*/
|
|
351
368
|
function removeLayoutSegments(routePath = "/") {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
369
|
+
return routePath.split("/").filter((segment) => !segment.startsWith("_")).join("/");
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* The `node.path` is used as the `id` in the route definition.
|
|
373
|
+
* This function checks if the given node has a parent and if so, it determines the correct path for the given node.
|
|
374
|
+
* @param node - The node to determine the path for.
|
|
375
|
+
* @returns The correct path for the given node.
|
|
376
|
+
*/
|
|
356
377
|
function determineNodePath(node) {
|
|
357
|
-
|
|
358
|
-
}
|
|
378
|
+
return node.path = node.parent ? node.routePath?.replace(node.parent.routePath ?? "", "") || "/" : node.routePath;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Removes the last segment from a given path. Segments are considered to be separated by a '/'.
|
|
382
|
+
*
|
|
383
|
+
* @param {string} routePath - The path from which to remove the last segment. Defaults to '/'.
|
|
384
|
+
* @returns {string} The path with the last segment removed.
|
|
385
|
+
* @example
|
|
386
|
+
* removeLastSegmentFromPath('/workspace/_auth/foo') // '/workspace/_auth'
|
|
387
|
+
*/
|
|
359
388
|
function removeLastSegmentFromPath(routePath = "/") {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
389
|
+
const segments = routePath.split("/");
|
|
390
|
+
segments.pop();
|
|
391
|
+
return segments.join("/");
|
|
363
392
|
}
|
|
393
|
+
/**
|
|
394
|
+
* Find parent route using RoutePrefixMap for O(k) lookups instead of O(n).
|
|
395
|
+
*/
|
|
364
396
|
function hasParentRoute(prefixMap, node, routePathToCheck) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
397
|
+
if (!routePathToCheck || routePathToCheck === "/") return null;
|
|
398
|
+
return prefixMap.findParent(routePathToCheck);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Gets the final variable name for a route
|
|
402
|
+
*/
|
|
403
|
+
var getResolvedRouteNodeVariableName = (routeNode) => {
|
|
404
|
+
return routeNode.children?.length ? `${routeNode.variableName}RouteWithChildren` : `${routeNode.variableName}Route`;
|
|
372
405
|
};
|
|
406
|
+
/**
|
|
407
|
+
* Checks if a given RouteNode is valid for augmenting it with typing based on conditions.
|
|
408
|
+
* Also asserts that the RouteNode is defined.
|
|
409
|
+
*
|
|
410
|
+
* @param routeNode - The RouteNode to check.
|
|
411
|
+
* @returns A boolean indicating whether the RouteNode is defined.
|
|
412
|
+
*/
|
|
373
413
|
function isRouteNodeValidForAugmentation(routeNode) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return routeNode.cleanedPath?.replace(/\/$/, "") ?? "";
|
|
414
|
+
if (!routeNode || routeNode.isVirtual) return false;
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Infers the path for use by TS
|
|
419
|
+
*/
|
|
420
|
+
var inferPath = (routeNode) => {
|
|
421
|
+
if (routeNode.cleanedPath === "/") return routeNode.cleanedPath ?? "";
|
|
422
|
+
return routeNode.cleanedPath?.replace(/\/$/, "") ?? "";
|
|
384
423
|
};
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
)
|
|
394
|
-
);
|
|
395
|
-
if (fullPath === "") {
|
|
396
|
-
return "/";
|
|
397
|
-
}
|
|
398
|
-
const isIndexRoute = routeNode.routePath?.endsWith("/");
|
|
399
|
-
if (isIndexRoute) {
|
|
400
|
-
return fullPath;
|
|
401
|
-
}
|
|
402
|
-
return fullPath.replace(/\/$/, "");
|
|
424
|
+
/**
|
|
425
|
+
* Infers the full path for use by TS
|
|
426
|
+
*/
|
|
427
|
+
var inferFullPath = (routeNode) => {
|
|
428
|
+
const fullPath = removeGroups(removeUnderscoresWithEscape(removeLayoutSegmentsWithEscape(routeNode.routePath, routeNode.originalRoutePath), routeNode.originalRoutePath));
|
|
429
|
+
if (fullPath === "") return "/";
|
|
430
|
+
if (routeNode.routePath?.endsWith("/")) return fullPath;
|
|
431
|
+
return fullPath.replace(/\/$/, "");
|
|
403
432
|
};
|
|
404
|
-
|
|
405
|
-
|
|
433
|
+
var shouldPreferIndexRoute = (current, existing) => {
|
|
434
|
+
return existing.cleanedPath === "/" && current.cleanedPath !== "/";
|
|
406
435
|
};
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
436
|
+
/**
|
|
437
|
+
* Creates a map from fullPath to routeNode
|
|
438
|
+
*/
|
|
439
|
+
var createRouteNodesByFullPath = (routeNodes) => {
|
|
440
|
+
const map = /* @__PURE__ */ new Map();
|
|
441
|
+
for (const routeNode of routeNodes) {
|
|
442
|
+
const fullPath = inferFullPath(routeNode);
|
|
443
|
+
if (fullPath === "/" && map.has("/")) {
|
|
444
|
+
if (shouldPreferIndexRoute(routeNode, map.get("/"))) continue;
|
|
445
|
+
}
|
|
446
|
+
map.set(fullPath, routeNode);
|
|
447
|
+
}
|
|
448
|
+
return map;
|
|
420
449
|
};
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
450
|
+
/**
|
|
451
|
+
* Create a map from 'to' to a routeNode
|
|
452
|
+
*/
|
|
453
|
+
var createRouteNodesByTo = (routeNodes) => {
|
|
454
|
+
const map = /* @__PURE__ */ new Map();
|
|
455
|
+
for (const routeNode of dedupeBranchesAndIndexRoutes(routeNodes)) {
|
|
456
|
+
const to = inferTo(routeNode);
|
|
457
|
+
if (to === "/" && map.has("/")) {
|
|
458
|
+
if (shouldPreferIndexRoute(routeNode, map.get("/"))) continue;
|
|
459
|
+
}
|
|
460
|
+
map.set(to, routeNode);
|
|
461
|
+
}
|
|
462
|
+
return map;
|
|
434
463
|
};
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
464
|
+
/**
|
|
465
|
+
* Create a map from 'id' to a routeNode
|
|
466
|
+
*/
|
|
467
|
+
var createRouteNodesById = (routeNodes) => {
|
|
468
|
+
return new Map(routeNodes.map((routeNode) => {
|
|
469
|
+
return [routeNode.routePath ?? "", routeNode];
|
|
470
|
+
}));
|
|
442
471
|
};
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
472
|
+
/**
|
|
473
|
+
* Infers to path
|
|
474
|
+
*/
|
|
475
|
+
var inferTo = (routeNode) => {
|
|
476
|
+
const fullPath = inferFullPath(routeNode);
|
|
477
|
+
if (fullPath === "/") return fullPath;
|
|
478
|
+
return fullPath.replace(/\/$/, "");
|
|
447
479
|
};
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
480
|
+
/**
|
|
481
|
+
* Dedupes branches and index routes
|
|
482
|
+
*/
|
|
483
|
+
var dedupeBranchesAndIndexRoutes = (routes) => {
|
|
484
|
+
return routes.filter((route) => {
|
|
485
|
+
if (route.children?.find((child) => child.cleanedPath === "/")) return false;
|
|
486
|
+
return true;
|
|
487
|
+
});
|
|
453
488
|
};
|
|
454
489
|
function checkUnique(routes, key) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
);
|
|
462
|
-
return conflictingFiles;
|
|
463
|
-
}
|
|
464
|
-
return void 0;
|
|
490
|
+
const keys = routes.map((d) => d[key]);
|
|
491
|
+
const uniqueKeys = new Set(keys);
|
|
492
|
+
if (keys.length !== uniqueKeys.size) {
|
|
493
|
+
const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i);
|
|
494
|
+
return routes.filter((d) => duplicateKeys.includes(d[key]));
|
|
495
|
+
}
|
|
465
496
|
}
|
|
466
497
|
function checkRouteFullPathUniqueness(_routes, config) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
Conflicting files:
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
498
|
+
const emptyPathRoutes = _routes.filter((d) => d.routePath === "");
|
|
499
|
+
if (emptyPathRoutes.length) {
|
|
500
|
+
const errorMessage = `Invalid route path "" was found. Root routes must be defined via __root.tsx (createRootRoute), not createFileRoute('') or a route file that resolves to an empty path.
|
|
501
|
+
Conflicting files: \n ${emptyPathRoutes.map((d) => node_path.default.resolve(config.routesDirectory, d.filePath)).join("\n ")}\n`;
|
|
502
|
+
throw new Error(errorMessage);
|
|
503
|
+
}
|
|
504
|
+
const conflictingFiles = checkUnique(_routes.map((d) => {
|
|
505
|
+
const inferredFullPath = inferFullPath(d);
|
|
506
|
+
return {
|
|
507
|
+
...d,
|
|
508
|
+
inferredFullPath
|
|
509
|
+
};
|
|
510
|
+
}), "inferredFullPath");
|
|
511
|
+
if (conflictingFiles !== void 0) {
|
|
512
|
+
const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? "s" : ""}: ${conflictingFiles.map((p) => `"${p.inferredFullPath}"`).join(", ")}.
|
|
482
513
|
Please ensure each Route has a unique full path.
|
|
483
|
-
Conflicting files:
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
throw new Error(errorMessage);
|
|
487
|
-
}
|
|
514
|
+
Conflicting files: \n ${conflictingFiles.map((d) => node_path.default.resolve(config.routesDirectory, d.filePath)).join("\n ")}\n`;
|
|
515
|
+
throw new Error(errorMessage);
|
|
516
|
+
}
|
|
488
517
|
}
|
|
489
518
|
function buildRouteTreeConfig(nodes, disableTypes, depth = 1) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (node.children?.length) {
|
|
499
|
-
const childConfigs = buildRouteTreeConfig(
|
|
500
|
-
node.children,
|
|
501
|
-
disableTypes,
|
|
502
|
-
depth + 1
|
|
503
|
-
);
|
|
504
|
-
const childrenDeclaration = disableTypes ? "" : `interface ${route}RouteChildren {
|
|
505
|
-
${node.children.map(
|
|
506
|
-
(child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`
|
|
507
|
-
).join(",")}
|
|
519
|
+
return nodes.map((node) => {
|
|
520
|
+
if (node._fsRouteType === "__root") return;
|
|
521
|
+
if (node._fsRouteType === "pathless_layout" && !node.children?.length) return;
|
|
522
|
+
const route = `${node.variableName}`;
|
|
523
|
+
if (node.children?.length) {
|
|
524
|
+
const childConfigs = buildRouteTreeConfig(node.children, disableTypes, depth + 1);
|
|
525
|
+
const childrenDeclaration = disableTypes ? "" : `interface ${route}RouteChildren {
|
|
526
|
+
${node.children.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(",")}
|
|
508
527
|
}`;
|
|
509
|
-
|
|
510
|
-
${node.children.map(
|
|
511
|
-
(child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`
|
|
512
|
-
).join(",")}
|
|
528
|
+
const children = `const ${route}RouteChildren${disableTypes ? "" : `: ${route}RouteChildren`} = {
|
|
529
|
+
${node.children.map((child) => `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`).join(",")}
|
|
513
530
|
}`;
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
});
|
|
524
|
-
return children.filter((x) => x !== void 0);
|
|
531
|
+
const routeWithChildren = `const ${route}RouteWithChildren = ${route}Route._addFileChildren(${route}RouteChildren)`;
|
|
532
|
+
return [
|
|
533
|
+
childConfigs.join("\n"),
|
|
534
|
+
childrenDeclaration,
|
|
535
|
+
children,
|
|
536
|
+
routeWithChildren
|
|
537
|
+
].join("\n\n");
|
|
538
|
+
}
|
|
539
|
+
}).filter((x) => x !== void 0);
|
|
525
540
|
}
|
|
526
541
|
function buildImportString(importDeclaration) {
|
|
527
|
-
|
|
528
|
-
|
|
542
|
+
const { source, specifiers, importKind } = importDeclaration;
|
|
543
|
+
return specifiers.length ? `import ${importKind === "type" ? "type " : ""}{ ${specifiers.map((s) => s.local ? `${s.imported} as ${s.local}` : s.imported).join(", ")} } from '${source}'` : "";
|
|
529
544
|
}
|
|
530
545
|
function mergeImportDeclarations(imports) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
return `${node.parent.variableName}Route`;
|
|
562
|
-
}
|
|
563
|
-
return findParent(node.parent);
|
|
546
|
+
const merged = /* @__PURE__ */ new Map();
|
|
547
|
+
for (const imp of imports) {
|
|
548
|
+
const key = `${imp.source}-${imp.importKind ?? ""}`;
|
|
549
|
+
let existing = merged.get(key);
|
|
550
|
+
if (!existing) {
|
|
551
|
+
existing = {
|
|
552
|
+
...imp,
|
|
553
|
+
specifiers: []
|
|
554
|
+
};
|
|
555
|
+
merged.set(key, existing);
|
|
556
|
+
}
|
|
557
|
+
const existingSpecs = existing.specifiers;
|
|
558
|
+
for (const specifier of imp.specifiers) {
|
|
559
|
+
let found = false;
|
|
560
|
+
for (let i = 0; i < existingSpecs.length; i++) {
|
|
561
|
+
const e = existingSpecs[i];
|
|
562
|
+
if (e.imported === specifier.imported && e.local === specifier.local) {
|
|
563
|
+
found = true;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (!found) existingSpecs.push(specifier);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return [...merged.values()];
|
|
571
|
+
}
|
|
572
|
+
var findParent = (node) => {
|
|
573
|
+
if (!node) return `rootRouteImport`;
|
|
574
|
+
if (node.parent) return `${node.parent.variableName}Route`;
|
|
575
|
+
return findParent(node.parent);
|
|
564
576
|
};
|
|
565
577
|
function buildFileRoutesByPathInterface(opts) {
|
|
566
|
-
|
|
578
|
+
return `declare module '${opts.module}' {
|
|
567
579
|
interface ${opts.interfaceName} {
|
|
568
580
|
${opts.routeNodes.map((routeNode) => {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
581
|
+
const filePathId = routeNode.routePath;
|
|
582
|
+
const preloaderRoute = `typeof ${routeNode.variableName}RouteImport`;
|
|
583
|
+
const parent = findParent(routeNode);
|
|
584
|
+
return `'${filePathId}': {
|
|
573
585
|
id: '${filePathId}'
|
|
574
586
|
path: '${inferPath(routeNode)}'
|
|
575
587
|
fullPath: '${inferFullPath(routeNode)}'
|
|
576
588
|
preLoaderRoute: ${preloaderRoute}
|
|
577
589
|
parentRoute: typeof ${parent}
|
|
578
590
|
}`;
|
|
579
|
-
|
|
591
|
+
}).join("\n")}
|
|
580
592
|
}
|
|
581
593
|
}`;
|
|
582
594
|
}
|
|
583
595
|
function getImportPath(node, config, generatedRouteTreePath) {
|
|
584
|
-
|
|
585
|
-
removeExt(
|
|
586
|
-
path.relative(
|
|
587
|
-
path.dirname(generatedRouteTreePath),
|
|
588
|
-
path.resolve(config.routesDirectory, node.filePath)
|
|
589
|
-
),
|
|
590
|
-
config.addExtensions
|
|
591
|
-
)
|
|
592
|
-
);
|
|
596
|
+
return replaceBackslash(removeExt(node_path.default.relative(node_path.default.dirname(generatedRouteTreePath), node_path.default.resolve(config.routesDirectory, node.filePath)), config.addExtensions));
|
|
593
597
|
}
|
|
594
598
|
function getImportForRouteNode(node, config, generatedRouteTreePath, root) {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
source,
|
|
608
|
-
specifiers: [
|
|
609
|
-
{
|
|
610
|
-
imported: "Route",
|
|
611
|
-
local: `${node.variableName}RouteImport`
|
|
612
|
-
}
|
|
613
|
-
]
|
|
614
|
-
};
|
|
615
|
-
}
|
|
599
|
+
let source = "";
|
|
600
|
+
if (config.importRoutesUsingAbsolutePaths) source = replaceBackslash(removeExt(node_path.default.resolve(root, config.routesDirectory, node.filePath), config.addExtensions));
|
|
601
|
+
else source = `./${getImportPath(node, config, generatedRouteTreePath)}`;
|
|
602
|
+
return {
|
|
603
|
+
source,
|
|
604
|
+
specifiers: [{
|
|
605
|
+
imported: "Route",
|
|
606
|
+
local: `${node.variableName}RouteImport`
|
|
607
|
+
}]
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
//#endregion
|
|
616
611
|
exports.RoutePrefixMap = RoutePrefixMap;
|
|
617
612
|
exports.buildFileRoutesByPathInterface = buildFileRoutesByPathInterface;
|
|
618
613
|
exports.buildImportString = buildImportString;
|
|
@@ -625,7 +620,6 @@ exports.createRouteNodesByFullPath = createRouteNodesByFullPath;
|
|
|
625
620
|
exports.createRouteNodesById = createRouteNodesById;
|
|
626
621
|
exports.createRouteNodesByTo = createRouteNodesByTo;
|
|
627
622
|
exports.createTokenRegex = createTokenRegex;
|
|
628
|
-
exports.dedupeBranchesAndIndexRoutes = dedupeBranchesAndIndexRoutes;
|
|
629
623
|
exports.determineInitialRoutePath = determineInitialRoutePath;
|
|
630
624
|
exports.determineNodePath = determineNodePath;
|
|
631
625
|
exports.findParent = findParent;
|
|
@@ -634,12 +628,8 @@ exports.getImportForRouteNode = getImportForRouteNode;
|
|
|
634
628
|
exports.getImportPath = getImportPath;
|
|
635
629
|
exports.getResolvedRouteNodeVariableName = getResolvedRouteNodeVariableName;
|
|
636
630
|
exports.hasEscapedLeadingUnderscore = hasEscapedLeadingUnderscore;
|
|
637
|
-
exports.hasEscapedTrailingUnderscore = hasEscapedTrailingUnderscore;
|
|
638
631
|
exports.hasParentRoute = hasParentRoute;
|
|
639
632
|
exports.inferFullPath = inferFullPath;
|
|
640
|
-
exports.inferPath = inferPath;
|
|
641
|
-
exports.inferTo = inferTo;
|
|
642
|
-
exports.isBracketWrappedSegment = isBracketWrappedSegment;
|
|
643
633
|
exports.isRouteNodeValidForAugmentation = isRouteNodeValidForAugmentation;
|
|
644
634
|
exports.isSegmentPathless = isSegmentPathless;
|
|
645
635
|
exports.mergeImportDeclarations = mergeImportDeclarations;
|
|
@@ -647,7 +637,6 @@ exports.multiSortBy = multiSortBy;
|
|
|
647
637
|
exports.removeExt = removeExt;
|
|
648
638
|
exports.removeGroups = removeGroups;
|
|
649
639
|
exports.removeLastSegmentFromPath = removeLastSegmentFromPath;
|
|
650
|
-
exports.removeLayoutSegments = removeLayoutSegments;
|
|
651
640
|
exports.removeLayoutSegmentsWithEscape = removeLayoutSegmentsWithEscape;
|
|
652
641
|
exports.removeLeadingSlash = removeLeadingSlash;
|
|
653
642
|
exports.removeTrailingSlash = removeTrailingSlash;
|
|
@@ -659,4 +648,5 @@ exports.routePathToVariable = routePathToVariable;
|
|
|
659
648
|
exports.trimPathLeft = trimPathLeft;
|
|
660
649
|
exports.unwrapBracketWrappedSegment = unwrapBracketWrappedSegment;
|
|
661
650
|
exports.writeIfDifferent = writeIfDifferent;
|
|
662
|
-
|
|
651
|
+
|
|
652
|
+
//# sourceMappingURL=utils.cjs.map
|