@react-router/dev 7.0.0-pre.2 → 7.0.0-pre.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cli/index.d.ts +2 -1
  3. package/dist/cli/index.js +1198 -8
  4. package/dist/{config/routes.d.ts → routes-C14jcF98.d.ts} +15 -21
  5. package/dist/routes.d.ts +2 -2
  6. package/dist/routes.js +181 -11
  7. package/dist/typescript/plugin.d.ts +5 -2
  8. package/dist/typescript/plugin.js +479 -31
  9. package/dist/vite/cloudflare.d.ts +23 -1
  10. package/dist/vite/cloudflare.js +171 -5
  11. package/dist/vite.d.ts +169 -2
  12. package/dist/vite.js +2394 -5
  13. package/package.json +28 -7
  14. package/dist/cli/commands.d.ts +0 -13
  15. package/dist/cli/commands.js +0 -179
  16. package/dist/cli/detectPackageManager.d.ts +0 -10
  17. package/dist/cli/detectPackageManager.js +0 -39
  18. package/dist/cli/run.d.ts +0 -5
  19. package/dist/cli/run.js +0 -188
  20. package/dist/cli/useJavascript.d.ts +0 -4
  21. package/dist/cli/useJavascript.js +0 -66
  22. package/dist/colors.d.ts +0 -17
  23. package/dist/colors.js +0 -49
  24. package/dist/config/format.d.ts +0 -5
  25. package/dist/config/format.js +0 -68
  26. package/dist/config/routes.js +0 -253
  27. package/dist/config/serverModes.d.ts +0 -9
  28. package/dist/invariant.d.ts +0 -2
  29. package/dist/invariant.js +0 -20
  30. package/dist/manifest.d.ts +0 -28
  31. package/dist/typescript/typegen.d.ts +0 -10
  32. package/dist/typescript/typegen.js +0 -190
  33. package/dist/vite/babel.d.ts +0 -20
  34. package/dist/vite/babel.js +0 -49
  35. package/dist/vite/build.d.ts +0 -15
  36. package/dist/vite/build.js +0 -249
  37. package/dist/vite/cloudflare-dev-proxy.d.ts +0 -21
  38. package/dist/vite/cloudflare-dev-proxy.js +0 -89
  39. package/dist/vite/combine-urls-test.d.ts +0 -1
  40. package/dist/vite/combine-urls.d.ts +0 -1
  41. package/dist/vite/combine-urls.js +0 -20
  42. package/dist/vite/config.d.ts +0 -234
  43. package/dist/vite/config.js +0 -282
  44. package/dist/vite/dev.d.ts +0 -15
  45. package/dist/vite/dev.js +0 -81
  46. package/dist/vite/import-vite-esm-sync.d.ts +0 -4
  47. package/dist/vite/import-vite-esm-sync.js +0 -28
  48. package/dist/vite/node-adapter.d.ts +0 -6
  49. package/dist/vite/node-adapter.js +0 -90
  50. package/dist/vite/plugin.d.ts +0 -75
  51. package/dist/vite/plugin.js +0 -1301
  52. package/dist/vite/profiler.d.ts +0 -5
  53. package/dist/vite/profiler.js +0 -55
  54. package/dist/vite/remove-exports-test.d.ts +0 -1
  55. package/dist/vite/remove-exports.d.ts +0 -2
  56. package/dist/vite/remove-exports.js +0 -148
  57. package/dist/vite/resolve-file-url.d.ts +0 -3
  58. package/dist/vite/resolve-file-url.js +0 -53
  59. package/dist/vite/styles.d.ts +0 -14
  60. package/dist/vite/styles.js +0 -199
  61. package/dist/vite/vite-node.d.ts +0 -9
  62. package/dist/vite/vite-node.js +0 -57
  63. package/dist/vite/vmod.d.ts +0 -3
  64. package/dist/vite/vmod.js +0 -21
  65. package/dist/vite/with-props.d.ts +0 -4
  66. package/dist/vite/with-props.js +0 -151
  67. /package/dist/{vite/static → static}/refresh-utils.cjs +0 -0
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.0.0-pre.2
2
+ * @react-router/dev v7.0.0-pre.4
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,12 +8,2401 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- 'use strict';
11
+ "use strict";
12
+ var __create = Object.create;
13
+ var __defProp = Object.defineProperty;
14
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
+ var __getOwnPropNames = Object.getOwnPropertyNames;
16
+ var __getProtoOf = Object.getPrototypeOf;
17
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
18
+ var __export = (target, all) => {
19
+ for (var name in all)
20
+ __defProp(target, name, { get: all[name], enumerable: true });
21
+ };
22
+ var __copyProps = (to, from, except, desc) => {
23
+ if (from && typeof from === "object" || typeof from === "function") {
24
+ for (let key of __getOwnPropNames(from))
25
+ if (!__hasOwnProp.call(to, key) && key !== except)
26
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
27
+ }
28
+ return to;
29
+ };
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
+ // If the importer is in node compatibility mode or this is not an ESM
32
+ // file that has been converted to a CommonJS file using a Babel-
33
+ // compatible transform (i.e. "__esModule" has not been set), then set
34
+ // "default" to the CommonJS "module.exports" for node compatibility.
35
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
36
+ mod
37
+ ));
38
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
12
39
 
13
- Object.defineProperty(exports, '__esModule', { value: true });
40
+ // vite.ts
41
+ var vite_exports = {};
42
+ __export(vite_exports, {
43
+ reactRouter: () => reactRouterVitePlugin
44
+ });
45
+ module.exports = __toCommonJS(vite_exports);
14
46
 
15
- var plugin = require('./vite/plugin.js');
47
+ // vite/plugin.ts
48
+ var import_node_crypto = require("crypto");
49
+ var path4 = __toESM(require("path"));
50
+ var url2 = __toESM(require("url"));
51
+ var fse2 = __toESM(require("fs-extra"));
52
+ var babel = __toESM(require("@babel/core"));
53
+ var import_react_router2 = require("react-router");
54
+ var import_es_module_lexer = require("es-module-lexer");
55
+ var import_jsesc = __toESM(require("jsesc"));
56
+ var import_picocolors2 = __toESM(require("picocolors"));
16
57
 
58
+ // invariant.ts
59
+ function invariant(value, message) {
60
+ if (value === false || value === null || typeof value === "undefined") {
61
+ console.error(
62
+ "The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose"
63
+ );
64
+ throw new Error(message);
65
+ }
66
+ }
17
67
 
68
+ // vite/babel.ts
69
+ var import_parser = require("@babel/parser");
70
+ var t = __toESM(require("@babel/types"));
71
+ var traverse = require("@babel/traverse").default;
72
+ var generate = require("@babel/generator").default;
18
73
 
19
- exports.reactRouter = plugin.reactRouterVitePlugin;
74
+ // vite/node-adapter.ts
75
+ var import_node_events = require("events");
76
+ var import_node_stream = require("stream");
77
+ var import_set_cookie_parser = require("set-cookie-parser");
78
+ var import_node = require("@react-router/node");
79
+ function fromNodeHeaders(nodeHeaders) {
80
+ let headers = new Headers();
81
+ for (let [key, values] of Object.entries(nodeHeaders)) {
82
+ if (values) {
83
+ if (Array.isArray(values)) {
84
+ for (let value of values) {
85
+ headers.append(key, value);
86
+ }
87
+ } else {
88
+ headers.set(key, values);
89
+ }
90
+ }
91
+ }
92
+ return headers;
93
+ }
94
+ function fromNodeRequest(nodeReq, nodeRes) {
95
+ let origin = nodeReq.headers.origin && "null" !== nodeReq.headers.origin ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
96
+ invariant(
97
+ nodeReq.originalUrl,
98
+ "Expected `nodeReq.originalUrl` to be defined"
99
+ );
100
+ let url3 = new URL(nodeReq.originalUrl, origin);
101
+ let controller = new AbortController();
102
+ let init = {
103
+ method: nodeReq.method,
104
+ headers: fromNodeHeaders(nodeReq.headers),
105
+ signal: controller.signal
106
+ };
107
+ nodeRes.on("finish", () => controller = null);
108
+ nodeRes.on("close", () => controller?.abort());
109
+ if (nodeReq.method !== "GET" && nodeReq.method !== "HEAD") {
110
+ init.body = (0, import_node.createReadableStreamFromReadable)(nodeReq);
111
+ init.duplex = "half";
112
+ }
113
+ return new Request(url3.href, init);
114
+ }
115
+ async function toNodeRequest(res, nodeRes) {
116
+ nodeRes.statusCode = res.status;
117
+ nodeRes.statusMessage = res.statusText;
118
+ let cookiesStrings = [];
119
+ for (let [name, value] of res.headers) {
120
+ if (name === "set-cookie") {
121
+ cookiesStrings.push(...(0, import_set_cookie_parser.splitCookiesString)(value));
122
+ } else nodeRes.setHeader(name, value);
123
+ }
124
+ if (cookiesStrings.length) {
125
+ nodeRes.setHeader("set-cookie", cookiesStrings);
126
+ }
127
+ if (res.body) {
128
+ let responseBody = res.body;
129
+ let readable = import_node_stream.Readable.from(responseBody);
130
+ readable.pipe(nodeRes);
131
+ await (0, import_node_events.once)(readable, "end");
132
+ } else {
133
+ nodeRes.end();
134
+ }
135
+ }
136
+
137
+ // vite/styles.ts
138
+ var path2 = __toESM(require("path"));
139
+ var import_react_router = require("react-router");
140
+
141
+ // vite/resolve-file-url.ts
142
+ var path = __toESM(require("path"));
143
+
144
+ // vite/import-vite-esm-sync.ts
145
+ var vite;
146
+ async function preloadViteEsm() {
147
+ vite = await import("vite");
148
+ }
149
+ function importViteEsmSync() {
150
+ invariant(vite, "importViteEsmSync() called before preloadViteEsm()");
151
+ return vite;
152
+ }
153
+
154
+ // vite/resolve-file-url.ts
155
+ var resolveFileUrl = ({ rootDirectory }, filePath) => {
156
+ let vite2 = importViteEsmSync();
157
+ let relativePath = path.relative(rootDirectory, filePath);
158
+ let isWithinRoot = !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
159
+ if (!isWithinRoot) {
160
+ return path.posix.join("/@fs", vite2.normalizePath(filePath));
161
+ }
162
+ return "/" + vite2.normalizePath(relativePath);
163
+ };
164
+
165
+ // vite/styles.ts
166
+ var cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
167
+ var cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
168
+ var isCssFile = (file) => cssFileRegExp.test(file);
169
+ var isCssModulesFile = (file) => cssModulesRegExp.test(file);
170
+ var cssUrlParamsWithoutSideEffects = ["url", "inline", "raw", "inline-css"];
171
+ var isCssUrlWithoutSideEffects = (url3) => {
172
+ let queryString = url3.split("?")[1];
173
+ if (!queryString) {
174
+ return false;
175
+ }
176
+ let params = new URLSearchParams(queryString);
177
+ for (let paramWithoutSideEffects of cssUrlParamsWithoutSideEffects) {
178
+ if (
179
+ // Parameter is blank and not explicitly set, i.e. "?url", not "?url="
180
+ params.get(paramWithoutSideEffects) === "" && !url3.includes(`?${paramWithoutSideEffects}=`) && !url3.includes(`&${paramWithoutSideEffects}=`)
181
+ ) {
182
+ return true;
183
+ }
184
+ }
185
+ return false;
186
+ };
187
+ var getStylesForFiles = async ({
188
+ viteDevServer,
189
+ rootDirectory,
190
+ cssModulesManifest,
191
+ files
192
+ }) => {
193
+ let styles = {};
194
+ let deps = /* @__PURE__ */ new Set();
195
+ try {
196
+ for (let file of files) {
197
+ let normalizedPath = path2.resolve(rootDirectory, file).replace(/\\/g, "/");
198
+ let node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
199
+ if (!node) {
200
+ try {
201
+ await viteDevServer.transformRequest(
202
+ resolveFileUrl({ rootDirectory }, normalizedPath)
203
+ );
204
+ } catch (err) {
205
+ console.error(err);
206
+ }
207
+ node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
208
+ }
209
+ if (!node) {
210
+ console.log(`Could not resolve module for file: ${file}`);
211
+ continue;
212
+ }
213
+ await findDeps(viteDevServer, node, deps);
214
+ }
215
+ } catch (err) {
216
+ console.error(err);
217
+ }
218
+ for (let dep of deps) {
219
+ if (dep.file && isCssFile(dep.file) && !isCssUrlWithoutSideEffects(dep.url)) {
220
+ try {
221
+ let css = isCssModulesFile(dep.file) ? cssModulesManifest[dep.file] : (await viteDevServer.ssrLoadModule(dep.url)).default;
222
+ if (css === void 0) {
223
+ throw new Error();
224
+ }
225
+ styles[dep.url] = css;
226
+ } catch {
227
+ console.warn(`Could not load ${dep.file}`);
228
+ }
229
+ }
230
+ }
231
+ return Object.entries(styles).map(([fileName, css], i) => [
232
+ `
233
+ /* ${fileName.replace(/\/\*/g, "/\\*").replace(/\*\//g, "*\\/")} */`,
234
+ css
235
+ ]).flat().join("\n") || void 0;
236
+ };
237
+ var findDeps = async (vite2, node, deps) => {
238
+ let branches = [];
239
+ async function addFromNode(node2) {
240
+ if (!deps.has(node2)) {
241
+ deps.add(node2);
242
+ await findDeps(vite2, node2, deps);
243
+ }
244
+ }
245
+ async function addFromUrl(url3) {
246
+ let node2 = await vite2.moduleGraph.getModuleByUrl(url3);
247
+ if (node2) {
248
+ await addFromNode(node2);
249
+ }
250
+ }
251
+ if (node.ssrTransformResult) {
252
+ if (node.ssrTransformResult.deps) {
253
+ node.ssrTransformResult.deps.forEach(
254
+ (url3) => branches.push(addFromUrl(url3))
255
+ );
256
+ }
257
+ } else {
258
+ node.importedModules.forEach((node2) => branches.push(addFromNode(node2)));
259
+ }
260
+ await Promise.all(branches);
261
+ };
262
+ var groupRoutesByParentId = (manifest) => {
263
+ let routes = {};
264
+ Object.values(manifest).forEach((route) => {
265
+ if (route) {
266
+ let parentId = route.parentId || "";
267
+ if (!routes[parentId]) {
268
+ routes[parentId] = [];
269
+ }
270
+ routes[parentId].push(route);
271
+ }
272
+ });
273
+ return routes;
274
+ };
275
+ var createRoutes = (manifest, parentId = "", routesByParentId = groupRoutesByParentId(manifest)) => {
276
+ return (routesByParentId[parentId] || []).map((route) => ({
277
+ ...route,
278
+ children: createRoutes(manifest, route.id, routesByParentId)
279
+ }));
280
+ };
281
+ var getStylesForUrl = async ({
282
+ viteDevServer,
283
+ rootDirectory,
284
+ reactRouterConfig,
285
+ entryClientFilePath,
286
+ cssModulesManifest,
287
+ build,
288
+ url: url3
289
+ }) => {
290
+ if (url3 === void 0 || url3.includes("?_data=")) {
291
+ return void 0;
292
+ }
293
+ let routes = createRoutes(build.routes);
294
+ let appPath = path2.relative(process.cwd(), reactRouterConfig.appDirectory);
295
+ let documentRouteFiles = (0, import_react_router.matchRoutes)(routes, url3, build.basename)?.map(
296
+ (match) => path2.resolve(appPath, reactRouterConfig.routes[match.route.id].file)
297
+ ) ?? [];
298
+ let styles = await getStylesForFiles({
299
+ viteDevServer,
300
+ rootDirectory,
301
+ cssModulesManifest,
302
+ files: [
303
+ // Always include the client entry file when crawling the module graph for CSS
304
+ path2.relative(rootDirectory, entryClientFilePath),
305
+ // Then include any styles from the matched routes
306
+ ...documentRouteFiles
307
+ ]
308
+ });
309
+ return styles;
310
+ };
311
+
312
+ // vite/vmod.ts
313
+ var id = (name) => `virtual:react-router/${name}`;
314
+ var resolve2 = (id2) => `\0${id2}`;
315
+ var url = (id2) => `/@id/__x00__${id2}`;
316
+
317
+ // vite/combine-urls.ts
318
+ function combineURLs(baseURL, relativeURL) {
319
+ return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
320
+ }
321
+
322
+ // vite/remove-exports.ts
323
+ var import_babel_dead_code_elimination = require("babel-dead-code-elimination");
324
+ var removeExports = (ast, exportsToRemove) => {
325
+ let previouslyReferencedIdentifiers = (0, import_babel_dead_code_elimination.findReferencedIdentifiers)(ast);
326
+ let exportsFiltered = false;
327
+ let markedForRemoval = /* @__PURE__ */ new Set();
328
+ traverse(ast, {
329
+ ExportDeclaration(path5) {
330
+ if (path5.node.type === "ExportNamedDeclaration") {
331
+ if (path5.node.specifiers.length) {
332
+ path5.node.specifiers = path5.node.specifiers.filter((specifier) => {
333
+ if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
334
+ if (exportsToRemove.includes(specifier.exported.name)) {
335
+ exportsFiltered = true;
336
+ return false;
337
+ }
338
+ }
339
+ return true;
340
+ });
341
+ if (path5.node.specifiers.length === 0) {
342
+ markedForRemoval.add(path5);
343
+ }
344
+ }
345
+ if (path5.node.declaration?.type === "VariableDeclaration") {
346
+ let declaration = path5.node.declaration;
347
+ declaration.declarations = declaration.declarations.filter(
348
+ (declaration2) => {
349
+ if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
350
+ exportsFiltered = true;
351
+ return false;
352
+ }
353
+ if (declaration2.id.type === "ArrayPattern" || declaration2.id.type === "ObjectPattern") {
354
+ validateDestructuredExports(declaration2.id, exportsToRemove);
355
+ }
356
+ return true;
357
+ }
358
+ );
359
+ if (declaration.declarations.length === 0) {
360
+ markedForRemoval.add(path5);
361
+ }
362
+ }
363
+ if (path5.node.declaration?.type === "FunctionDeclaration") {
364
+ let id2 = path5.node.declaration.id;
365
+ if (id2 && exportsToRemove.includes(id2.name)) {
366
+ markedForRemoval.add(path5);
367
+ }
368
+ }
369
+ if (path5.node.declaration?.type === "ClassDeclaration") {
370
+ let id2 = path5.node.declaration.id;
371
+ if (id2 && exportsToRemove.includes(id2.name)) {
372
+ markedForRemoval.add(path5);
373
+ }
374
+ }
375
+ }
376
+ if (path5.node.type === "ExportDefaultDeclaration" && exportsToRemove.includes("default")) {
377
+ markedForRemoval.add(path5);
378
+ }
379
+ }
380
+ });
381
+ if (markedForRemoval.size > 0 || exportsFiltered) {
382
+ for (let path5 of markedForRemoval) {
383
+ path5.remove();
384
+ }
385
+ (0, import_babel_dead_code_elimination.deadCodeElimination)(ast, previouslyReferencedIdentifiers);
386
+ }
387
+ };
388
+ function validateDestructuredExports(id2, exportsToRemove) {
389
+ if (id2.type === "ArrayPattern") {
390
+ for (let element of id2.elements) {
391
+ if (!element) {
392
+ continue;
393
+ }
394
+ if (element.type === "Identifier" && exportsToRemove.includes(element.name)) {
395
+ throw invalidDestructureError(element.name);
396
+ }
397
+ if (element.type === "RestElement" && element.argument.type === "Identifier" && exportsToRemove.includes(element.argument.name)) {
398
+ throw invalidDestructureError(element.argument.name);
399
+ }
400
+ if (element.type === "ArrayPattern" || element.type === "ObjectPattern") {
401
+ validateDestructuredExports(element, exportsToRemove);
402
+ }
403
+ }
404
+ }
405
+ if (id2.type === "ObjectPattern") {
406
+ for (let property of id2.properties) {
407
+ if (!property) {
408
+ continue;
409
+ }
410
+ if (property.type === "ObjectProperty" && property.key.type === "Identifier") {
411
+ if (property.value.type === "Identifier" && exportsToRemove.includes(property.value.name)) {
412
+ throw invalidDestructureError(property.value.name);
413
+ }
414
+ if (property.value.type === "ArrayPattern" || property.value.type === "ObjectPattern") {
415
+ validateDestructuredExports(property.value, exportsToRemove);
416
+ }
417
+ }
418
+ if (property.type === "RestElement" && property.argument.type === "Identifier" && exportsToRemove.includes(property.argument.name)) {
419
+ throw invalidDestructureError(property.argument.name);
420
+ }
421
+ }
422
+ }
423
+ }
424
+ function invalidDestructureError(name) {
425
+ return new Error(`Cannot remove destructured export "${name}"`);
426
+ }
427
+
428
+ // vite/config.ts
429
+ var import_node_child_process = require("child_process");
430
+ var import_node_path2 = __toESM(require("path"));
431
+ var import_fs_extra = __toESM(require("fs-extra"));
432
+ var import_picocolors = __toESM(require("picocolors"));
433
+ var import_pick2 = __toESM(require("lodash/pick"));
434
+ var import_omit = __toESM(require("lodash/omit"));
435
+ var import_package_json = __toESM(require("@npmcli/package-json"));
436
+
437
+ // config/routes.ts
438
+ var import_node_path = require("path");
439
+ var v = __toESM(require("valibot"));
440
+ var import_pick = __toESM(require("lodash/pick"));
441
+ function setAppDirectory(directory) {
442
+ globalThis.__reactRouterAppDirectory = directory;
443
+ }
444
+ var routeConfigEntrySchema = v.pipe(
445
+ v.custom((value) => {
446
+ return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
447
+ }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
448
+ v.object({
449
+ id: v.optional(v.string()),
450
+ path: v.optional(v.string()),
451
+ index: v.optional(v.boolean()),
452
+ caseSensitive: v.optional(v.boolean()),
453
+ file: v.string(),
454
+ children: v.optional(v.array(v.lazy(() => routeConfigEntrySchema)))
455
+ })
456
+ );
457
+ var resolvedRouteConfigSchema = v.array(routeConfigEntrySchema);
458
+ function validateRouteConfig({
459
+ routeConfigFile,
460
+ routeConfig
461
+ }) {
462
+ if (!routeConfig) {
463
+ return {
464
+ valid: false,
465
+ message: `No "routes" export defined in "${routeConfigFile}.`
466
+ };
467
+ }
468
+ if (!Array.isArray(routeConfig)) {
469
+ return {
470
+ valid: false,
471
+ message: `Route config in "${routeConfigFile}" must be an array.`
472
+ };
473
+ }
474
+ let { issues } = v.safeParse(resolvedRouteConfigSchema, routeConfig);
475
+ if (issues?.length) {
476
+ let { root, nested } = v.flatten(issues);
477
+ return {
478
+ valid: false,
479
+ message: [
480
+ `Route config in "${routeConfigFile}" is invalid.`,
481
+ root ? `${root}` : [],
482
+ nested ? Object.entries(nested).map(
483
+ ([path5, message]) => `Path: routes.${path5}
484
+ ${message}`
485
+ ) : []
486
+ ].flat().join("\n\n")
487
+ };
488
+ }
489
+ return { valid: true };
490
+ }
491
+ function configRoutesToRouteManifest(routes, rootId = "root") {
492
+ let routeManifest = {};
493
+ function walk(route, parentId) {
494
+ let id2 = route.id || createRouteId(route.file);
495
+ let manifestItem = {
496
+ id: id2,
497
+ parentId,
498
+ file: route.file,
499
+ path: route.path,
500
+ index: route.index,
501
+ caseSensitive: route.caseSensitive
502
+ };
503
+ if (routeManifest.hasOwnProperty(id2)) {
504
+ throw new Error(
505
+ `Unable to define routes with duplicate route id: "${id2}"`
506
+ );
507
+ }
508
+ routeManifest[id2] = manifestItem;
509
+ if (route.children) {
510
+ for (let child of route.children) {
511
+ walk(child, id2);
512
+ }
513
+ }
514
+ }
515
+ for (let route of routes) {
516
+ walk(route, rootId);
517
+ }
518
+ return routeManifest;
519
+ }
520
+ function createRouteId(file) {
521
+ return normalizeSlashes(stripFileExtension(file));
522
+ }
523
+ function normalizeSlashes(file) {
524
+ return file.split(import_node_path.win32.sep).join("/");
525
+ }
526
+ function stripFileExtension(file) {
527
+ return file.replace(/\.[a-z0-9]+$/i, "");
528
+ }
529
+
530
+ // cli/detectPackageManager.ts
531
+ var detectPackageManager = () => {
532
+ let { npm_config_user_agent } = process.env;
533
+ if (!npm_config_user_agent) return void 0;
534
+ try {
535
+ let pkgManager = npm_config_user_agent.split("/")[0];
536
+ if (pkgManager === "npm") return "npm";
537
+ if (pkgManager === "pnpm") return "pnpm";
538
+ if (pkgManager === "yarn") return "yarn";
539
+ if (pkgManager === "bun") return "bun";
540
+ return void 0;
541
+ } catch {
542
+ return void 0;
543
+ }
544
+ };
545
+
546
+ // vite/config.ts
547
+ var excludedConfigPresetKeys = ["presets"];
548
+ var mergeReactRouterConfig = (...configs) => {
549
+ let reducer = (configA, configB) => {
550
+ let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
551
+ return {
552
+ ...configA,
553
+ ...configB,
554
+ ...mergeRequired("buildEnd") ? {
555
+ buildEnd: async (...args) => {
556
+ await Promise.all([
557
+ configA.buildEnd?.(...args),
558
+ configB.buildEnd?.(...args)
559
+ ]);
560
+ }
561
+ } : {},
562
+ ...mergeRequired("future") ? {
563
+ future: {
564
+ ...configA.future,
565
+ ...configB.future
566
+ }
567
+ } : {},
568
+ ...mergeRequired("presets") ? {
569
+ presets: [...configA.presets ?? [], ...configB.presets ?? []]
570
+ } : {}
571
+ };
572
+ };
573
+ return configs.reduce(reducer, {});
574
+ };
575
+ var deepFreeze = (o) => {
576
+ Object.freeze(o);
577
+ let oIsFunction = typeof o === "function";
578
+ let hasOwnProp = Object.prototype.hasOwnProperty;
579
+ Object.getOwnPropertyNames(o).forEach(function(prop) {
580
+ if (hasOwnProp.call(o, prop) && (oIsFunction ? prop !== "caller" && prop !== "callee" && prop !== "arguments" : true) && o[prop] !== null && (typeof o[prop] === "object" || typeof o[prop] === "function") && !Object.isFrozen(o[prop])) {
581
+ deepFreeze(o[prop]);
582
+ }
583
+ });
584
+ return o;
585
+ };
586
+ function resolvePublicPath(viteUserConfig) {
587
+ return viteUserConfig.base ?? "/";
588
+ }
589
+ var isFirstLoad = true;
590
+ var lastValidRoutes = {};
591
+ async function resolveReactRouterConfig({
592
+ rootDirectory,
593
+ reactRouterUserConfig,
594
+ routeConfigChanged,
595
+ viteUserConfig,
596
+ viteCommand,
597
+ routesViteNodeContext
598
+ }) {
599
+ let vite2 = importViteEsmSync();
600
+ let logger = vite2.createLogger(viteUserConfig.logLevel, {
601
+ prefix: "[react-router]"
602
+ });
603
+ let presets = (await Promise.all(
604
+ (reactRouterUserConfig.presets ?? []).map(async (preset) => {
605
+ if (!preset.name) {
606
+ throw new Error(
607
+ "React Router presets must have a `name` property defined."
608
+ );
609
+ }
610
+ if (!preset.reactRouterConfig) {
611
+ return null;
612
+ }
613
+ let configPreset = (0, import_omit.default)(
614
+ await preset.reactRouterConfig({ reactRouterUserConfig }),
615
+ excludedConfigPresetKeys
616
+ );
617
+ return configPreset;
618
+ })
619
+ )).filter(function isNotNull(value) {
620
+ return value !== null;
621
+ });
622
+ let defaults = {
623
+ basename: "/",
624
+ buildDirectory: "build",
625
+ serverBuildFile: "index.js",
626
+ serverModuleFormat: "esm",
627
+ ssr: true
628
+ };
629
+ let {
630
+ appDirectory: userAppDirectory,
631
+ basename: basename2,
632
+ buildDirectory: userBuildDirectory,
633
+ buildEnd,
634
+ prerender,
635
+ serverBuildFile,
636
+ serverBundles,
637
+ serverModuleFormat,
638
+ ssr
639
+ } = {
640
+ ...defaults,
641
+ // Default values should be completely overridden by user/preset config, not merged
642
+ ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
643
+ };
644
+ if (!ssr && serverBundles) {
645
+ console.warn(
646
+ import_picocolors.default.yellow(
647
+ import_picocolors.default.bold("\u26A0\uFE0F SPA Mode: ") + "the `serverBundles` config is invalid with `ssr:false` and will be ignored`"
648
+ )
649
+ );
650
+ serverBundles = void 0;
651
+ }
652
+ let isValidPrerenderConfig = prerender == null || typeof prerender === "boolean" || Array.isArray(prerender) || typeof prerender === "function";
653
+ if (!isValidPrerenderConfig) {
654
+ logger.error(
655
+ import_picocolors.default.red(
656
+ "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
657
+ )
658
+ );
659
+ process.exit(1);
660
+ }
661
+ let appDirectory = import_node_path2.default.resolve(rootDirectory, userAppDirectory || "app");
662
+ let buildDirectory = import_node_path2.default.resolve(rootDirectory, userBuildDirectory);
663
+ let publicPath = resolvePublicPath(viteUserConfig);
664
+ if (basename2 !== "/" && viteCommand === "serve" && !viteUserConfig.server?.middlewareMode && !basename2.startsWith(publicPath)) {
665
+ logger.error(
666
+ import_picocolors.default.red(
667
+ "When using the React Router `basename` and the Vite `base` config, the `basename` config must begin with `base` for the default Vite dev server."
668
+ )
669
+ );
670
+ process.exit(1);
671
+ }
672
+ let rootRouteFile = findEntry(appDirectory, "root");
673
+ if (!rootRouteFile) {
674
+ let rootRouteDisplayPath = import_node_path2.default.relative(
675
+ rootDirectory,
676
+ import_node_path2.default.join(appDirectory, "root.tsx")
677
+ );
678
+ logger.error(
679
+ import_picocolors.default.red(
680
+ `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
681
+ )
682
+ );
683
+ process.exit(1);
684
+ }
685
+ let routes = {
686
+ root: { path: "", id: "root", file: rootRouteFile }
687
+ };
688
+ let routeConfigFile = findEntry(appDirectory, "routes");
689
+ class FriendlyError extends Error {
690
+ }
691
+ try {
692
+ if (!routeConfigFile) {
693
+ let routeConfigDisplayPath = vite2.normalizePath(
694
+ import_node_path2.default.relative(rootDirectory, import_node_path2.default.join(appDirectory, "routes.ts"))
695
+ );
696
+ throw new FriendlyError(
697
+ `Route config file not found at "${routeConfigDisplayPath}".`
698
+ );
699
+ }
700
+ setAppDirectory(appDirectory);
701
+ let routeConfigExport = (await routesViteNodeContext.runner.executeFile(
702
+ import_node_path2.default.join(appDirectory, routeConfigFile)
703
+ )).routes;
704
+ let routeConfig = await routeConfigExport;
705
+ let result = validateRouteConfig({
706
+ routeConfigFile,
707
+ routeConfig
708
+ });
709
+ if (!result.valid) {
710
+ throw new FriendlyError(result.message);
711
+ }
712
+ routes = { ...routes, ...configRoutesToRouteManifest(routeConfig) };
713
+ lastValidRoutes = routes;
714
+ if (routeConfigChanged) {
715
+ logger.info(import_picocolors.default.green("Route config changed."), {
716
+ clear: true,
717
+ timestamp: true
718
+ });
719
+ }
720
+ } catch (error) {
721
+ logger.error(
722
+ error instanceof FriendlyError ? import_picocolors.default.red(error.message) : [
723
+ import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
724
+ "",
725
+ error.loc?.file && error.loc?.column && error.frame ? [
726
+ import_node_path2.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
727
+ error.frame.trim?.()
728
+ ] : error.stack
729
+ ].flat().join("\n") + "\n",
730
+ {
731
+ error,
732
+ clear: !isFirstLoad,
733
+ timestamp: !isFirstLoad
734
+ }
735
+ );
736
+ if (isFirstLoad) {
737
+ process.exit(1);
738
+ }
739
+ routes = lastValidRoutes;
740
+ }
741
+ let future = {};
742
+ let reactRouterConfig = deepFreeze({
743
+ appDirectory,
744
+ basename: basename2,
745
+ buildDirectory,
746
+ buildEnd,
747
+ future,
748
+ prerender,
749
+ routes,
750
+ serverBuildFile,
751
+ serverBundles,
752
+ serverModuleFormat,
753
+ ssr
754
+ });
755
+ for (let preset of reactRouterUserConfig.presets ?? []) {
756
+ await preset.reactRouterConfigResolved?.({ reactRouterConfig });
757
+ }
758
+ isFirstLoad = false;
759
+ return reactRouterConfig;
760
+ }
761
+ async function resolveEntryFiles({
762
+ rootDirectory,
763
+ reactRouterConfig
764
+ }) {
765
+ let { appDirectory } = reactRouterConfig;
766
+ let defaultsDirectory = import_node_path2.default.resolve(
767
+ import_node_path2.default.dirname(require.resolve("@react-router/dev/package.json")),
768
+ "dist",
769
+ "config",
770
+ "defaults"
771
+ );
772
+ let userEntryClientFile = findEntry(appDirectory, "entry.client");
773
+ let userEntryServerFile = findEntry(appDirectory, "entry.server");
774
+ let entryServerFile;
775
+ let entryClientFile = userEntryClientFile || "entry.client.tsx";
776
+ let pkgJson = await import_package_json.default.load(rootDirectory);
777
+ let deps = pkgJson.content.dependencies ?? {};
778
+ if (userEntryServerFile) {
779
+ entryServerFile = userEntryServerFile;
780
+ } else {
781
+ if (!deps["@react-router/node"]) {
782
+ throw new Error(
783
+ `Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
784
+ );
785
+ }
786
+ if (!deps["isbot"]) {
787
+ console.log(
788
+ "adding `isbot@5` to your package.json, you should commit this change"
789
+ );
790
+ pkgJson.update({
791
+ dependencies: {
792
+ ...pkgJson.content.dependencies,
793
+ isbot: "^5"
794
+ }
795
+ });
796
+ await pkgJson.save();
797
+ let packageManager = detectPackageManager() ?? "npm";
798
+ (0, import_node_child_process.execSync)(`${packageManager} install`, {
799
+ cwd: rootDirectory,
800
+ stdio: "inherit"
801
+ });
802
+ }
803
+ entryServerFile = `entry.server.node.tsx`;
804
+ }
805
+ let entryClientFilePath = userEntryClientFile ? import_node_path2.default.resolve(reactRouterConfig.appDirectory, userEntryClientFile) : import_node_path2.default.resolve(defaultsDirectory, entryClientFile);
806
+ let entryServerFilePath = userEntryServerFile ? import_node_path2.default.resolve(reactRouterConfig.appDirectory, userEntryServerFile) : import_node_path2.default.resolve(defaultsDirectory, entryServerFile);
807
+ return { entryClientFilePath, entryServerFilePath };
808
+ }
809
+ var entryExts = [".js", ".jsx", ".ts", ".tsx"];
810
+ function findEntry(dir, basename2) {
811
+ for (let ext of entryExts) {
812
+ let file = import_node_path2.default.resolve(dir, basename2 + ext);
813
+ if (import_fs_extra.default.existsSync(file)) return import_node_path2.default.relative(dir, file);
814
+ }
815
+ return void 0;
816
+ }
817
+
818
+ // vite/with-props.ts
819
+ var import_dedent = __toESM(require("dedent"));
820
+ var vmodId = id("with-props");
821
+ var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
822
+ var plugin = {
823
+ name: "react-router-with-props",
824
+ enforce: "pre",
825
+ resolveId(id2) {
826
+ if (id2 === vmodId) return resolve2(vmodId);
827
+ },
828
+ async load(id2) {
829
+ if (id2 !== resolve2(vmodId)) return;
830
+ return import_dedent.default`
831
+ import { createElement as h } from "react";
832
+ import { useActionData, useLoaderData, useParams } from "react-router";
833
+
834
+ export function withComponentProps(Component) {
835
+ return function Wrapped() {
836
+ const props = {
837
+ params: useParams(),
838
+ loaderData: useLoaderData(),
839
+ actionData: useActionData(),
840
+ };
841
+ return h(Component, props);
842
+ };
843
+ }
844
+
845
+ export function withHydrateFallbackProps(HydrateFallback) {
846
+ return function Wrapped() {
847
+ const props = {
848
+ params: useParams(),
849
+ };
850
+ return h(HydrateFallback, props);
851
+ };
852
+ }
853
+
854
+ export function withErrorBoundaryProps(ErrorBoundary) {
855
+ return function Wrapped() {
856
+ const props = {
857
+ params: useParams(),
858
+ loaderData: useLoaderData(),
859
+ actionData: useActionData(),
860
+ };
861
+ return h(ErrorBoundary, props);
862
+ };
863
+ }
864
+ `;
865
+ }
866
+ };
867
+ var transform = (ast) => {
868
+ const hocs = [];
869
+ function getHocUid(path5, hocName) {
870
+ const uid = path5.scope.generateUidIdentifier(hocName);
871
+ hocs.push([hocName, uid]);
872
+ return uid;
873
+ }
874
+ traverse(ast, {
875
+ ExportDeclaration(path5) {
876
+ if (path5.isExportDefaultDeclaration()) {
877
+ const declaration = path5.get("declaration");
878
+ const expr = declaration.isExpression() ? declaration.node : declaration.isFunctionDeclaration() ? toFunctionExpression(declaration.node) : void 0;
879
+ if (expr) {
880
+ const uid = getHocUid(path5, "withComponentProps");
881
+ declaration.replaceWith(t.callExpression(uid, [expr]));
882
+ }
883
+ return;
884
+ }
885
+ if (path5.isExportNamedDeclaration()) {
886
+ const decl = path5.get("declaration");
887
+ if (decl.isVariableDeclaration()) {
888
+ decl.get("declarations").forEach((varDeclarator) => {
889
+ const id2 = varDeclarator.get("id");
890
+ const init = varDeclarator.get("init");
891
+ const expr = init.node;
892
+ if (!expr) return;
893
+ if (!id2.isIdentifier()) return;
894
+ const { name } = id2.node;
895
+ if (!NAMED_COMPONENT_EXPORTS.includes(name)) return;
896
+ const uid = getHocUid(path5, `with${name}Props`);
897
+ init.replaceWith(t.callExpression(uid, [expr]));
898
+ });
899
+ return;
900
+ }
901
+ if (decl.isFunctionDeclaration()) {
902
+ const { id: id2 } = decl.node;
903
+ if (!id2) return;
904
+ const { name } = id2;
905
+ if (!NAMED_COMPONENT_EXPORTS.includes(name)) return;
906
+ const uid = getHocUid(path5, `with${name}Props`);
907
+ decl.replaceWith(
908
+ t.variableDeclaration("const", [
909
+ t.variableDeclarator(
910
+ t.identifier(name),
911
+ t.callExpression(uid, [toFunctionExpression(decl.node)])
912
+ )
913
+ ])
914
+ );
915
+ }
916
+ }
917
+ }
918
+ });
919
+ if (hocs.length > 0) {
920
+ ast.program.body.unshift(
921
+ t.importDeclaration(
922
+ hocs.map(
923
+ ([name, identifier]) => t.importSpecifier(identifier, t.identifier(name))
924
+ ),
925
+ t.stringLiteral(vmodId)
926
+ )
927
+ );
928
+ }
929
+ };
930
+ function toFunctionExpression(decl) {
931
+ return t.functionExpression(
932
+ decl.id,
933
+ decl.params,
934
+ decl.body,
935
+ decl.generator,
936
+ decl.async
937
+ );
938
+ }
939
+
940
+ // vite/vite-node.ts
941
+ var import_server = require("vite-node/server");
942
+ var import_client = require("vite-node/client");
943
+ var import_source_map = require("vite-node/source-map");
944
+ async function createContext(viteConfig = {}) {
945
+ await preloadViteEsm();
946
+ const vite2 = importViteEsmSync();
947
+ const devServer = await vite2.createServer(
948
+ vite2.mergeConfig(
949
+ {
950
+ server: {
951
+ preTransformRequests: false,
952
+ hmr: false
953
+ },
954
+ optimizeDeps: {
955
+ noDiscovery: true
956
+ },
957
+ configFile: false,
958
+ envFile: false,
959
+ plugins: []
960
+ },
961
+ viteConfig
962
+ )
963
+ );
964
+ await devServer.pluginContainer.buildStart({});
965
+ const server = new import_server.ViteNodeServer(devServer);
966
+ (0, import_source_map.installSourcemapsSupport)({
967
+ getSourceMap: (source) => server.getSourceMap(source)
968
+ });
969
+ const runner = new import_client.ViteNodeRunner({
970
+ root: devServer.config.root,
971
+ base: devServer.config.base,
972
+ fetchModule(id2) {
973
+ return server.fetchModule(id2);
974
+ },
975
+ resolveId(id2, importer) {
976
+ return server.resolveId(id2, importer);
977
+ }
978
+ });
979
+ return { devServer, server, runner };
980
+ }
981
+
982
+ // vite/plugin.ts
983
+ var SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "headers"];
984
+ var CLIENT_ROUTE_EXPORTS = [
985
+ "clientAction",
986
+ "clientLoader",
987
+ "default",
988
+ "ErrorBoundary",
989
+ "handle",
990
+ "HydrateFallback",
991
+ "Layout",
992
+ "links",
993
+ "meta",
994
+ "shouldRevalidate"
995
+ ];
996
+ var ROUTE_ENTRY_QUERY_STRING = "?route-entry=1";
997
+ var isRouteEntry = (id2) => {
998
+ return id2.endsWith(ROUTE_ENTRY_QUERY_STRING);
999
+ };
1000
+ var serverBuildId = id("server-build");
1001
+ var serverManifestId = id("server-manifest");
1002
+ var browserManifestId = id("browser-manifest");
1003
+ var hmrRuntimeId = id("hmr-runtime");
1004
+ var injectHmrRuntimeId = id("inject-hmr-runtime");
1005
+ var resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
1006
+ let vite2 = importViteEsmSync();
1007
+ let file = route.file;
1008
+ let fullPath = path4.resolve(reactRouterConfig.appDirectory, file);
1009
+ return vite2.normalizePath(fullPath);
1010
+ };
1011
+ var vmods = [serverBuildId, serverManifestId, browserManifestId];
1012
+ var invalidateVirtualModules = (viteDevServer) => {
1013
+ vmods.forEach((vmod) => {
1014
+ let mod = viteDevServer.moduleGraph.getModuleById(
1015
+ resolve2(vmod)
1016
+ );
1017
+ if (mod) {
1018
+ viteDevServer.moduleGraph.invalidateModule(mod);
1019
+ }
1020
+ });
1021
+ };
1022
+ var getHash = (source, maxLength) => {
1023
+ let hash = (0, import_node_crypto.createHash)("sha256").update(source).digest("hex");
1024
+ return typeof maxLength === "number" ? hash.slice(0, maxLength) : hash;
1025
+ };
1026
+ var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
1027
+ let vite2 = importViteEsmSync();
1028
+ let rootRelativeFilePath = vite2.normalizePath(
1029
+ path4.relative(ctx.rootDirectory, absoluteFilePath)
1030
+ );
1031
+ let entryChunk = viteManifest[rootRelativeFilePath + ROUTE_ENTRY_QUERY_STRING] ?? viteManifest[rootRelativeFilePath];
1032
+ if (!entryChunk) {
1033
+ let knownManifestKeys = Object.keys(viteManifest).map((key) => '"' + key + '"').join(", ");
1034
+ throw new Error(
1035
+ `No manifest entry found for "${rootRelativeFilePath}". Known manifest keys: ${knownManifestKeys}`
1036
+ );
1037
+ }
1038
+ return entryChunk;
1039
+ };
1040
+ var getReactRouterManifestBuildAssets = (ctx, viteManifest, entryFilePath, prependedAssetFilePaths = []) => {
1041
+ let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
1042
+ let prependedAssetChunks = prependedAssetFilePaths.map(
1043
+ (filePath) => resolveChunk(ctx, viteManifest, filePath)
1044
+ );
1045
+ let chunks = resolveDependantChunks(viteManifest, [
1046
+ ...prependedAssetChunks,
1047
+ entryChunk
1048
+ ]);
1049
+ return {
1050
+ module: `${ctx.publicPath}${entryChunk.file}`,
1051
+ imports: dedupe(chunks.flatMap((e) => e.imports ?? [])).map((imported) => {
1052
+ return `${ctx.publicPath}${viteManifest[imported].file}`;
1053
+ }) ?? [],
1054
+ css: dedupe(chunks.flatMap((e) => e.css ?? [])).map((href) => {
1055
+ return `${ctx.publicPath}${href}`;
1056
+ }) ?? []
1057
+ };
1058
+ };
1059
+ function resolveDependantChunks(viteManifest, entryChunks) {
1060
+ let chunks = /* @__PURE__ */ new Set();
1061
+ function walk(chunk) {
1062
+ if (chunks.has(chunk)) {
1063
+ return;
1064
+ }
1065
+ chunks.add(chunk);
1066
+ if (chunk.imports) {
1067
+ for (let importKey of chunk.imports) {
1068
+ walk(viteManifest[importKey]);
1069
+ }
1070
+ }
1071
+ }
1072
+ for (let entryChunk of entryChunks) {
1073
+ walk(entryChunk);
1074
+ }
1075
+ return Array.from(chunks);
1076
+ }
1077
+ function dedupe(array2) {
1078
+ return [...new Set(array2)];
1079
+ }
1080
+ var writeFileSafe = async (file, contents) => {
1081
+ await fse2.ensureDir(path4.dirname(file));
1082
+ await fse2.writeFile(file, contents);
1083
+ };
1084
+ var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
1085
+ let entries = await Promise.all(
1086
+ Object.entries(ctx.reactRouterConfig.routes).map(async ([key, route]) => {
1087
+ let sourceExports = await getRouteModuleExports(
1088
+ viteChildCompiler,
1089
+ ctx,
1090
+ route.file
1091
+ );
1092
+ return [key, sourceExports];
1093
+ })
1094
+ );
1095
+ return Object.fromEntries(entries);
1096
+ };
1097
+ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
1098
+ if (!viteChildCompiler) {
1099
+ throw new Error("Vite child compiler not found");
1100
+ }
1101
+ let ssr = true;
1102
+ let { pluginContainer, moduleGraph } = viteChildCompiler;
1103
+ let routePath = path4.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
1104
+ let url3 = resolveFileUrl(ctx, routePath);
1105
+ let resolveId = async () => {
1106
+ let result = await pluginContainer.resolveId(url3, void 0, { ssr });
1107
+ if (!result) throw new Error(`Could not resolve module ID for ${url3}`);
1108
+ return result.id;
1109
+ };
1110
+ let [id2, code] = await Promise.all([
1111
+ resolveId(),
1112
+ readRouteFile?.() ?? fse2.readFile(routePath, "utf-8"),
1113
+ // pluginContainer.transform(...) fails if we don't do this first:
1114
+ moduleGraph.ensureEntryFromUrl(url3, ssr)
1115
+ ]);
1116
+ let transformed = await pluginContainer.transform(code, id2, { ssr });
1117
+ let [, exports2] = (0, import_es_module_lexer.parse)(transformed.code);
1118
+ let exportNames = exports2.map((e) => e.n);
1119
+ return exportNames;
1120
+ };
1121
+ var getServerBundleBuildConfig = (viteUserConfig) => {
1122
+ if (!("__reactRouterServerBundleBuildConfig" in viteUserConfig) || !viteUserConfig.__reactRouterServerBundleBuildConfig) {
1123
+ return null;
1124
+ }
1125
+ return viteUserConfig.__reactRouterServerBundleBuildConfig;
1126
+ };
1127
+ var getServerBuildDirectory = (ctx) => path4.join(
1128
+ ctx.reactRouterConfig.buildDirectory,
1129
+ "server",
1130
+ ...ctx.serverBundleBuildConfig ? [ctx.serverBundleBuildConfig.serverBundleId] : []
1131
+ );
1132
+ var getClientBuildDirectory = (reactRouterConfig) => path4.join(reactRouterConfig.buildDirectory, "client");
1133
+ var defaultEntriesDir = path4.resolve(
1134
+ path4.dirname(require.resolve("@react-router/dev/package.json")),
1135
+ "dist",
1136
+ "config",
1137
+ "defaults"
1138
+ );
1139
+ var defaultEntries = fse2.readdirSync(defaultEntriesDir).map((filename) => path4.join(defaultEntriesDir, filename));
1140
+ invariant(defaultEntries.length > 0, "No default entries found");
1141
+ var reactRouterDevLoadContext = () => ({});
1142
+ var deepFreeze2 = (o) => {
1143
+ Object.freeze(o);
1144
+ let oIsFunction = typeof o === "function";
1145
+ let hasOwnProp = Object.prototype.hasOwnProperty;
1146
+ Object.getOwnPropertyNames(o).forEach(function(prop) {
1147
+ if (hasOwnProp.call(o, prop) && (oIsFunction ? prop !== "caller" && prop !== "callee" && prop !== "arguments" : true) && o[prop] !== null && (typeof o[prop] === "object" || typeof o[prop] === "function") && !Object.isFrozen(o[prop])) {
1148
+ deepFreeze2(o[prop]);
1149
+ }
1150
+ });
1151
+ return o;
1152
+ };
1153
+ var reactRouterVitePlugin = (_config) => {
1154
+ let reactRouterUserConfig = _config ?? {};
1155
+ reactRouterUserConfig = deepFreeze2(reactRouterUserConfig);
1156
+ let viteCommand;
1157
+ let viteUserConfig;
1158
+ let viteConfigEnv;
1159
+ let viteConfig;
1160
+ let cssModulesManifest = {};
1161
+ let viteChildCompiler = null;
1162
+ let routesViteNodeContext = null;
1163
+ let ssrExternals = isInReactRouterMonorepo() ? [
1164
+ // This is only needed within this repo because these packages
1165
+ // are linked to a directory outside of node_modules so Vite
1166
+ // treats them as internal code by default.
1167
+ "react-router",
1168
+ "react-router-dom",
1169
+ "@react-router/architect",
1170
+ "@react-router/cloudflare",
1171
+ "@react-router/dev",
1172
+ "@react-router/express",
1173
+ "@react-router/node",
1174
+ "@react-router/serve"
1175
+ ] : void 0;
1176
+ let ctx;
1177
+ let updatePluginContext = async ({
1178
+ routeConfigChanged = false
1179
+ } = {}) => {
1180
+ let rootDirectory = viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
1181
+ invariant(routesViteNodeContext);
1182
+ let reactRouterConfig = await resolveReactRouterConfig({
1183
+ rootDirectory,
1184
+ reactRouterUserConfig,
1185
+ routeConfigChanged,
1186
+ viteUserConfig,
1187
+ viteCommand,
1188
+ routesViteNodeContext
1189
+ });
1190
+ let { entryClientFilePath, entryServerFilePath } = await resolveEntryFiles({
1191
+ rootDirectory,
1192
+ reactRouterConfig
1193
+ });
1194
+ let publicPath = resolvePublicPath(viteUserConfig);
1195
+ let viteManifestEnabled = viteUserConfig.build?.manifest === true;
1196
+ let ssrBuildCtx = viteConfigEnv.isSsrBuild && viteCommand === "build" ? {
1197
+ isSsrBuild: true,
1198
+ getReactRouterServerManifest: async () => (await generateReactRouterManifestsForBuild()).reactRouterServerManifest,
1199
+ serverBundleBuildConfig: getServerBundleBuildConfig(viteUserConfig)
1200
+ } : { isSsrBuild: false };
1201
+ ctx = {
1202
+ reactRouterConfig,
1203
+ rootDirectory,
1204
+ entryClientFilePath,
1205
+ entryServerFilePath,
1206
+ publicPath,
1207
+ viteManifestEnabled,
1208
+ ...ssrBuildCtx
1209
+ };
1210
+ };
1211
+ let pluginIndex = (pluginName) => {
1212
+ invariant(viteConfig);
1213
+ return viteConfig.plugins.findIndex((plugin2) => plugin2.name === pluginName);
1214
+ };
1215
+ let getServerEntry = async () => {
1216
+ invariant(viteConfig, "viteconfig required to generate the server entry");
1217
+ let routes = ctx.serverBundleBuildConfig ? (
1218
+ // For server bundle builds, the server build should only import the
1219
+ // routes for this bundle rather than importing all routes
1220
+ ctx.serverBundleBuildConfig.routes
1221
+ ) : (
1222
+ // Otherwise, all routes are imported as usual
1223
+ ctx.reactRouterConfig.routes
1224
+ );
1225
+ return `
1226
+ import * as entryServer from ${JSON.stringify(
1227
+ resolveFileUrl(ctx, ctx.entryServerFilePath)
1228
+ )};
1229
+ ${Object.keys(routes).map((key, index) => {
1230
+ let route = routes[key];
1231
+ return `import * as route${index} from ${JSON.stringify(
1232
+ resolveFileUrl(
1233
+ ctx,
1234
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
1235
+ ) + ROUTE_ENTRY_QUERY_STRING
1236
+ )};`;
1237
+ }).join("\n")}
1238
+ export { default as assets } from ${JSON.stringify(serverManifestId)};
1239
+ export const assetsBuildDirectory = ${JSON.stringify(
1240
+ path4.relative(
1241
+ ctx.rootDirectory,
1242
+ getClientBuildDirectory(ctx.reactRouterConfig)
1243
+ )
1244
+ )};
1245
+ export const basename = ${JSON.stringify(ctx.reactRouterConfig.basename)};
1246
+ export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
1247
+ export const isSpaMode = ${!ctx.reactRouterConfig.ssr && ctx.reactRouterConfig.prerender == null};
1248
+ export const publicPath = ${JSON.stringify(ctx.publicPath)};
1249
+ export const entry = { module: entryServer };
1250
+ export const routes = {
1251
+ ${Object.keys(routes).map((key, index) => {
1252
+ let route = routes[key];
1253
+ return `${JSON.stringify(key)}: {
1254
+ id: ${JSON.stringify(route.id)},
1255
+ parentId: ${JSON.stringify(route.parentId)},
1256
+ path: ${JSON.stringify(route.path)},
1257
+ index: ${JSON.stringify(route.index)},
1258
+ caseSensitive: ${JSON.stringify(route.caseSensitive)},
1259
+ module: route${index}
1260
+ }`;
1261
+ }).join(",\n ")}
1262
+ };`;
1263
+ };
1264
+ let loadViteManifest = async (directory) => {
1265
+ let manifestContents = await fse2.readFile(
1266
+ path4.resolve(directory, ".vite", "manifest.json"),
1267
+ "utf-8"
1268
+ );
1269
+ return JSON.parse(manifestContents);
1270
+ };
1271
+ let hasDependency = (name) => {
1272
+ try {
1273
+ return Boolean(require.resolve(name, { paths: [ctx.rootDirectory] }));
1274
+ } catch (err) {
1275
+ return false;
1276
+ }
1277
+ };
1278
+ let getViteManifestAssetPaths = (viteManifest) => {
1279
+ let cssUrlPaths = Object.values(viteManifest).filter((chunk) => chunk.file.endsWith(".css")).map((chunk) => chunk.file);
1280
+ let chunkAssetPaths = Object.values(viteManifest).flatMap(
1281
+ (chunk) => chunk.assets ?? []
1282
+ );
1283
+ return /* @__PURE__ */ new Set([...cssUrlPaths, ...chunkAssetPaths]);
1284
+ };
1285
+ let generateReactRouterManifestsForBuild = async () => {
1286
+ invariant(viteConfig);
1287
+ let viteManifest = await loadViteManifest(
1288
+ getClientBuildDirectory(ctx.reactRouterConfig)
1289
+ );
1290
+ let entry = getReactRouterManifestBuildAssets(
1291
+ ctx,
1292
+ viteManifest,
1293
+ ctx.entryClientFilePath
1294
+ );
1295
+ let browserRoutes = {};
1296
+ let serverRoutes = {};
1297
+ let routeManifestExports = await getRouteManifestModuleExports(
1298
+ viteChildCompiler,
1299
+ ctx
1300
+ );
1301
+ for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
1302
+ let routeFilePath = path4.join(
1303
+ ctx.reactRouterConfig.appDirectory,
1304
+ route.file
1305
+ );
1306
+ let sourceExports = routeManifestExports[key];
1307
+ let isRootRoute = route.parentId === void 0;
1308
+ let routeManifestEntry = {
1309
+ id: route.id,
1310
+ parentId: route.parentId,
1311
+ path: route.path,
1312
+ index: route.index,
1313
+ caseSensitive: route.caseSensitive,
1314
+ hasAction: sourceExports.includes("action"),
1315
+ hasLoader: sourceExports.includes("loader"),
1316
+ hasClientAction: sourceExports.includes("clientAction"),
1317
+ hasClientLoader: sourceExports.includes("clientLoader"),
1318
+ hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
1319
+ ...getReactRouterManifestBuildAssets(
1320
+ ctx,
1321
+ viteManifest,
1322
+ routeFilePath,
1323
+ // If this is the root route, we also need to include assets from the
1324
+ // client entry file as this is a common way for consumers to import
1325
+ // global reset styles, etc.
1326
+ isRootRoute ? [ctx.entryClientFilePath] : []
1327
+ )
1328
+ };
1329
+ browserRoutes[key] = routeManifestEntry;
1330
+ let serverBundleRoutes = ctx.serverBundleBuildConfig?.routes;
1331
+ if (!serverBundleRoutes || serverBundleRoutes[key]) {
1332
+ serverRoutes[key] = routeManifestEntry;
1333
+ }
1334
+ }
1335
+ let fingerprintedValues = { entry, routes: browserRoutes };
1336
+ let version = getHash(JSON.stringify(fingerprintedValues), 8);
1337
+ let manifestPath = path4.posix.join(
1338
+ viteConfig.build.assetsDir,
1339
+ `manifest-${version}.js`
1340
+ );
1341
+ let url3 = `${ctx.publicPath}${manifestPath}`;
1342
+ let nonFingerprintedValues = { url: url3, version };
1343
+ let reactRouterBrowserManifest = {
1344
+ ...fingerprintedValues,
1345
+ ...nonFingerprintedValues
1346
+ };
1347
+ await writeFileSafe(
1348
+ path4.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
1349
+ `window.__reactRouterManifest=${JSON.stringify(
1350
+ reactRouterBrowserManifest
1351
+ )};`
1352
+ );
1353
+ let reactRouterServerManifest = {
1354
+ ...reactRouterBrowserManifest,
1355
+ routes: serverRoutes
1356
+ };
1357
+ return {
1358
+ reactRouterBrowserManifest,
1359
+ reactRouterServerManifest
1360
+ };
1361
+ };
1362
+ let getReactRouterManifestForDev = async () => {
1363
+ let routes = {};
1364
+ let routeManifestExports = await getRouteManifestModuleExports(
1365
+ viteChildCompiler,
1366
+ ctx
1367
+ );
1368
+ for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
1369
+ let sourceExports = routeManifestExports[key];
1370
+ routes[key] = {
1371
+ id: route.id,
1372
+ parentId: route.parentId,
1373
+ path: route.path,
1374
+ index: route.index,
1375
+ caseSensitive: route.caseSensitive,
1376
+ module: combineURLs(
1377
+ ctx.publicPath,
1378
+ `${resolveFileUrl(
1379
+ ctx,
1380
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
1381
+ )}${ROUTE_ENTRY_QUERY_STRING}`
1382
+ ),
1383
+ hasAction: sourceExports.includes("action"),
1384
+ hasLoader: sourceExports.includes("loader"),
1385
+ hasClientAction: sourceExports.includes("clientAction"),
1386
+ hasClientLoader: sourceExports.includes("clientLoader"),
1387
+ hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
1388
+ imports: []
1389
+ };
1390
+ }
1391
+ return {
1392
+ version: String(Math.random()),
1393
+ url: combineURLs(ctx.publicPath, url(browserManifestId)),
1394
+ hmr: {
1395
+ runtime: combineURLs(
1396
+ ctx.publicPath,
1397
+ url(injectHmrRuntimeId)
1398
+ )
1399
+ },
1400
+ entry: {
1401
+ module: combineURLs(
1402
+ ctx.publicPath,
1403
+ resolveFileUrl(ctx, ctx.entryClientFilePath)
1404
+ ),
1405
+ imports: []
1406
+ },
1407
+ routes
1408
+ };
1409
+ };
1410
+ return [
1411
+ {
1412
+ name: "react-router",
1413
+ config: async (_viteUserConfig, _viteConfigEnv) => {
1414
+ await preloadViteEsm();
1415
+ let vite2 = importViteEsmSync();
1416
+ viteUserConfig = _viteUserConfig;
1417
+ viteConfigEnv = _viteConfigEnv;
1418
+ viteCommand = viteConfigEnv.command;
1419
+ routesViteNodeContext = await createContext({
1420
+ root: viteUserConfig.root,
1421
+ mode: viteConfigEnv.mode,
1422
+ server: {
1423
+ watch: viteCommand === "build" ? null : void 0
1424
+ },
1425
+ ssr: {
1426
+ external: ssrExternals
1427
+ }
1428
+ });
1429
+ await updatePluginContext();
1430
+ Object.assign(
1431
+ process.env,
1432
+ vite2.loadEnv(
1433
+ viteConfigEnv.mode,
1434
+ ctx.rootDirectory,
1435
+ // We override default prefix of "VITE_" with a blank string since
1436
+ // we're targeting the server, so we want to load all environment
1437
+ // variables, not just those explicitly marked for the client
1438
+ ""
1439
+ )
1440
+ );
1441
+ let baseRollupOptions = {
1442
+ // Silence Rollup "use client" warnings
1443
+ // Adapted from https://github.com/vitejs/vite-plugin-react/pull/144
1444
+ onwarn(warning, defaultHandler) {
1445
+ if (warning.code === "MODULE_LEVEL_DIRECTIVE" && warning.message.includes("use client")) {
1446
+ return;
1447
+ }
1448
+ if (viteUserConfig.build?.rollupOptions?.onwarn) {
1449
+ viteUserConfig.build.rollupOptions.onwarn(
1450
+ warning,
1451
+ defaultHandler
1452
+ );
1453
+ } else {
1454
+ defaultHandler(warning);
1455
+ }
1456
+ }
1457
+ };
1458
+ return {
1459
+ __reactRouterPluginContext: ctx,
1460
+ appType: viteCommand === "serve" && viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr === false ? "spa" : "custom",
1461
+ ssr: {
1462
+ external: ssrExternals
1463
+ },
1464
+ optimizeDeps: {
1465
+ include: [
1466
+ // Pre-bundle React dependencies to avoid React duplicates,
1467
+ // even if React dependencies are not direct dependencies.
1468
+ // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
1469
+ "react",
1470
+ "react/jsx-runtime",
1471
+ "react/jsx-dev-runtime",
1472
+ "react-dom",
1473
+ "react-dom/client",
1474
+ // Pre-bundle router dependencies to avoid router duplicates.
1475
+ // Mismatching routers cause `Error: You must render this element inside a <Remix> element`.
1476
+ "react-router",
1477
+ "react-router/dom",
1478
+ // Check to avoid "Failed to resolve dependency: react-router-dom, present in 'optimizeDeps.include'"
1479
+ ...hasDependency("react-router-dom") ? ["react-router-dom"] : []
1480
+ ]
1481
+ },
1482
+ esbuild: {
1483
+ jsx: "automatic",
1484
+ jsxDev: viteCommand !== "build"
1485
+ },
1486
+ resolve: {
1487
+ dedupe: [
1488
+ // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
1489
+ "react",
1490
+ "react-dom",
1491
+ // see description for `optimizeDeps.include`
1492
+ "react-router",
1493
+ "react-router/dom",
1494
+ "react-router-dom"
1495
+ ]
1496
+ },
1497
+ base: viteUserConfig.base,
1498
+ // When consumer provides an allow list for files that can be read by
1499
+ // the server, ensure that the default entry files are included.
1500
+ // If we don't do this and a default entry file is used, the server
1501
+ // will throw an error that the file is not allowed to be read.
1502
+ // https://vitejs.dev/config/server-options#server-fs-allow
1503
+ server: viteUserConfig.server?.fs?.allow ? { fs: { allow: defaultEntries } } : void 0,
1504
+ // Vite config options for building
1505
+ ...viteCommand === "build" ? {
1506
+ build: {
1507
+ cssMinify: viteUserConfig.build?.cssMinify ?? true,
1508
+ ...!viteConfigEnv.isSsrBuild ? {
1509
+ manifest: true,
1510
+ outDir: getClientBuildDirectory(ctx.reactRouterConfig),
1511
+ rollupOptions: {
1512
+ ...baseRollupOptions,
1513
+ preserveEntrySignatures: "exports-only",
1514
+ input: [
1515
+ ctx.entryClientFilePath,
1516
+ ...Object.values(ctx.reactRouterConfig.routes).map(
1517
+ (route) => `${path4.resolve(
1518
+ ctx.reactRouterConfig.appDirectory,
1519
+ route.file
1520
+ )}${ROUTE_ENTRY_QUERY_STRING}`
1521
+ )
1522
+ ]
1523
+ }
1524
+ } : {
1525
+ // We move SSR-only assets to client assets. Note that the
1526
+ // SSR build can also emit code-split JS files (e.g. by
1527
+ // dynamic import) under the same assets directory
1528
+ // regardless of "ssrEmitAssets" option, so we also need to
1529
+ // keep these JS files have to be kept as-is.
1530
+ ssrEmitAssets: true,
1531
+ copyPublicDir: false,
1532
+ // Assets in the public directory are only used by the client
1533
+ manifest: true,
1534
+ // We need the manifest to detect SSR-only assets
1535
+ outDir: getServerBuildDirectory(ctx),
1536
+ rollupOptions: {
1537
+ ...baseRollupOptions,
1538
+ preserveEntrySignatures: "exports-only",
1539
+ input: viteUserConfig.build?.rollupOptions?.input ?? serverBuildId,
1540
+ output: {
1541
+ entryFileNames: ctx.reactRouterConfig.serverBuildFile,
1542
+ format: ctx.reactRouterConfig.serverModuleFormat
1543
+ }
1544
+ }
1545
+ }
1546
+ }
1547
+ } : void 0,
1548
+ // Vite config options for SPA preview mode
1549
+ ...viteCommand === "serve" && ctx.reactRouterConfig.ssr === false ? {
1550
+ build: {
1551
+ manifest: true,
1552
+ outDir: getClientBuildDirectory(ctx.reactRouterConfig)
1553
+ }
1554
+ } : void 0
1555
+ };
1556
+ },
1557
+ async configResolved(resolvedViteConfig) {
1558
+ await import_es_module_lexer.init;
1559
+ viteConfig = resolvedViteConfig;
1560
+ invariant(viteConfig);
1561
+ if (!viteConfig.configFile) {
1562
+ throw new Error(
1563
+ "The React Router Vite plugin requires the use of a Vite config file"
1564
+ );
1565
+ }
1566
+ let vite2 = importViteEsmSync();
1567
+ let childCompilerConfigFile = await vite2.loadConfigFromFile(
1568
+ {
1569
+ command: viteConfig.command,
1570
+ mode: viteConfig.mode,
1571
+ isSsrBuild: ctx.isSsrBuild
1572
+ },
1573
+ viteConfig.configFile
1574
+ );
1575
+ invariant(
1576
+ childCompilerConfigFile,
1577
+ "Vite config file was unable to be resolved for React Router child compiler"
1578
+ );
1579
+ let rollupPrePlugins = [
1580
+ { pluginName: "@mdx-js/rollup", displayName: "@mdx-js/rollup" }
1581
+ ];
1582
+ for (let prePlugin of rollupPrePlugins) {
1583
+ let prePluginIndex = pluginIndex(prePlugin.pluginName);
1584
+ if (prePluginIndex >= 0 && prePluginIndex > pluginIndex("react-router")) {
1585
+ throw new Error(
1586
+ `The "${prePlugin.displayName}" plugin should be placed before the React Router plugin in your Vite config file`
1587
+ );
1588
+ }
1589
+ }
1590
+ viteChildCompiler = await vite2.createServer({
1591
+ ...viteUserConfig,
1592
+ mode: viteConfig.mode,
1593
+ server: {
1594
+ watch: viteConfig.command === "build" ? null : void 0,
1595
+ preTransformRequests: false,
1596
+ hmr: false
1597
+ },
1598
+ configFile: false,
1599
+ envFile: false,
1600
+ plugins: [
1601
+ ...(childCompilerConfigFile.config.plugins ?? []).flat().filter(
1602
+ (plugin2) => typeof plugin2 === "object" && plugin2 !== null && "name" in plugin2 && plugin2.name !== "react-router" && plugin2.name !== "react-router-route-exports" && plugin2.name !== "react-router-hmr-updates"
1603
+ )
1604
+ ]
1605
+ });
1606
+ await viteChildCompiler.pluginContainer.buildStart({});
1607
+ },
1608
+ async transform(code, id2) {
1609
+ if (isCssModulesFile(id2)) {
1610
+ cssModulesManifest[id2] = code;
1611
+ }
1612
+ },
1613
+ buildStart() {
1614
+ invariant(viteConfig);
1615
+ if (viteCommand === "build" && viteConfig.mode === "production" && !viteConfig.build.ssr && viteConfig.build.sourcemap) {
1616
+ viteConfig.logger.warn(
1617
+ import_picocolors2.default.yellow(
1618
+ "\n" + import_picocolors2.default.bold(" \u26A0\uFE0F Source maps are enabled in production\n") + [
1619
+ "This makes your server code publicly",
1620
+ "visible in the browser. This is highly",
1621
+ "discouraged! If you insist, ensure that",
1622
+ "you are using environment variables for",
1623
+ "secrets and not hard-coding them in",
1624
+ "your source code."
1625
+ ].map((line) => " " + line).join("\n") + "\n"
1626
+ )
1627
+ );
1628
+ }
1629
+ },
1630
+ async configureServer(viteDevServer) {
1631
+ (0, import_react_router2.unstable_setDevServerHooks)({
1632
+ // Give the request handler access to the critical CSS in dev to avoid a
1633
+ // flash of unstyled content since Vite injects CSS file contents via JS
1634
+ getCriticalCss: async (build, url3) => {
1635
+ return getStylesForUrl({
1636
+ rootDirectory: ctx.rootDirectory,
1637
+ entryClientFilePath: ctx.entryClientFilePath,
1638
+ reactRouterConfig: ctx.reactRouterConfig,
1639
+ viteDevServer,
1640
+ cssModulesManifest,
1641
+ build,
1642
+ url: url3
1643
+ });
1644
+ },
1645
+ // If an error is caught within the request handler, let Vite fix the
1646
+ // stack trace so it maps back to the actual source code
1647
+ processRequestError: (error) => {
1648
+ if (error instanceof Error) {
1649
+ viteDevServer.ssrFixStacktrace(error);
1650
+ }
1651
+ }
1652
+ });
1653
+ viteDevServer.watcher.on("all", async (eventName, rawFilepath) => {
1654
+ let { normalizePath } = importViteEsmSync();
1655
+ let filepath = normalizePath(rawFilepath);
1656
+ let appFileAddedOrRemoved = (eventName === "add" || eventName === "unlink") && filepath.startsWith(
1657
+ normalizePath(ctx.reactRouterConfig.appDirectory)
1658
+ );
1659
+ invariant(viteConfig?.configFile);
1660
+ let viteConfigChanged = eventName === "change" && filepath === normalizePath(viteConfig.configFile);
1661
+ let routeConfigChanged = Boolean(
1662
+ routesViteNodeContext?.devServer?.moduleGraph.getModuleById(
1663
+ filepath
1664
+ )
1665
+ );
1666
+ if (routeConfigChanged || appFileAddedOrRemoved) {
1667
+ routesViteNodeContext?.devServer?.moduleGraph.invalidateAll();
1668
+ routesViteNodeContext?.runner?.moduleCache.clear();
1669
+ }
1670
+ if (appFileAddedOrRemoved || viteConfigChanged || routeConfigChanged) {
1671
+ let lastReactRouterConfig = ctx.reactRouterConfig;
1672
+ await updatePluginContext({ routeConfigChanged });
1673
+ if (!isEqualJson(lastReactRouterConfig, ctx.reactRouterConfig)) {
1674
+ invalidateVirtualModules(viteDevServer);
1675
+ }
1676
+ }
1677
+ });
1678
+ return () => {
1679
+ if (!viteDevServer.config.server.middlewareMode) {
1680
+ viteDevServer.middlewares.use(async (req, res, next) => {
1681
+ try {
1682
+ let build = await viteDevServer.ssrLoadModule(
1683
+ serverBuildId
1684
+ );
1685
+ let handler = (0, import_react_router2.createRequestHandler)(build, "development");
1686
+ let nodeHandler = async (nodeReq, nodeRes) => {
1687
+ let req2 = fromNodeRequest(nodeReq, nodeRes);
1688
+ let res2 = await handler(
1689
+ req2,
1690
+ await reactRouterDevLoadContext(req2)
1691
+ );
1692
+ await toNodeRequest(res2, nodeRes);
1693
+ };
1694
+ await nodeHandler(req, res);
1695
+ } catch (error) {
1696
+ next(error);
1697
+ }
1698
+ });
1699
+ }
1700
+ };
1701
+ },
1702
+ writeBundle: {
1703
+ // After the SSR build is finished, we inspect the Vite manifest for
1704
+ // the SSR build and move server-only assets to client assets directory
1705
+ async handler() {
1706
+ if (!ctx.isSsrBuild) {
1707
+ return;
1708
+ }
1709
+ invariant(viteConfig);
1710
+ let clientBuildDirectory = getClientBuildDirectory(
1711
+ ctx.reactRouterConfig
1712
+ );
1713
+ let serverBuildDirectory = getServerBuildDirectory(ctx);
1714
+ let ssrViteManifest = await loadViteManifest(serverBuildDirectory);
1715
+ let ssrAssetPaths = getViteManifestAssetPaths(ssrViteManifest);
1716
+ let movedAssetPaths = [];
1717
+ for (let ssrAssetPath of ssrAssetPaths) {
1718
+ let src = path4.join(serverBuildDirectory, ssrAssetPath);
1719
+ let dest = path4.join(clientBuildDirectory, ssrAssetPath);
1720
+ if (!fse2.existsSync(dest)) {
1721
+ await fse2.move(src, dest);
1722
+ movedAssetPaths.push(dest);
1723
+ } else {
1724
+ await fse2.remove(src);
1725
+ }
1726
+ }
1727
+ let ssrCssPaths = Object.values(ssrViteManifest).flatMap(
1728
+ (chunk) => chunk.css ?? []
1729
+ );
1730
+ await Promise.all(
1731
+ ssrCssPaths.map(
1732
+ (cssPath) => fse2.remove(path4.join(serverBuildDirectory, cssPath))
1733
+ )
1734
+ );
1735
+ if (movedAssetPaths.length) {
1736
+ viteConfig.logger.info(
1737
+ [
1738
+ "",
1739
+ `${import_picocolors2.default.green("\u2713")} ${movedAssetPaths.length} asset${movedAssetPaths.length > 1 ? "s" : ""} moved from React Router server build to client assets.`,
1740
+ ...movedAssetPaths.map(
1741
+ (movedAssetPath) => import_picocolors2.default.dim(path4.relative(ctx.rootDirectory, movedAssetPath))
1742
+ ),
1743
+ ""
1744
+ ].join("\n")
1745
+ );
1746
+ }
1747
+ if (ctx.reactRouterConfig.prerender != null && ctx.reactRouterConfig.prerender !== false) {
1748
+ await handlePrerender(
1749
+ viteConfig,
1750
+ ctx.reactRouterConfig,
1751
+ serverBuildDirectory,
1752
+ clientBuildDirectory
1753
+ );
1754
+ } else if (!ctx.reactRouterConfig.ssr) {
1755
+ await handleSpaMode(
1756
+ viteConfig,
1757
+ ctx.reactRouterConfig,
1758
+ serverBuildDirectory,
1759
+ clientBuildDirectory
1760
+ );
1761
+ }
1762
+ if (!ctx.reactRouterConfig.ssr) {
1763
+ viteConfig.logger.info(
1764
+ [
1765
+ "Removing the server build in",
1766
+ import_picocolors2.default.green(serverBuildDirectory),
1767
+ "due to ssr:false"
1768
+ ].join(" ")
1769
+ );
1770
+ fse2.removeSync(serverBuildDirectory);
1771
+ }
1772
+ }
1773
+ },
1774
+ async buildEnd() {
1775
+ await viteChildCompiler?.close();
1776
+ await routesViteNodeContext?.devServer?.close();
1777
+ }
1778
+ },
1779
+ {
1780
+ name: "react-router-route-entry",
1781
+ enforce: "pre",
1782
+ async transform(_code, id2, options) {
1783
+ if (!isRouteEntry(id2)) return;
1784
+ let routeModuleId = id2.replace(ROUTE_ENTRY_QUERY_STRING, "");
1785
+ let routeFileName = path4.basename(routeModuleId);
1786
+ let sourceExports = await getRouteModuleExports(
1787
+ viteChildCompiler,
1788
+ ctx,
1789
+ routeModuleId
1790
+ );
1791
+ let reexports = sourceExports.filter(
1792
+ (exportName) => options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName)
1793
+ ).join(", ");
1794
+ return `export { ${reexports} } from "./${routeFileName}";`;
1795
+ }
1796
+ },
1797
+ {
1798
+ name: "react-router-virtual-modules",
1799
+ enforce: "pre",
1800
+ resolveId(id2) {
1801
+ if (vmods.includes(id2)) return resolve2(id2);
1802
+ },
1803
+ async load(id2) {
1804
+ switch (id2) {
1805
+ case resolve2(serverBuildId): {
1806
+ return await getServerEntry();
1807
+ }
1808
+ case resolve2(serverManifestId): {
1809
+ let reactRouterManifest = ctx.isSsrBuild ? await ctx.getReactRouterServerManifest() : await getReactRouterManifestForDev();
1810
+ return `export default ${(0, import_jsesc.default)(reactRouterManifest, {
1811
+ es6: true
1812
+ })};`;
1813
+ }
1814
+ case resolve2(browserManifestId): {
1815
+ if (viteCommand === "build") {
1816
+ throw new Error("This module only exists in development");
1817
+ }
1818
+ let reactRouterManifest = await getReactRouterManifestForDev();
1819
+ let reactRouterManifestString = (0, import_jsesc.default)(reactRouterManifest, {
1820
+ es6: true
1821
+ });
1822
+ return `window.__reactRouterManifest=${reactRouterManifestString};`;
1823
+ }
1824
+ }
1825
+ }
1826
+ },
1827
+ {
1828
+ name: "react-router-dot-server",
1829
+ enforce: "pre",
1830
+ async resolveId(id2, importer, options) {
1831
+ let isOptimizeDeps = viteCommand === "serve" && options?.scan === true;
1832
+ if (isOptimizeDeps || options?.ssr) return;
1833
+ let isResolving = options?.custom?.["react-router-dot-server"] ?? false;
1834
+ if (isResolving) return;
1835
+ options.custom = { ...options.custom, "react-router-dot-server": true };
1836
+ let resolved = await this.resolve(id2, importer, options);
1837
+ if (!resolved) return;
1838
+ let serverFileRE = /\.server(\.[cm]?[jt]sx?)?$/;
1839
+ let serverDirRE = /\/\.server\//;
1840
+ let isDotServer = serverFileRE.test(resolved.id) || serverDirRE.test(resolved.id);
1841
+ if (!isDotServer) return;
1842
+ if (!importer) return;
1843
+ if (viteCommand !== "build" && importer.endsWith(".html")) {
1844
+ return;
1845
+ }
1846
+ let vite2 = importViteEsmSync();
1847
+ let importerShort = vite2.normalizePath(
1848
+ path4.relative(ctx.rootDirectory, importer)
1849
+ );
1850
+ let isRoute = getRoute(ctx.reactRouterConfig, importer);
1851
+ if (isRoute) {
1852
+ let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
1853
+ (xport) => `\`${xport}\``
1854
+ ).join(", ");
1855
+ throw Error(
1856
+ [
1857
+ import_picocolors2.default.red(`Server-only module referenced by client`),
1858
+ "",
1859
+ ` '${id2}' imported by route '${importerShort}'`,
1860
+ "",
1861
+ ` React Router automatically removes server-code from these exports:`,
1862
+ ` ${serverOnlyExports}`,
1863
+ "",
1864
+ ` But other route exports in '${importerShort}' depend on '${id2}'.`,
1865
+ "",
1866
+ " See https://remix.run/docs/en/main/guides/vite#splitting-up-client-and-server-code",
1867
+ ""
1868
+ ].join("\n")
1869
+ );
1870
+ }
1871
+ throw Error(
1872
+ [
1873
+ import_picocolors2.default.red(`Server-only module referenced by client`),
1874
+ "",
1875
+ ` '${id2}' imported by '${importerShort}'`,
1876
+ "",
1877
+ " See https://remix.run/docs/en/main/guides/vite#splitting-up-client-and-server-code",
1878
+ ""
1879
+ ].join("\n")
1880
+ );
1881
+ }
1882
+ },
1883
+ {
1884
+ name: "react-router-dot-client",
1885
+ async transform(code, id2, options) {
1886
+ if (!options?.ssr) return;
1887
+ let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
1888
+ let clientDirRE = /\/\.client\//;
1889
+ if (clientFileRE.test(id2) || clientDirRE.test(id2)) {
1890
+ let exports2 = (0, import_es_module_lexer.parse)(code)[1];
1891
+ return {
1892
+ code: exports2.map(
1893
+ ({ n: name }) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
1894
+ ).join("\n"),
1895
+ map: null
1896
+ };
1897
+ }
1898
+ }
1899
+ },
1900
+ plugin,
1901
+ {
1902
+ name: "react-router-route-exports",
1903
+ async transform(code, id2, options) {
1904
+ let route = getRoute(ctx.reactRouterConfig, id2);
1905
+ if (!route) return;
1906
+ if (!options?.ssr && !ctx.reactRouterConfig.ssr) {
1907
+ let serverOnlyExports = (0, import_es_module_lexer.parse)(code)[1].map((exp) => exp.n).filter((exp) => SERVER_ONLY_ROUTE_EXPORTS.includes(exp));
1908
+ if (serverOnlyExports.length > 0) {
1909
+ let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
1910
+ let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://remix.run/guides/spa-mode for more information.`;
1911
+ throw Error(message);
1912
+ }
1913
+ if (route.id !== "root") {
1914
+ let hasHydrateFallback = (0, import_es_module_lexer.parse)(code)[1].map((exp) => exp.n).some((exp) => exp === "HydrateFallback");
1915
+ if (hasHydrateFallback) {
1916
+ let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://remix.run/guides/spa-mode for more information.`;
1917
+ throw Error(message);
1918
+ }
1919
+ }
1920
+ }
1921
+ let [filepath] = id2.split("?");
1922
+ let ast = (0, import_parser.parse)(code, { sourceType: "module" });
1923
+ if (!options?.ssr) {
1924
+ removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
1925
+ }
1926
+ transform(ast);
1927
+ return generate(ast, {
1928
+ sourceMaps: true,
1929
+ filename: id2,
1930
+ sourceFileName: filepath
1931
+ });
1932
+ }
1933
+ },
1934
+ {
1935
+ name: "react-router-inject-hmr-runtime",
1936
+ enforce: "pre",
1937
+ resolveId(id2) {
1938
+ if (id2 === injectHmrRuntimeId)
1939
+ return resolve2(injectHmrRuntimeId);
1940
+ },
1941
+ async load(id2) {
1942
+ if (id2 !== resolve2(injectHmrRuntimeId)) return;
1943
+ return [
1944
+ `import RefreshRuntime from "${hmrRuntimeId}"`,
1945
+ "RefreshRuntime.injectIntoGlobalHook(window)",
1946
+ "window.$RefreshReg$ = () => {}",
1947
+ "window.$RefreshSig$ = () => (type) => type",
1948
+ "window.__vite_plugin_react_preamble_installed__ = true"
1949
+ ].join("\n");
1950
+ }
1951
+ },
1952
+ {
1953
+ name: "react-router-hmr-runtime",
1954
+ enforce: "pre",
1955
+ resolveId(id2) {
1956
+ if (id2 === hmrRuntimeId) return resolve2(hmrRuntimeId);
1957
+ },
1958
+ async load(id2) {
1959
+ if (id2 !== resolve2(hmrRuntimeId)) return;
1960
+ let reactRefreshDir = path4.dirname(
1961
+ require.resolve("react-refresh/package.json")
1962
+ );
1963
+ let reactRefreshRuntimePath = path4.join(
1964
+ reactRefreshDir,
1965
+ "cjs/react-refresh-runtime.development.js"
1966
+ );
1967
+ return [
1968
+ "const exports = {}",
1969
+ await fse2.readFile(reactRefreshRuntimePath, "utf8"),
1970
+ await fse2.readFile(
1971
+ require.resolve("./static/refresh-utils.cjs"),
1972
+ "utf8"
1973
+ ),
1974
+ "export default exports"
1975
+ ].join("\n");
1976
+ }
1977
+ },
1978
+ {
1979
+ name: "react-router-react-refresh-babel",
1980
+ async transform(code, id2, options) {
1981
+ if (viteCommand !== "serve") return;
1982
+ if (id2.includes("/node_modules/")) return;
1983
+ let [filepath] = id2.split("?");
1984
+ let extensionsRE = /\.(jsx?|tsx?|mdx?)$/;
1985
+ if (!extensionsRE.test(filepath)) return;
1986
+ let devRuntime = "react/jsx-dev-runtime";
1987
+ let ssr = options?.ssr === true;
1988
+ let isJSX = filepath.endsWith("x");
1989
+ let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
1990
+ if (!useFastRefresh) return;
1991
+ if (isRouteEntry(id2)) {
1992
+ return { code: addRefreshWrapper(ctx.reactRouterConfig, code, id2) };
1993
+ }
1994
+ let result = await babel.transformAsync(code, {
1995
+ babelrc: false,
1996
+ configFile: false,
1997
+ filename: id2,
1998
+ sourceFileName: filepath,
1999
+ parserOpts: {
2000
+ sourceType: "module",
2001
+ allowAwaitOutsideFunction: true
2002
+ },
2003
+ plugins: [[require("react-refresh/babel"), { skipEnvCheck: true }]],
2004
+ sourceMaps: true
2005
+ });
2006
+ if (result === null) return;
2007
+ code = result.code;
2008
+ let refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
2009
+ if (refreshContentRE.test(code)) {
2010
+ code = addRefreshWrapper(ctx.reactRouterConfig, code, id2);
2011
+ }
2012
+ return { code, map: result.map };
2013
+ }
2014
+ },
2015
+ {
2016
+ name: "react-router-hmr-updates",
2017
+ async handleHotUpdate({ server, file, modules, read }) {
2018
+ let route = getRoute(ctx.reactRouterConfig, file);
2019
+ let hmrEventData = { route: null };
2020
+ if (route) {
2021
+ let serverManifest = (await server.ssrLoadModule(serverManifestId)).default;
2022
+ let oldRouteMetadata = serverManifest.routes[route.id];
2023
+ let newRouteMetadata = await getRouteMetadata(
2024
+ ctx,
2025
+ viteChildCompiler,
2026
+ route,
2027
+ read
2028
+ );
2029
+ hmrEventData.route = newRouteMetadata;
2030
+ if (!oldRouteMetadata || [
2031
+ "hasLoader",
2032
+ "hasClientLoader",
2033
+ "hasAction",
2034
+ "hasClientAction",
2035
+ "hasErrorBoundary"
2036
+ ].some((key) => oldRouteMetadata[key] !== newRouteMetadata[key])) {
2037
+ invalidateVirtualModules(server);
2038
+ }
2039
+ }
2040
+ server.hot.send({
2041
+ type: "custom",
2042
+ event: "react-router:hmr",
2043
+ data: hmrEventData
2044
+ });
2045
+ return modules;
2046
+ }
2047
+ }
2048
+ ];
2049
+ };
2050
+ function isInReactRouterMonorepo() {
2051
+ let serverRuntimePath = path4.dirname(
2052
+ require.resolve("@react-router/node/package.json")
2053
+ );
2054
+ let serverRuntimeParentDir = path4.basename(
2055
+ path4.resolve(serverRuntimePath, "..")
2056
+ );
2057
+ return serverRuntimeParentDir === "packages";
2058
+ }
2059
+ function isEqualJson(v1, v2) {
2060
+ return JSON.stringify(v1) === JSON.stringify(v2);
2061
+ }
2062
+ function addRefreshWrapper(reactRouterConfig, code, id2) {
2063
+ let route = getRoute(reactRouterConfig, id2);
2064
+ let acceptExports = route || isRouteEntry(id2) ? [
2065
+ "clientAction",
2066
+ "clientLoader",
2067
+ "handle",
2068
+ "meta",
2069
+ "links",
2070
+ "shouldRevalidate"
2071
+ ] : [];
2072
+ return "\n\n" + withCommentBoundaries(
2073
+ "REACT REFRESH HEADER",
2074
+ REACT_REFRESH_HEADER.replaceAll("__SOURCE__", JSON.stringify(id2))
2075
+ ) + "\n\n" + withCommentBoundaries("REACT REFRESH BODY", code) + "\n\n" + withCommentBoundaries(
2076
+ "REACT REFRESH FOOTER",
2077
+ REACT_REFRESH_FOOTER.replaceAll("__SOURCE__", JSON.stringify(id2)).replaceAll("__ACCEPT_EXPORTS__", JSON.stringify(acceptExports)).replaceAll("__ROUTE_ID__", JSON.stringify(route?.id))
2078
+ ) + "\n";
2079
+ }
2080
+ function withCommentBoundaries(label, text) {
2081
+ let begin = `// [BEGIN] ${label} `;
2082
+ begin += "-".repeat(80 - begin.length);
2083
+ let end = `// [END] ${label} `;
2084
+ end += "-".repeat(80 - end.length);
2085
+ return `${begin}
2086
+ ${text}
2087
+ ${end}`;
2088
+ }
2089
+ var REACT_REFRESH_HEADER = `
2090
+ import RefreshRuntime from "${hmrRuntimeId}";
2091
+
2092
+ const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
2093
+ let prevRefreshReg;
2094
+ let prevRefreshSig;
2095
+
2096
+ if (import.meta.hot && !inWebWorker) {
2097
+ if (!window.__vite_plugin_react_preamble_installed__) {
2098
+ throw new Error(
2099
+ "React Router Vite plugin can't detect preamble. Something is wrong."
2100
+ );
2101
+ }
2102
+
2103
+ prevRefreshReg = window.$RefreshReg$;
2104
+ prevRefreshSig = window.$RefreshSig$;
2105
+ window.$RefreshReg$ = (type, id) => {
2106
+ RefreshRuntime.register(type, __SOURCE__ + " " + id)
2107
+ };
2108
+ window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
2109
+ }`.trim();
2110
+ var REACT_REFRESH_FOOTER = `
2111
+ if (import.meta.hot && !inWebWorker) {
2112
+ window.$RefreshReg$ = prevRefreshReg;
2113
+ window.$RefreshSig$ = prevRefreshSig;
2114
+ RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
2115
+ RefreshRuntime.registerExportsForReactRefresh(__SOURCE__, currentExports);
2116
+ import.meta.hot.accept((nextExports) => {
2117
+ if (!nextExports) return;
2118
+ __ROUTE_ID__ && window.__reactRouterRouteModuleUpdates.set(__ROUTE_ID__, nextExports);
2119
+ const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports, __ACCEPT_EXPORTS__);
2120
+ if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
2121
+ });
2122
+ });
2123
+ }`.trim();
2124
+ function getRoute(pluginConfig, file) {
2125
+ let vite2 = importViteEsmSync();
2126
+ let routePath = vite2.normalizePath(
2127
+ path4.relative(pluginConfig.appDirectory, file)
2128
+ );
2129
+ let route = Object.values(pluginConfig.routes).find(
2130
+ (r) => vite2.normalizePath(r.file) === routePath
2131
+ );
2132
+ return route;
2133
+ }
2134
+ async function getRouteMetadata(ctx, viteChildCompiler, route, readRouteFile) {
2135
+ let sourceExports = await getRouteModuleExports(
2136
+ viteChildCompiler,
2137
+ ctx,
2138
+ route.file,
2139
+ readRouteFile
2140
+ );
2141
+ let info = {
2142
+ id: route.id,
2143
+ parentId: route.parentId,
2144
+ path: route.path,
2145
+ index: route.index,
2146
+ caseSensitive: route.caseSensitive,
2147
+ url: combineURLs(
2148
+ ctx.publicPath,
2149
+ "/" + path4.relative(
2150
+ ctx.rootDirectory,
2151
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
2152
+ )
2153
+ ),
2154
+ module: combineURLs(
2155
+ ctx.publicPath,
2156
+ `${resolveFileUrl(
2157
+ ctx,
2158
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
2159
+ )}?import`
2160
+ ),
2161
+ // Ensure the Vite dev server responds with a JS module
2162
+ hasAction: sourceExports.includes("action"),
2163
+ hasClientAction: sourceExports.includes("clientAction"),
2164
+ hasLoader: sourceExports.includes("loader"),
2165
+ hasClientLoader: sourceExports.includes("clientLoader"),
2166
+ hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
2167
+ imports: []
2168
+ };
2169
+ return info;
2170
+ }
2171
+ async function getPrerenderBuildAndHandler(viteConfig, reactRouterConfig, serverBuildDirectory) {
2172
+ let serverBuildPath = path4.join(
2173
+ serverBuildDirectory,
2174
+ reactRouterConfig.serverBuildFile
2175
+ );
2176
+ let build = await import(url2.pathToFileURL(serverBuildPath).toString());
2177
+ let { createRequestHandler: createHandler } = await import("react-router");
2178
+ return {
2179
+ build,
2180
+ handler: createHandler(build, viteConfig.mode)
2181
+ };
2182
+ }
2183
+ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
2184
+ let { handler } = await getPrerenderBuildAndHandler(
2185
+ viteConfig,
2186
+ reactRouterConfig,
2187
+ serverBuildDirectory
2188
+ );
2189
+ let request = new Request(`http://localhost${reactRouterConfig.basename}`);
2190
+ let response = await handler(request);
2191
+ let html = await response.text();
2192
+ validatePrerenderedResponse(response, html, "SPA Mode", "/");
2193
+ validatePrerenderedHtml(html, "SPA Mode");
2194
+ await fse2.writeFile(path4.join(clientBuildDirectory, "index.html"), html);
2195
+ viteConfig.logger.info(
2196
+ "SPA Mode: index.html has been written to your " + import_picocolors2.default.bold(path4.relative(process.cwd(), clientBuildDirectory)) + " directory"
2197
+ );
2198
+ }
2199
+ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
2200
+ let { build, handler } = await getPrerenderBuildAndHandler(
2201
+ viteConfig,
2202
+ reactRouterConfig,
2203
+ serverBuildDirectory
2204
+ );
2205
+ let routes = createPrerenderRoutes(build.routes);
2206
+ let routesToPrerender;
2207
+ if (typeof reactRouterConfig.prerender === "boolean") {
2208
+ invariant(reactRouterConfig.prerender, "Expected prerender:true");
2209
+ routesToPrerender = determineStaticPrerenderRoutes(
2210
+ routes,
2211
+ viteConfig,
2212
+ true
2213
+ );
2214
+ } else if (typeof reactRouterConfig.prerender === "function") {
2215
+ routesToPrerender = await reactRouterConfig.prerender({
2216
+ getStaticPaths: () => determineStaticPrerenderRoutes(routes, viteConfig, false)
2217
+ });
2218
+ } else {
2219
+ routesToPrerender = reactRouterConfig.prerender || ["/"];
2220
+ }
2221
+ let headers = {
2222
+ // Header that can be used in the loader to know if you're running at
2223
+ // build time or runtime
2224
+ "X-React-Router-Prerender": "yes"
2225
+ };
2226
+ for (let path5 of routesToPrerender) {
2227
+ let matches = (0, import_react_router2.matchRoutes)(routes, path5);
2228
+ let hasLoaders = matches?.some((m) => m.route.loader);
2229
+ let data;
2230
+ if (hasLoaders) {
2231
+ data = await prerenderData(
2232
+ handler,
2233
+ path5,
2234
+ clientBuildDirectory,
2235
+ reactRouterConfig,
2236
+ viteConfig,
2237
+ { headers }
2238
+ );
2239
+ }
2240
+ let leafRoute = matches ? matches[matches.length - 1].route : null;
2241
+ let manifestRoute = leafRoute ? build.routes[leafRoute.id]?.module : null;
2242
+ let isResourceRoute = manifestRoute && !manifestRoute.default && !manifestRoute.ErrorBoundary && manifestRoute.loader;
2243
+ if (isResourceRoute) {
2244
+ await prerenderResourceRoute(
2245
+ handler,
2246
+ path5,
2247
+ clientBuildDirectory,
2248
+ reactRouterConfig,
2249
+ viteConfig,
2250
+ { headers }
2251
+ );
2252
+ } else {
2253
+ await prerenderRoute(
2254
+ handler,
2255
+ path5,
2256
+ clientBuildDirectory,
2257
+ reactRouterConfig,
2258
+ viteConfig,
2259
+ data ? { headers: { ...headers, "X-React-Router-Prerender-Data": data } } : { headers }
2260
+ );
2261
+ }
2262
+ }
2263
+ await prerenderManifest(
2264
+ build,
2265
+ clientBuildDirectory,
2266
+ reactRouterConfig,
2267
+ viteConfig
2268
+ );
2269
+ }
2270
+ function determineStaticPrerenderRoutes(routes, viteConfig, isBooleanUsage = false) {
2271
+ let paths = ["/"];
2272
+ let paramRoutes = [];
2273
+ function recurse(subtree, prefix = "") {
2274
+ for (let route of subtree) {
2275
+ let newPath = [prefix, route.path].join("/").replace(/\/\/+/g, "/");
2276
+ if (route.path) {
2277
+ let segments = route.path.split("/");
2278
+ if (segments.some((s) => s.startsWith(":") || s === "*")) {
2279
+ paramRoutes.push(route.path);
2280
+ } else {
2281
+ paths.push(newPath);
2282
+ }
2283
+ }
2284
+ if (route.children) {
2285
+ recurse(route.children, newPath);
2286
+ }
2287
+ }
2288
+ }
2289
+ recurse(routes);
2290
+ if (isBooleanUsage && paramRoutes.length > 0) {
2291
+ viteConfig.logger.warn(
2292
+ [
2293
+ "\u26A0\uFE0F Paths with dynamic/splat params cannot be prerendered when using `prerender: true`.",
2294
+ "You may want to use the `prerender()` API to prerender the following paths:",
2295
+ ...paramRoutes.map((p) => " - " + p)
2296
+ ].join("\n")
2297
+ );
2298
+ }
2299
+ return paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1"));
2300
+ }
2301
+ async function prerenderData(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
2302
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
2303
+ let request = new Request(`http://localhost${normalizedPath}`, requestInit);
2304
+ let response = await handler(request);
2305
+ let data = await response.text();
2306
+ validatePrerenderedResponse(response, data, "Prerender", normalizedPath);
2307
+ let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2308
+ let outfile = path4.join(outdir, ...normalizedPath.split("/"));
2309
+ await fse2.ensureDir(path4.dirname(outfile));
2310
+ await fse2.outputFile(outfile, data);
2311
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2312
+ return data;
2313
+ }
2314
+ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
2315
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(
2316
+ /\/\/+/g,
2317
+ "/"
2318
+ );
2319
+ let request = new Request(`http://localhost${normalizedPath}`, requestInit);
2320
+ let response = await handler(request);
2321
+ let html = await response.text();
2322
+ validatePrerenderedResponse(response, html, "Prerender", normalizedPath);
2323
+ if (!reactRouterConfig.ssr) {
2324
+ validatePrerenderedHtml(html, "Prerender");
2325
+ }
2326
+ let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2327
+ let outfile = path4.join(outdir, ...normalizedPath.split("/"), "index.html");
2328
+ await fse2.ensureDir(path4.dirname(outfile));
2329
+ await fse2.outputFile(outfile, html);
2330
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2331
+ }
2332
+ async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
2333
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
2334
+ let request = new Request(`http://localhost${normalizedPath}`, requestInit);
2335
+ let response = await handler(request);
2336
+ let text = await response.text();
2337
+ validatePrerenderedResponse(response, text, "Prerender", normalizedPath);
2338
+ let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2339
+ let outfile = path4.join(outdir, ...normalizedPath.split("/"));
2340
+ await fse2.ensureDir(path4.dirname(outfile));
2341
+ await fse2.outputFile(outfile, text);
2342
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2343
+ }
2344
+ async function prerenderManifest(build, clientBuildDirectory, reactRouterConfig, viteConfig) {
2345
+ let normalizedPath = `${reactRouterConfig.basename}/__manifest`.replace(
2346
+ /\/\/+/g,
2347
+ "/"
2348
+ );
2349
+ let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2350
+ let outfile = path4.join(outdir, ...normalizedPath.split("/"));
2351
+ await fse2.ensureDir(path4.dirname(outfile));
2352
+ let manifestData = JSON.stringify(build.assets.routes);
2353
+ await fse2.outputFile(outfile, manifestData);
2354
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2355
+ }
2356
+ function validatePrerenderedResponse(response, html, prefix, path5) {
2357
+ if (response.status !== 200) {
2358
+ throw new Error(
2359
+ `${prefix}: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${path5}\` path.
2360
+ ${html}`
2361
+ );
2362
+ }
2363
+ }
2364
+ function validatePrerenderedHtml(html, prefix) {
2365
+ if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
2366
+ throw new Error(
2367
+ `${prefix}: Did you forget to include <Scripts/> in your root route? Your pre-rendered HTML files cannot hydrate without \`<Scripts />\`.`
2368
+ );
2369
+ }
2370
+ }
2371
+ function groupRoutesByParentId2(manifest) {
2372
+ let routes = {};
2373
+ Object.values(manifest).forEach((route) => {
2374
+ if (route) {
2375
+ let parentId = route.parentId || "";
2376
+ if (!routes[parentId]) {
2377
+ routes[parentId] = [];
2378
+ }
2379
+ routes[parentId].push(route);
2380
+ }
2381
+ });
2382
+ return routes;
2383
+ }
2384
+ function createPrerenderRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) {
2385
+ return (routesByParentId[parentId] || []).map((route) => {
2386
+ let commonRoute = {
2387
+ // Always include root due to default boundaries
2388
+ hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
2389
+ id: route.id,
2390
+ path: route.path,
2391
+ loader: route.module.loader ? () => null : void 0,
2392
+ action: void 0,
2393
+ handle: route.module.handle
2394
+ };
2395
+ return route.index ? {
2396
+ index: true,
2397
+ ...commonRoute
2398
+ } : {
2399
+ caseSensitive: route.caseSensitive,
2400
+ children: createPrerenderRoutes(manifest, route.id, routesByParentId),
2401
+ ...commonRoute
2402
+ };
2403
+ });
2404
+ }
2405
+ // Annotate the CommonJS export names for ESM import in node:
2406
+ 0 && (module.exports = {
2407
+ reactRouter
2408
+ });