@react-router/dev 0.0.0-experimental-c0856287f
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/CHANGELOG.md +1773 -0
- package/LICENSE.md +23 -0
- package/README.md +13 -0
- package/dist/cli/commands.d.ts +12 -0
- package/dist/cli/commands.js +174 -0
- package/dist/cli/detectPackageManager.d.ts +10 -0
- package/dist/cli/detectPackageManager.js +39 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +19 -0
- package/dist/cli/run.d.ts +5 -0
- package/dist/cli/run.js +180 -0
- package/dist/cli/useJavascript.d.ts +4 -0
- package/dist/cli/useJavascript.js +66 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +21 -0
- package/dist/colors.d.ts +17 -0
- package/dist/colors.js +49 -0
- package/dist/config/defaults/entry.client.tsx +12 -0
- package/dist/config/defaults/entry.dev.d.ts +2 -0
- package/dist/config/defaults/entry.dev.ts +13 -0
- package/dist/config/defaults/entry.server.cloudflare.tsx +55 -0
- package/dist/config/defaults/entry.server.deno.tsx +55 -0
- package/dist/config/defaults/entry.server.node.tsx +155 -0
- package/dist/config/defaults/entry.server.spa.tsx +20 -0
- package/dist/config/flat-routes.d.ts +14 -0
- package/dist/config/flat-routes.js +418 -0
- package/dist/config/format.d.ts +5 -0
- package/dist/config/format.js +68 -0
- package/dist/config/routes.d.ts +98 -0
- package/dist/config/routes.js +93 -0
- package/dist/config/serverModes.d.ts +9 -0
- package/dist/config/serverModes.js +28 -0
- package/dist/config.d.ts +75 -0
- package/dist/config.js +152 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +23 -0
- package/dist/invariant.d.ts +2 -0
- package/dist/invariant.js +22 -0
- package/dist/manifest.d.ts +28 -0
- package/dist/vite/babel.d.ts +20 -0
- package/dist/vite/babel.js +49 -0
- package/dist/vite/build.d.ts +15 -0
- package/dist/vite/build.js +271 -0
- package/dist/vite/cloudflare-proxy-plugin.d.ts +15 -0
- package/dist/vite/cloudflare-proxy-plugin.js +82 -0
- package/dist/vite/dev.d.ts +15 -0
- package/dist/vite/dev.js +81 -0
- package/dist/vite/import-vite-esm-sync.d.ts +4 -0
- package/dist/vite/import-vite-esm-sync.js +28 -0
- package/dist/vite/index.d.ts +4 -0
- package/dist/vite/index.js +30 -0
- package/dist/vite/node-adapter.d.ts +6 -0
- package/dist/vite/node-adapter.js +78 -0
- package/dist/vite/plugin.d.ts +165 -0
- package/dist/vite/plugin.js +1178 -0
- package/dist/vite/profiler.d.ts +5 -0
- package/dist/vite/profiler.js +55 -0
- package/dist/vite/remove-exports-test.d.ts +1 -0
- package/dist/vite/remove-exports.d.ts +2 -0
- package/dist/vite/remove-exports.js +278 -0
- package/dist/vite/resolve-file-url.d.ts +3 -0
- package/dist/vite/resolve-file-url.js +53 -0
- package/dist/vite/static/refresh-utils.cjs +185 -0
- package/dist/vite/styles.d.ts +13 -0
- package/dist/vite/styles.js +176 -0
- package/dist/vite/vmod.d.ts +3 -0
- package/dist/vite/vmod.js +21 -0
- package/package.json +107 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-c0856287f
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var fs = require('node:fs');
|
|
16
|
+
var path = require('node:path');
|
|
17
|
+
var minimatch = require('minimatch');
|
|
18
|
+
var routes = require('./routes.js');
|
|
19
|
+
var config = require('../config.js');
|
|
20
|
+
|
|
21
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
22
|
+
|
|
23
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
24
|
+
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
25
|
+
|
|
26
|
+
const routeModuleExts = [".js", ".jsx", ".ts", ".tsx", ".md", ".mdx"];
|
|
27
|
+
let paramPrefixChar = "$";
|
|
28
|
+
let escapeStart = "[";
|
|
29
|
+
let escapeEnd = "]";
|
|
30
|
+
let optionalStart = "(";
|
|
31
|
+
let optionalEnd = ")";
|
|
32
|
+
const PrefixLookupTrieEndSymbol = Symbol("PrefixLookupTrieEndSymbol");
|
|
33
|
+
class PrefixLookupTrie {
|
|
34
|
+
root = {
|
|
35
|
+
[PrefixLookupTrieEndSymbol]: false
|
|
36
|
+
};
|
|
37
|
+
add(value) {
|
|
38
|
+
if (!value) throw new Error("Cannot add empty string to PrefixLookupTrie");
|
|
39
|
+
let node = this.root;
|
|
40
|
+
for (let char of value) {
|
|
41
|
+
if (!node[char]) {
|
|
42
|
+
node[char] = {
|
|
43
|
+
[PrefixLookupTrieEndSymbol]: false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
node = node[char];
|
|
47
|
+
}
|
|
48
|
+
node[PrefixLookupTrieEndSymbol] = true;
|
|
49
|
+
}
|
|
50
|
+
findAndRemove(prefix, filter) {
|
|
51
|
+
let node = this.root;
|
|
52
|
+
for (let char of prefix) {
|
|
53
|
+
if (!node[char]) return [];
|
|
54
|
+
node = node[char];
|
|
55
|
+
}
|
|
56
|
+
return this.#findAndRemoveRecursive([], node, prefix, filter);
|
|
57
|
+
}
|
|
58
|
+
#findAndRemoveRecursive(values, node, prefix, filter) {
|
|
59
|
+
for (let char of Object.keys(node)) {
|
|
60
|
+
this.#findAndRemoveRecursive(values, node[char], prefix + char, filter);
|
|
61
|
+
}
|
|
62
|
+
if (node[PrefixLookupTrieEndSymbol] && filter(prefix)) {
|
|
63
|
+
node[PrefixLookupTrieEndSymbol] = false;
|
|
64
|
+
values.push(prefix);
|
|
65
|
+
}
|
|
66
|
+
return values;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function flatRoutes(appDirectory, ignoredFilePatterns = [], prefix = "routes") {
|
|
70
|
+
let ignoredFileRegex = Array.from(new Set(["**/.*", ...ignoredFilePatterns])).map(re => minimatch.makeRe(re)).filter(re => !!re);
|
|
71
|
+
let routesDir = path__default["default"].join(appDirectory, prefix);
|
|
72
|
+
let rootRoute = config.findConfig(appDirectory, "root", routeModuleExts);
|
|
73
|
+
if (!rootRoute) {
|
|
74
|
+
throw new Error(`Could not find a root route module in the app directory: ${appDirectory}`);
|
|
75
|
+
}
|
|
76
|
+
if (!fs__default["default"].existsSync(rootRoute)) {
|
|
77
|
+
throw new Error(`Could not find the routes directory: ${routesDir}. Did you forget to create it?`);
|
|
78
|
+
}
|
|
79
|
+
// Only read the routes directory
|
|
80
|
+
let entries = fs__default["default"].readdirSync(routesDir, {
|
|
81
|
+
withFileTypes: true,
|
|
82
|
+
encoding: "utf-8"
|
|
83
|
+
});
|
|
84
|
+
let routes$1 = [];
|
|
85
|
+
for (let entry of entries) {
|
|
86
|
+
let filepath = routes.normalizeSlashes(path__default["default"].join(routesDir, entry.name));
|
|
87
|
+
let route = null;
|
|
88
|
+
// If it's a directory, don't recurse into it, instead just look for a route module
|
|
89
|
+
if (entry.isDirectory()) {
|
|
90
|
+
route = findRouteModuleForFolder(appDirectory, filepath, ignoredFileRegex);
|
|
91
|
+
} else if (entry.isFile()) {
|
|
92
|
+
route = findRouteModuleForFile(appDirectory, filepath, ignoredFileRegex);
|
|
93
|
+
}
|
|
94
|
+
if (route) routes$1.push(route);
|
|
95
|
+
}
|
|
96
|
+
let routeManifest = flatRoutesUniversal(appDirectory, routes$1, prefix);
|
|
97
|
+
return routeManifest;
|
|
98
|
+
}
|
|
99
|
+
function flatRoutesUniversal(appDirectory, routes$1, prefix = "routes") {
|
|
100
|
+
let urlConflicts = new Map();
|
|
101
|
+
let routeManifest = {};
|
|
102
|
+
let prefixLookup = new PrefixLookupTrie();
|
|
103
|
+
let uniqueRoutes = new Map();
|
|
104
|
+
let routeIdConflicts = new Map();
|
|
105
|
+
// id -> file
|
|
106
|
+
let routeIds = new Map();
|
|
107
|
+
for (let file of routes$1) {
|
|
108
|
+
let normalizedFile = routes.normalizeSlashes(file);
|
|
109
|
+
let routeExt = path__default["default"].extname(normalizedFile);
|
|
110
|
+
let routeDir = path__default["default"].dirname(normalizedFile);
|
|
111
|
+
let normalizedApp = routes.normalizeSlashes(appDirectory);
|
|
112
|
+
let routeId = routeDir === path__default["default"].posix.join(normalizedApp, prefix) ? path__default["default"].posix.relative(normalizedApp, normalizedFile).slice(0, -routeExt.length) : path__default["default"].posix.relative(normalizedApp, routeDir);
|
|
113
|
+
let conflict = routeIds.get(routeId);
|
|
114
|
+
if (conflict) {
|
|
115
|
+
let currentConflicts = routeIdConflicts.get(routeId);
|
|
116
|
+
if (!currentConflicts) {
|
|
117
|
+
currentConflicts = [path__default["default"].posix.relative(normalizedApp, conflict)];
|
|
118
|
+
}
|
|
119
|
+
currentConflicts.push(path__default["default"].posix.relative(normalizedApp, normalizedFile));
|
|
120
|
+
routeIdConflicts.set(routeId, currentConflicts);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
routeIds.set(routeId, normalizedFile);
|
|
124
|
+
}
|
|
125
|
+
let sortedRouteIds = Array.from(routeIds).sort(([a], [b]) => b.length - a.length);
|
|
126
|
+
for (let [routeId, file] of sortedRouteIds) {
|
|
127
|
+
let index = routeId.endsWith("_index");
|
|
128
|
+
let [segments, raw] = getRouteSegments(routeId.slice(prefix.length + 1));
|
|
129
|
+
let pathname = createRoutePath(segments, raw, index);
|
|
130
|
+
routeManifest[routeId] = {
|
|
131
|
+
file: file.slice(appDirectory.length + 1),
|
|
132
|
+
id: routeId,
|
|
133
|
+
path: pathname
|
|
134
|
+
};
|
|
135
|
+
if (index) routeManifest[routeId].index = true;
|
|
136
|
+
let childRouteIds = prefixLookup.findAndRemove(routeId, value => {
|
|
137
|
+
return [".", "/"].includes(value.slice(routeId.length).charAt(0));
|
|
138
|
+
});
|
|
139
|
+
prefixLookup.add(routeId);
|
|
140
|
+
if (childRouteIds.length > 0) {
|
|
141
|
+
for (let childRouteId of childRouteIds) {
|
|
142
|
+
routeManifest[childRouteId].parentId = routeId;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// path creation
|
|
147
|
+
let parentChildrenMap = new Map();
|
|
148
|
+
for (let [routeId] of sortedRouteIds) {
|
|
149
|
+
let config = routeManifest[routeId];
|
|
150
|
+
if (!config.parentId) continue;
|
|
151
|
+
let existingChildren = parentChildrenMap.get(config.parentId) || [];
|
|
152
|
+
existingChildren.push(config);
|
|
153
|
+
parentChildrenMap.set(config.parentId, existingChildren);
|
|
154
|
+
}
|
|
155
|
+
for (let [routeId] of sortedRouteIds) {
|
|
156
|
+
let config = routeManifest[routeId];
|
|
157
|
+
let originalPathname = config.path || "";
|
|
158
|
+
let pathname = config.path;
|
|
159
|
+
let parentConfig = config.parentId ? routeManifest[config.parentId] : null;
|
|
160
|
+
if (parentConfig !== null && parentConfig !== void 0 && parentConfig.path && pathname) {
|
|
161
|
+
pathname = pathname.slice(parentConfig.path.length).replace(/^\//, "").replace(/\/$/, "");
|
|
162
|
+
}
|
|
163
|
+
if (!config.parentId) config.parentId = "root";
|
|
164
|
+
config.path = pathname || undefined;
|
|
165
|
+
/**
|
|
166
|
+
* We do not try to detect path collisions for pathless layout route
|
|
167
|
+
* files because, by definition, they create the potential for route
|
|
168
|
+
* collisions _at that level in the tree_.
|
|
169
|
+
*
|
|
170
|
+
* Consider example where a user may want multiple pathless layout routes
|
|
171
|
+
* for different subfolders
|
|
172
|
+
*
|
|
173
|
+
* routes/
|
|
174
|
+
* account.tsx
|
|
175
|
+
* account._private.tsx
|
|
176
|
+
* account._private.orders.tsx
|
|
177
|
+
* account._private.profile.tsx
|
|
178
|
+
* account._public.tsx
|
|
179
|
+
* account._public.login.tsx
|
|
180
|
+
* account._public.perks.tsx
|
|
181
|
+
*
|
|
182
|
+
* In order to support both a public and private layout for `/account/*`
|
|
183
|
+
* URLs, we are creating a mutually exclusive set of URLs beneath 2
|
|
184
|
+
* separate pathless layout routes. In this case, the route paths for
|
|
185
|
+
* both account._public.tsx and account._private.tsx is the same
|
|
186
|
+
* (/account), but we're again not expecting to match at that level.
|
|
187
|
+
*
|
|
188
|
+
* By only ignoring this check when the final portion of the filename is
|
|
189
|
+
* pathless, we will still detect path collisions such as:
|
|
190
|
+
*
|
|
191
|
+
* routes/parent._pathless.foo.tsx
|
|
192
|
+
* routes/parent._pathless2.foo.tsx
|
|
193
|
+
*
|
|
194
|
+
* and
|
|
195
|
+
*
|
|
196
|
+
* routes/parent._pathless/index.tsx
|
|
197
|
+
* routes/parent._pathless2/index.tsx
|
|
198
|
+
*/
|
|
199
|
+
let lastRouteSegment = config.id.replace(new RegExp(`^${prefix}/`), "").split(".").pop();
|
|
200
|
+
let isPathlessLayoutRoute = lastRouteSegment && lastRouteSegment.startsWith("_") && lastRouteSegment !== "_index";
|
|
201
|
+
if (isPathlessLayoutRoute) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
let conflictRouteId = originalPathname + (config.index ? "?index" : "");
|
|
205
|
+
let conflict = uniqueRoutes.get(conflictRouteId);
|
|
206
|
+
uniqueRoutes.set(conflictRouteId, config);
|
|
207
|
+
if (conflict && (originalPathname || config.index)) {
|
|
208
|
+
let currentConflicts = urlConflicts.get(originalPathname);
|
|
209
|
+
if (!currentConflicts) currentConflicts = [conflict];
|
|
210
|
+
currentConflicts.push(config);
|
|
211
|
+
urlConflicts.set(originalPathname, currentConflicts);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (routeIdConflicts.size > 0) {
|
|
216
|
+
for (let [routeId, files] of routeIdConflicts.entries()) {
|
|
217
|
+
console.error(getRouteIdConflictErrorMessage(routeId, files));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// report conflicts
|
|
221
|
+
if (urlConflicts.size > 0) {
|
|
222
|
+
for (let [path, routes] of urlConflicts.entries()) {
|
|
223
|
+
// delete all but the first route from the manifest
|
|
224
|
+
for (let i = 1; i < routes.length; i++) {
|
|
225
|
+
delete routeManifest[routes[i].id];
|
|
226
|
+
}
|
|
227
|
+
let files = routes.map(r => r.file);
|
|
228
|
+
console.error(getRoutePathConflictErrorMessage(path, files));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return routeManifest;
|
|
232
|
+
}
|
|
233
|
+
function findRouteModuleForFile(appDirectory, filepath, ignoredFileRegex) {
|
|
234
|
+
let relativePath = routes.normalizeSlashes(path__default["default"].relative(appDirectory, filepath));
|
|
235
|
+
let isIgnored = ignoredFileRegex.some(regex => regex.test(relativePath));
|
|
236
|
+
if (isIgnored) return null;
|
|
237
|
+
return filepath;
|
|
238
|
+
}
|
|
239
|
+
function findRouteModuleForFolder(appDirectory, filepath, ignoredFileRegex) {
|
|
240
|
+
let relativePath = path__default["default"].relative(appDirectory, filepath);
|
|
241
|
+
let isIgnored = ignoredFileRegex.some(regex => regex.test(relativePath));
|
|
242
|
+
if (isIgnored) return null;
|
|
243
|
+
let routeRouteModule = config.findConfig(filepath, "route", routeModuleExts);
|
|
244
|
+
let routeIndexModule = config.findConfig(filepath, "index", routeModuleExts);
|
|
245
|
+
// if both a route and index module exist, throw a conflict error
|
|
246
|
+
// preferring the route module over the index module
|
|
247
|
+
if (routeRouteModule && routeIndexModule) {
|
|
248
|
+
let [segments, raw] = getRouteSegments(path__default["default"].relative(appDirectory, filepath));
|
|
249
|
+
let routePath = createRoutePath(segments, raw, false);
|
|
250
|
+
console.error(getRoutePathConflictErrorMessage(routePath || "/", [routeRouteModule, routeIndexModule]));
|
|
251
|
+
}
|
|
252
|
+
return routeRouteModule || routeIndexModule || null;
|
|
253
|
+
}
|
|
254
|
+
function getRouteSegments(routeId) {
|
|
255
|
+
let routeSegments = [];
|
|
256
|
+
let rawRouteSegments = [];
|
|
257
|
+
let index = 0;
|
|
258
|
+
let routeSegment = "";
|
|
259
|
+
let rawRouteSegment = "";
|
|
260
|
+
let state = "NORMAL";
|
|
261
|
+
let pushRouteSegment = (segment, rawSegment) => {
|
|
262
|
+
if (!segment) return;
|
|
263
|
+
let notSupportedInRR = (segment, char) => {
|
|
264
|
+
throw new Error(`Route segment "${segment}" for "${routeId}" cannot contain "${char}".\n` + `If this is something you need, upvote this proposal for React Router https://github.com/remix-run/react-router/discussions/9822.`);
|
|
265
|
+
};
|
|
266
|
+
if (rawSegment.includes("*")) {
|
|
267
|
+
return notSupportedInRR(rawSegment, "*");
|
|
268
|
+
}
|
|
269
|
+
if (rawSegment.includes(":")) {
|
|
270
|
+
return notSupportedInRR(rawSegment, ":");
|
|
271
|
+
}
|
|
272
|
+
if (rawSegment.includes("/")) {
|
|
273
|
+
return notSupportedInRR(segment, "/");
|
|
274
|
+
}
|
|
275
|
+
routeSegments.push(segment);
|
|
276
|
+
rawRouteSegments.push(rawSegment);
|
|
277
|
+
};
|
|
278
|
+
while (index < routeId.length) {
|
|
279
|
+
let char = routeId[index];
|
|
280
|
+
index++; //advance to next char
|
|
281
|
+
switch (state) {
|
|
282
|
+
case "NORMAL":
|
|
283
|
+
{
|
|
284
|
+
if (isSegmentSeparator(char)) {
|
|
285
|
+
pushRouteSegment(routeSegment, rawRouteSegment);
|
|
286
|
+
routeSegment = "";
|
|
287
|
+
rawRouteSegment = "";
|
|
288
|
+
state = "NORMAL";
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
if (char === escapeStart) {
|
|
292
|
+
state = "ESCAPE";
|
|
293
|
+
rawRouteSegment += char;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
if (char === optionalStart) {
|
|
297
|
+
state = "OPTIONAL";
|
|
298
|
+
rawRouteSegment += char;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
if (!routeSegment && char == paramPrefixChar) {
|
|
302
|
+
if (index === routeId.length) {
|
|
303
|
+
routeSegment += "*";
|
|
304
|
+
rawRouteSegment += char;
|
|
305
|
+
} else {
|
|
306
|
+
routeSegment += ":";
|
|
307
|
+
rawRouteSegment += char;
|
|
308
|
+
}
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
routeSegment += char;
|
|
312
|
+
rawRouteSegment += char;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
case "ESCAPE":
|
|
316
|
+
{
|
|
317
|
+
if (char === escapeEnd) {
|
|
318
|
+
state = "NORMAL";
|
|
319
|
+
rawRouteSegment += char;
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
routeSegment += char;
|
|
323
|
+
rawRouteSegment += char;
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
case "OPTIONAL":
|
|
327
|
+
{
|
|
328
|
+
if (char === optionalEnd) {
|
|
329
|
+
routeSegment += "?";
|
|
330
|
+
rawRouteSegment += char;
|
|
331
|
+
state = "NORMAL";
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
if (char === escapeStart) {
|
|
335
|
+
state = "OPTIONAL_ESCAPE";
|
|
336
|
+
rawRouteSegment += char;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
if (!routeSegment && char === paramPrefixChar) {
|
|
340
|
+
if (index === routeId.length) {
|
|
341
|
+
routeSegment += "*";
|
|
342
|
+
rawRouteSegment += char;
|
|
343
|
+
} else {
|
|
344
|
+
routeSegment += ":";
|
|
345
|
+
rawRouteSegment += char;
|
|
346
|
+
}
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
routeSegment += char;
|
|
350
|
+
rawRouteSegment += char;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
case "OPTIONAL_ESCAPE":
|
|
354
|
+
{
|
|
355
|
+
if (char === escapeEnd) {
|
|
356
|
+
state = "OPTIONAL";
|
|
357
|
+
rawRouteSegment += char;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
routeSegment += char;
|
|
361
|
+
rawRouteSegment += char;
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// process remaining segment
|
|
367
|
+
pushRouteSegment(routeSegment, rawRouteSegment);
|
|
368
|
+
return [routeSegments, rawRouteSegments];
|
|
369
|
+
}
|
|
370
|
+
function createRoutePath(routeSegments, rawRouteSegments, isIndex) {
|
|
371
|
+
let result = [];
|
|
372
|
+
if (isIndex) {
|
|
373
|
+
routeSegments = routeSegments.slice(0, -1);
|
|
374
|
+
}
|
|
375
|
+
for (let index = 0; index < routeSegments.length; index++) {
|
|
376
|
+
let segment = routeSegments[index];
|
|
377
|
+
let rawSegment = rawRouteSegments[index];
|
|
378
|
+
// skip pathless layout segments
|
|
379
|
+
if (segment.startsWith("_") && rawSegment.startsWith("_")) {
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
// remove trailing slash
|
|
383
|
+
if (segment.endsWith("_") && rawSegment.endsWith("_")) {
|
|
384
|
+
segment = segment.slice(0, -1);
|
|
385
|
+
}
|
|
386
|
+
result.push(segment);
|
|
387
|
+
}
|
|
388
|
+
return result.length ? result.join("/") : undefined;
|
|
389
|
+
}
|
|
390
|
+
function getRoutePathConflictErrorMessage(pathname, routes) {
|
|
391
|
+
let [taken, ...others] = routes;
|
|
392
|
+
if (!pathname.startsWith("/")) {
|
|
393
|
+
pathname = "/" + pathname;
|
|
394
|
+
}
|
|
395
|
+
return `⚠️ Route Path Collision: "${pathname}"\n\n` + `The following routes all define the same URL, only the first one will be used\n\n` + `🟢 ${taken}\n` + others.map(route => `⭕️️ ${route}`).join("\n") + "\n";
|
|
396
|
+
}
|
|
397
|
+
function getRouteIdConflictErrorMessage(routeId, files) {
|
|
398
|
+
let [taken, ...others] = files;
|
|
399
|
+
return `⚠️ Route ID Collision: "${routeId}"\n\n` + `The following routes all define the same Route ID, only the first one will be used\n\n` + `🟢 ${taken}\n` + others.map(route => `⭕️️ ${route}`).join("\n") + "\n";
|
|
400
|
+
}
|
|
401
|
+
function isSegmentSeparator(checkChar) {
|
|
402
|
+
if (!checkChar) return false;
|
|
403
|
+
return ["/", ".", path__default["default"].win32.sep].includes(checkChar);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
exports.createRoutePath = createRoutePath;
|
|
407
|
+
exports.escapeEnd = escapeEnd;
|
|
408
|
+
exports.escapeStart = escapeStart;
|
|
409
|
+
exports.flatRoutes = flatRoutes;
|
|
410
|
+
exports.flatRoutesUniversal = flatRoutesUniversal;
|
|
411
|
+
exports.getRouteIdConflictErrorMessage = getRouteIdConflictErrorMessage;
|
|
412
|
+
exports.getRoutePathConflictErrorMessage = getRoutePathConflictErrorMessage;
|
|
413
|
+
exports.getRouteSegments = getRouteSegments;
|
|
414
|
+
exports.isSegmentSeparator = isSegmentSeparator;
|
|
415
|
+
exports.optionalEnd = optionalEnd;
|
|
416
|
+
exports.optionalStart = optionalStart;
|
|
417
|
+
exports.paramPrefixChar = paramPrefixChar;
|
|
418
|
+
exports.routeModuleExts = routeModuleExts;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RouteManifest } from "./routes";
|
|
2
|
+
export type RoutesFormat = "json" | "jsx";
|
|
3
|
+
export declare function formatRoutes(routeManifest: RouteManifest, format: RoutesFormat): string;
|
|
4
|
+
export declare function formatRoutesAsJson(routeManifest: RouteManifest): string;
|
|
5
|
+
export declare function formatRoutesAsJsx(routeManifest: RouteManifest): string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-c0856287f
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
function formatRoutes(routeManifest, format) {
|
|
16
|
+
switch (format) {
|
|
17
|
+
case "json":
|
|
18
|
+
return formatRoutesAsJson(routeManifest);
|
|
19
|
+
case "jsx":
|
|
20
|
+
return formatRoutesAsJsx(routeManifest);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function formatRoutesAsJson(routeManifest) {
|
|
24
|
+
function handleRoutesRecursive(parentId) {
|
|
25
|
+
let routes = Object.values(routeManifest).filter(route => route.parentId === parentId);
|
|
26
|
+
let children = [];
|
|
27
|
+
for (let route of routes) {
|
|
28
|
+
children.push({
|
|
29
|
+
id: route.id,
|
|
30
|
+
index: route.index,
|
|
31
|
+
path: route.path,
|
|
32
|
+
caseSensitive: route.caseSensitive,
|
|
33
|
+
file: route.file,
|
|
34
|
+
children: handleRoutesRecursive(route.id)
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (children.length > 0) {
|
|
38
|
+
return children;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return JSON.stringify(handleRoutesRecursive() || null, null, 2);
|
|
43
|
+
}
|
|
44
|
+
function formatRoutesAsJsx(routeManifest) {
|
|
45
|
+
let output = "<Routes>";
|
|
46
|
+
function handleRoutesRecursive(parentId, level = 1) {
|
|
47
|
+
let routes = Object.values(routeManifest).filter(route => route.parentId === parentId);
|
|
48
|
+
let indent = Array(level * 2).fill(" ").join("");
|
|
49
|
+
for (let route of routes) {
|
|
50
|
+
output += "\n" + indent;
|
|
51
|
+
output += `<Route${route.path ? ` path=${JSON.stringify(route.path)}` : ""}${route.index ? " index" : ""}${route.file ? ` file=${JSON.stringify(route.file)}` : ""}>`;
|
|
52
|
+
if (handleRoutesRecursive(route.id, level + 1)) {
|
|
53
|
+
output += "\n" + indent;
|
|
54
|
+
output += "</Route>";
|
|
55
|
+
} else {
|
|
56
|
+
output = output.slice(0, -1) + " />";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return routes.length > 0;
|
|
60
|
+
}
|
|
61
|
+
handleRoutesRecursive();
|
|
62
|
+
output += "\n</Routes>";
|
|
63
|
+
return output;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.formatRoutes = formatRoutes;
|
|
67
|
+
exports.formatRoutesAsJson = formatRoutesAsJson;
|
|
68
|
+
exports.formatRoutesAsJsx = formatRoutesAsJsx;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A route that was created using `defineRoutes` or created conventionally from
|
|
3
|
+
* looking at the files on the filesystem.
|
|
4
|
+
*/
|
|
5
|
+
export interface ConfigRoute {
|
|
6
|
+
/**
|
|
7
|
+
* The path this route uses to match on the URL pathname.
|
|
8
|
+
*/
|
|
9
|
+
path?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Should be `true` if it is an index route. This disallows child routes.
|
|
12
|
+
*/
|
|
13
|
+
index?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Should be `true` if the `path` is case-sensitive. Defaults to `false`.
|
|
16
|
+
*/
|
|
17
|
+
caseSensitive?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* The unique id for this route, named like its `file` but without the
|
|
20
|
+
* extension. So `app/routes/gists/$username.tsx` will have an `id` of
|
|
21
|
+
* `routes/gists/$username`.
|
|
22
|
+
*/
|
|
23
|
+
id: string;
|
|
24
|
+
/**
|
|
25
|
+
* The unique `id` for this route's parent route, if there is one.
|
|
26
|
+
*/
|
|
27
|
+
parentId?: string;
|
|
28
|
+
/**
|
|
29
|
+
* The path to the entry point for this route, relative to
|
|
30
|
+
* `config.appDirectory`.
|
|
31
|
+
*/
|
|
32
|
+
file: string;
|
|
33
|
+
}
|
|
34
|
+
export interface RouteManifest {
|
|
35
|
+
[routeId: string]: ConfigRoute;
|
|
36
|
+
}
|
|
37
|
+
export interface DefineRouteOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Should be `true` if the route `path` is case-sensitive. Defaults to
|
|
40
|
+
* `false`.
|
|
41
|
+
*/
|
|
42
|
+
caseSensitive?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Should be `true` if this is an index route that does not allow child routes.
|
|
45
|
+
*/
|
|
46
|
+
index?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* An optional unique id string for this route. Use this if you need to aggregate
|
|
49
|
+
* two or more routes with the same route file.
|
|
50
|
+
*/
|
|
51
|
+
id?: string;
|
|
52
|
+
}
|
|
53
|
+
interface DefineRouteChildren {
|
|
54
|
+
(): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A function for defining a route that is passed as the argument to the
|
|
58
|
+
* `defineRoutes` callback.
|
|
59
|
+
*
|
|
60
|
+
* Calls to this function are designed to be nested, using the `children`
|
|
61
|
+
* callback argument.
|
|
62
|
+
*
|
|
63
|
+
* defineRoutes(route => {
|
|
64
|
+
* route('/', 'pages/layout', () => {
|
|
65
|
+
* route('react-router', 'pages/react-router');
|
|
66
|
+
* route('reach-ui', 'pages/reach-ui');
|
|
67
|
+
* });
|
|
68
|
+
* });
|
|
69
|
+
*/
|
|
70
|
+
export interface DefineRouteFunction {
|
|
71
|
+
(
|
|
72
|
+
/**
|
|
73
|
+
* The path this route uses to match the URL pathname.
|
|
74
|
+
*/
|
|
75
|
+
path: string | undefined,
|
|
76
|
+
/**
|
|
77
|
+
* The path to the file that exports the React component rendered by this
|
|
78
|
+
* route as its default export, relative to the `app` directory.
|
|
79
|
+
*/
|
|
80
|
+
file: string,
|
|
81
|
+
/**
|
|
82
|
+
* Options for defining routes, or a function for defining child routes.
|
|
83
|
+
*/
|
|
84
|
+
optionsOrChildren?: DefineRouteOptions | DefineRouteChildren,
|
|
85
|
+
/**
|
|
86
|
+
* A function for defining child routes.
|
|
87
|
+
*/
|
|
88
|
+
children?: DefineRouteChildren): void;
|
|
89
|
+
}
|
|
90
|
+
export type DefineRoutesFunction = typeof defineRoutes;
|
|
91
|
+
/**
|
|
92
|
+
* A function for defining routes programmatically, instead of using the
|
|
93
|
+
* filesystem convention.
|
|
94
|
+
*/
|
|
95
|
+
export declare function defineRoutes(callback: (defineRoute: DefineRouteFunction) => void): RouteManifest;
|
|
96
|
+
export declare function createRouteId(file: string): string;
|
|
97
|
+
export declare function normalizeSlashes(file: string): string;
|
|
98
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-c0856287f
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var path = require('node:path');
|
|
16
|
+
|
|
17
|
+
function _interopNamespace(e) {
|
|
18
|
+
if (e && e.__esModule) return e;
|
|
19
|
+
var n = Object.create(null);
|
|
20
|
+
if (e) {
|
|
21
|
+
Object.keys(e).forEach(function (k) {
|
|
22
|
+
if (k !== 'default') {
|
|
23
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
24
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return e[k]; }
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
n["default"] = e;
|
|
32
|
+
return Object.freeze(n);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A function for defining routes programmatically, instead of using the
|
|
39
|
+
* filesystem convention.
|
|
40
|
+
*/
|
|
41
|
+
function defineRoutes(callback) {
|
|
42
|
+
let routes = Object.create(null);
|
|
43
|
+
let parentRoutes = [];
|
|
44
|
+
let alreadyReturned = false;
|
|
45
|
+
let defineRoute = (path, file, optionsOrChildren, children) => {
|
|
46
|
+
if (alreadyReturned) {
|
|
47
|
+
throw new Error("You tried to define routes asynchronously but started defining " + "routes before the async work was done. Please await all async " + "data before calling `defineRoutes()`");
|
|
48
|
+
}
|
|
49
|
+
let options;
|
|
50
|
+
if (typeof optionsOrChildren === "function") {
|
|
51
|
+
// route(path, file, children)
|
|
52
|
+
options = {};
|
|
53
|
+
children = optionsOrChildren;
|
|
54
|
+
} else {
|
|
55
|
+
// route(path, file, options, children)
|
|
56
|
+
// route(path, file, options)
|
|
57
|
+
options = optionsOrChildren || {};
|
|
58
|
+
}
|
|
59
|
+
let route = {
|
|
60
|
+
path: path ? path : undefined,
|
|
61
|
+
index: options.index ? true : undefined,
|
|
62
|
+
caseSensitive: options.caseSensitive ? true : undefined,
|
|
63
|
+
id: options.id || createRouteId(file),
|
|
64
|
+
parentId: parentRoutes.length > 0 ? parentRoutes[parentRoutes.length - 1].id : "root",
|
|
65
|
+
file
|
|
66
|
+
};
|
|
67
|
+
if (route.id in routes) {
|
|
68
|
+
throw new Error(`Unable to define routes with duplicate route id: "${route.id}"`);
|
|
69
|
+
}
|
|
70
|
+
routes[route.id] = route;
|
|
71
|
+
if (children) {
|
|
72
|
+
parentRoutes.push(route);
|
|
73
|
+
children();
|
|
74
|
+
parentRoutes.pop();
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
callback(defineRoute);
|
|
78
|
+
alreadyReturned = true;
|
|
79
|
+
return routes;
|
|
80
|
+
}
|
|
81
|
+
function createRouteId(file) {
|
|
82
|
+
return normalizeSlashes(stripFileExtension(file));
|
|
83
|
+
}
|
|
84
|
+
function normalizeSlashes(file) {
|
|
85
|
+
return file.split(path__namespace.win32.sep).join("/");
|
|
86
|
+
}
|
|
87
|
+
function stripFileExtension(file) {
|
|
88
|
+
return file.replace(/\.[a-z0-9]+$/i, "");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
exports.createRouteId = createRouteId;
|
|
92
|
+
exports.defineRoutes = defineRoutes;
|
|
93
|
+
exports.normalizeSlashes = normalizeSlashes;
|