@c0va23/react-router-dev 7.8.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.js ADDED
@@ -0,0 +1,4914 @@
1
+ /**
2
+ * @c0va23/react-router-dev v7.8.3-alpha.1
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ "use strict";
12
+ 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);
39
+
40
+ // vite.ts
41
+ var vite_exports = {};
42
+ __export(vite_exports, {
43
+ reactRouter: () => reactRouterVitePlugin
44
+ });
45
+ module.exports = __toCommonJS(vite_exports);
46
+
47
+ // vite/plugin.ts
48
+ var import_node_crypto = require("crypto");
49
+ var import_node_fs2 = require("fs");
50
+ var import_promises2 = require("fs/promises");
51
+ var path6 = __toESM(require("path"));
52
+ var url = __toESM(require("url"));
53
+ var babel = __toESM(require("@babel/core"));
54
+ var import_react_router2 = require("react-router");
55
+ var import_es_module_lexer = require("es-module-lexer");
56
+ var import_pick3 = __toESM(require("lodash/pick"));
57
+ var import_jsesc = __toESM(require("jsesc"));
58
+ var import_picocolors3 = __toESM(require("picocolors"));
59
+ var import_kebabCase = __toESM(require("lodash/kebabCase"));
60
+
61
+ // typegen/index.ts
62
+ var import_promises = __toESM(require("fs/promises"));
63
+ var Path4 = __toESM(require("pathe"));
64
+ var import_picocolors2 = require("picocolors");
65
+
66
+ // config/config.ts
67
+ var import_node_fs = __toESM(require("fs"));
68
+ var import_node_child_process = require("child_process");
69
+ var import_package_json = __toESM(require("@npmcli/package-json"));
70
+
71
+ // vite/vite.ts
72
+ var import_pathe2 = __toESM(require("pathe"));
73
+
74
+ // invariant.ts
75
+ function invariant(value, message) {
76
+ if (value === false || value === null || typeof value === "undefined") {
77
+ console.error(
78
+ "The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose"
79
+ );
80
+ throw new Error(message);
81
+ }
82
+ }
83
+
84
+ // config/is-react-router-repo.ts
85
+ var import_pathe = __toESM(require("pathe"));
86
+ function isReactRouterRepo() {
87
+ let serverRuntimePath = import_pathe.default.dirname(
88
+ require.resolve("@react-router/node/package.json")
89
+ );
90
+ let serverRuntimeParentDir = import_pathe.default.basename(
91
+ import_pathe.default.resolve(serverRuntimePath, "..")
92
+ );
93
+ return serverRuntimeParentDir === "packages";
94
+ }
95
+
96
+ // vite/vite.ts
97
+ var vite;
98
+ var viteImportSpecifier = isReactRouterRepo() ? (
99
+ // Support testing against different versions of Vite by ensuring that Vite
100
+ // is resolved from the current working directory when running within this
101
+ // repo. If we don't do this, Vite will always be imported relative to this
102
+ // file, which means that it will always resolve to Vite 6.
103
+ `file:///${import_pathe2.default.normalize(
104
+ require.resolve("vite/package.json", { paths: [process.cwd()] })
105
+ ).replace("package.json", "dist/node/index.js")}`
106
+ ) : "vite";
107
+ async function preloadVite() {
108
+ vite = await import(viteImportSpecifier);
109
+ }
110
+ function getVite() {
111
+ invariant(vite, "getVite() called before preloadVite()");
112
+ return vite;
113
+ }
114
+
115
+ // vite/ssr-externals.ts
116
+ var ssrExternals = isReactRouterRepo() ? [
117
+ // This is only needed within this repo because these packages
118
+ // are linked to a directory outside of node_modules so Vite
119
+ // treats them as internal code by default.
120
+ "react-router",
121
+ "react-router-dom",
122
+ "@react-router/architect",
123
+ "@react-router/cloudflare",
124
+ "@react-router/dev",
125
+ "@react-router/express",
126
+ "@react-router/node",
127
+ "@react-router/serve"
128
+ ] : void 0;
129
+
130
+ // vite/vite-node.ts
131
+ async function createContext({
132
+ root,
133
+ mode,
134
+ customLogger
135
+ }) {
136
+ await preloadVite();
137
+ const vite2 = getVite();
138
+ const [{ ViteNodeServer }, { ViteNodeRunner }, { installSourcemapsSupport }] = await Promise.all([
139
+ import("vite-node/server"),
140
+ import("vite-node/client"),
141
+ import("vite-node/source-map")
142
+ ]);
143
+ const devServer = await vite2.createServer({
144
+ root,
145
+ mode,
146
+ customLogger,
147
+ server: {
148
+ preTransformRequests: false,
149
+ hmr: false,
150
+ watch: null
151
+ },
152
+ ssr: {
153
+ external: ssrExternals
154
+ },
155
+ optimizeDeps: {
156
+ noDiscovery: true
157
+ },
158
+ css: {
159
+ // This empty PostCSS config object prevents the PostCSS config file from
160
+ // being loaded. We don't need it in a React Router config context, and
161
+ // there's also an issue in Vite 5 when using a .ts PostCSS config file in
162
+ // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers
163
+ // can work around this in their own Vite config file, but they can't
164
+ // configure this internal usage of vite-node.
165
+ postcss: {}
166
+ },
167
+ configFile: false,
168
+ envFile: false,
169
+ plugins: []
170
+ });
171
+ await devServer.pluginContainer.buildStart({});
172
+ const server = new ViteNodeServer(devServer);
173
+ installSourcemapsSupport({
174
+ getSourceMap: (source) => server.getSourceMap(source)
175
+ });
176
+ const runner = new ViteNodeRunner({
177
+ root: devServer.config.root,
178
+ base: devServer.config.base,
179
+ fetchModule(id) {
180
+ return server.fetchModule(id);
181
+ },
182
+ resolveId(id, importer) {
183
+ return server.resolveId(id, importer);
184
+ }
185
+ });
186
+ return { devServer, server, runner };
187
+ }
188
+
189
+ // config/config.ts
190
+ var import_pathe3 = __toESM(require("pathe"));
191
+ var import_chokidar = __toESM(require("chokidar"));
192
+ var import_picocolors = __toESM(require("picocolors"));
193
+ var import_pick2 = __toESM(require("lodash/pick"));
194
+ var import_omit = __toESM(require("lodash/omit"));
195
+ var import_cloneDeep = __toESM(require("lodash/cloneDeep"));
196
+ var import_isEqual = __toESM(require("lodash/isEqual"));
197
+
198
+ // config/routes.ts
199
+ var Path = __toESM(require("pathe"));
200
+ var v = __toESM(require("valibot"));
201
+ var import_pick = __toESM(require("lodash/pick"));
202
+ function setAppDirectory(directory) {
203
+ globalThis.__reactRouterAppDirectory = directory;
204
+ }
205
+ var routeConfigEntrySchema = v.pipe(
206
+ v.custom((value) => {
207
+ return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
208
+ }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
209
+ v.object({
210
+ id: v.optional(
211
+ v.pipe(
212
+ v.string(),
213
+ v.notValue("root", "A route cannot use the reserved id 'root'.")
214
+ )
215
+ ),
216
+ path: v.optional(v.string()),
217
+ index: v.optional(v.boolean()),
218
+ caseSensitive: v.optional(v.boolean()),
219
+ file: v.string(),
220
+ children: v.optional(v.array(v.lazy(() => routeConfigEntrySchema)))
221
+ })
222
+ );
223
+ var resolvedRouteConfigSchema = v.array(routeConfigEntrySchema);
224
+ function validateRouteConfig({
225
+ routeConfigFile,
226
+ routeConfig
227
+ }) {
228
+ if (!routeConfig) {
229
+ return {
230
+ valid: false,
231
+ message: `Route config must be the default export in "${routeConfigFile}".`
232
+ };
233
+ }
234
+ if (!Array.isArray(routeConfig)) {
235
+ return {
236
+ valid: false,
237
+ message: `Route config in "${routeConfigFile}" must be an array.`
238
+ };
239
+ }
240
+ let { issues } = v.safeParse(resolvedRouteConfigSchema, routeConfig);
241
+ if (issues?.length) {
242
+ let { root, nested } = v.flatten(issues);
243
+ return {
244
+ valid: false,
245
+ message: [
246
+ `Route config in "${routeConfigFile}" is invalid.`,
247
+ root ? `${root}` : [],
248
+ nested ? Object.entries(nested).map(
249
+ ([path7, message]) => `Path: routes.${path7}
250
+ ${message}`
251
+ ) : []
252
+ ].flat().join("\n\n")
253
+ };
254
+ }
255
+ return {
256
+ valid: true,
257
+ routeConfig
258
+ };
259
+ }
260
+ function configRoutesToRouteManifest(appDirectory, routes) {
261
+ let routeManifest = {};
262
+ function walk(route, parentId) {
263
+ let id = route.id || createRouteId(route.file);
264
+ let manifestItem = {
265
+ id,
266
+ parentId,
267
+ file: Path.isAbsolute(route.file) ? Path.relative(appDirectory, route.file) : route.file,
268
+ path: route.path,
269
+ index: route.index,
270
+ caseSensitive: route.caseSensitive
271
+ };
272
+ if (routeManifest.hasOwnProperty(id)) {
273
+ throw new Error(
274
+ `Unable to define routes with duplicate route id: "${id}"`
275
+ );
276
+ }
277
+ routeManifest[id] = manifestItem;
278
+ if (route.children) {
279
+ for (let child of route.children) {
280
+ walk(child, id);
281
+ }
282
+ }
283
+ }
284
+ for (let route of routes) {
285
+ walk(route);
286
+ }
287
+ return routeManifest;
288
+ }
289
+ function createRouteId(file) {
290
+ return Path.normalize(stripFileExtension(file));
291
+ }
292
+ function stripFileExtension(file) {
293
+ return file.replace(/\.[a-z0-9]+$/i, "");
294
+ }
295
+
296
+ // cli/detectPackageManager.ts
297
+ var detectPackageManager = () => {
298
+ let { npm_config_user_agent } = process.env;
299
+ if (!npm_config_user_agent) return void 0;
300
+ try {
301
+ let pkgManager = npm_config_user_agent.split("/")[0];
302
+ if (pkgManager === "npm") return "npm";
303
+ if (pkgManager === "pnpm") return "pnpm";
304
+ if (pkgManager === "yarn") return "yarn";
305
+ if (pkgManager === "bun") return "bun";
306
+ return void 0;
307
+ } catch {
308
+ return void 0;
309
+ }
310
+ };
311
+
312
+ // config/config.ts
313
+ var excludedConfigPresetKeys = ["presets"];
314
+ var branchRouteProperties = [
315
+ "id",
316
+ "path",
317
+ "file",
318
+ "index"
319
+ ];
320
+ var configRouteToBranchRoute = (configRoute) => (0, import_pick2.default)(configRoute, branchRouteProperties);
321
+ var mergeReactRouterConfig = (...configs) => {
322
+ let reducer = (configA, configB) => {
323
+ let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
324
+ return {
325
+ ...configA,
326
+ ...configB,
327
+ ...mergeRequired("buildEnd") ? {
328
+ buildEnd: async (...args) => {
329
+ await Promise.all([
330
+ configA.buildEnd?.(...args),
331
+ configB.buildEnd?.(...args)
332
+ ]);
333
+ }
334
+ } : {},
335
+ ...mergeRequired("future") ? {
336
+ future: {
337
+ ...configA.future,
338
+ ...configB.future
339
+ }
340
+ } : {},
341
+ ...mergeRequired("presets") ? {
342
+ presets: [...configA.presets ?? [], ...configB.presets ?? []]
343
+ } : {}
344
+ };
345
+ };
346
+ return configs.reduce(reducer, {});
347
+ };
348
+ var deepFreeze = (o) => {
349
+ Object.freeze(o);
350
+ let oIsFunction = typeof o === "function";
351
+ let hasOwnProp = Object.prototype.hasOwnProperty;
352
+ Object.getOwnPropertyNames(o).forEach(function(prop) {
353
+ 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])) {
354
+ deepFreeze(o[prop]);
355
+ }
356
+ });
357
+ return o;
358
+ };
359
+ function ok(value) {
360
+ return { ok: true, value };
361
+ }
362
+ function err(error) {
363
+ return { ok: false, error };
364
+ }
365
+ async function resolveConfig({
366
+ root,
367
+ viteNodeContext,
368
+ reactRouterConfigFile,
369
+ skipRoutes,
370
+ validateConfig
371
+ }) {
372
+ let reactRouterUserConfig = {};
373
+ if (reactRouterConfigFile) {
374
+ try {
375
+ if (!import_node_fs.default.existsSync(reactRouterConfigFile)) {
376
+ return err(`${reactRouterConfigFile} no longer exists`);
377
+ }
378
+ let configModule = await viteNodeContext.runner.executeFile(
379
+ reactRouterConfigFile
380
+ );
381
+ if (configModule.default === void 0) {
382
+ return err(`${reactRouterConfigFile} must provide a default export`);
383
+ }
384
+ if (typeof configModule.default !== "object") {
385
+ return err(`${reactRouterConfigFile} must export a config`);
386
+ }
387
+ reactRouterUserConfig = configModule.default;
388
+ if (validateConfig) {
389
+ const error = validateConfig(reactRouterUserConfig);
390
+ if (error) {
391
+ return err(error);
392
+ }
393
+ }
394
+ } catch (error) {
395
+ return err(`Error loading ${reactRouterConfigFile}: ${error}`);
396
+ }
397
+ }
398
+ reactRouterUserConfig = deepFreeze((0, import_cloneDeep.default)(reactRouterUserConfig));
399
+ let presets = (await Promise.all(
400
+ (reactRouterUserConfig.presets ?? []).map(async (preset) => {
401
+ if (!preset.name) {
402
+ throw new Error(
403
+ "React Router presets must have a `name` property defined."
404
+ );
405
+ }
406
+ if (!preset.reactRouterConfig) {
407
+ return null;
408
+ }
409
+ let configPreset = (0, import_omit.default)(
410
+ await preset.reactRouterConfig({ reactRouterUserConfig }),
411
+ excludedConfigPresetKeys
412
+ );
413
+ return configPreset;
414
+ })
415
+ )).filter(function isNotNull(value) {
416
+ return value !== null;
417
+ });
418
+ let defaults = {
419
+ basename: "/",
420
+ buildDirectory: "build",
421
+ serverBuildFile: "index.js",
422
+ serverModuleFormat: "esm",
423
+ ssr: true
424
+ };
425
+ let userAndPresetConfigs = mergeReactRouterConfig(
426
+ ...presets,
427
+ reactRouterUserConfig
428
+ );
429
+ let {
430
+ appDirectory: userAppDirectory,
431
+ basename: basename3,
432
+ buildDirectory: userBuildDirectory,
433
+ buildEnd,
434
+ prerender,
435
+ routeDiscovery: userRouteDiscovery,
436
+ serverBuildFile,
437
+ serverBundles,
438
+ serverModuleFormat,
439
+ ssr
440
+ } = {
441
+ ...defaults,
442
+ // Default values should be completely overridden by user/preset config, not merged
443
+ ...userAndPresetConfigs
444
+ };
445
+ if (!ssr && serverBundles) {
446
+ serverBundles = void 0;
447
+ }
448
+ let isValidPrerenderConfig = prerender == null || typeof prerender === "boolean" || Array.isArray(prerender) || typeof prerender === "function";
449
+ if (!isValidPrerenderConfig) {
450
+ return err(
451
+ "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
452
+ );
453
+ }
454
+ let routeDiscovery;
455
+ if (userRouteDiscovery == null) {
456
+ if (ssr) {
457
+ routeDiscovery = {
458
+ mode: "lazy",
459
+ manifestPath: "/__manifest"
460
+ };
461
+ } else {
462
+ routeDiscovery = { mode: "initial" };
463
+ }
464
+ } else if (userRouteDiscovery.mode === "initial") {
465
+ routeDiscovery = userRouteDiscovery;
466
+ } else if (userRouteDiscovery.mode === "lazy") {
467
+ if (!ssr) {
468
+ return err(
469
+ 'The `routeDiscovery.mode` config cannot be set to "lazy" when setting `ssr:false`'
470
+ );
471
+ }
472
+ let { manifestPath } = userRouteDiscovery;
473
+ if (manifestPath != null && !manifestPath.startsWith("/")) {
474
+ return err(
475
+ 'The `routeDiscovery.manifestPath` config must be a root-relative pathname beginning with a slash (i.e., "/__manifest")'
476
+ );
477
+ }
478
+ routeDiscovery = userRouteDiscovery;
479
+ }
480
+ let appDirectory = import_pathe3.default.resolve(root, userAppDirectory || "app");
481
+ let buildDirectory = import_pathe3.default.resolve(root, userBuildDirectory);
482
+ let rootRouteFile = findEntry(appDirectory, "root");
483
+ if (!rootRouteFile) {
484
+ let rootRouteDisplayPath = import_pathe3.default.relative(
485
+ root,
486
+ import_pathe3.default.join(appDirectory, "root.tsx")
487
+ );
488
+ return err(
489
+ `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
490
+ );
491
+ }
492
+ let routes;
493
+ let routeConfig = [];
494
+ if (skipRoutes) {
495
+ routes = {};
496
+ } else {
497
+ let routeConfigFile = findEntry(appDirectory, "routes");
498
+ try {
499
+ if (!routeConfigFile) {
500
+ let routeConfigDisplayPath = import_pathe3.default.relative(
501
+ root,
502
+ import_pathe3.default.join(appDirectory, "routes.ts")
503
+ );
504
+ return err(
505
+ `Route config file not found at "${routeConfigDisplayPath}".`
506
+ );
507
+ }
508
+ setAppDirectory(appDirectory);
509
+ let routeConfigExport = (await viteNodeContext.runner.executeFile(
510
+ import_pathe3.default.join(appDirectory, routeConfigFile)
511
+ )).default;
512
+ let result = validateRouteConfig({
513
+ routeConfigFile,
514
+ routeConfig: await routeConfigExport
515
+ });
516
+ if (!result.valid) {
517
+ return err(result.message);
518
+ }
519
+ routeConfig = [
520
+ {
521
+ id: "root",
522
+ path: "",
523
+ file: rootRouteFile,
524
+ children: result.routeConfig
525
+ }
526
+ ];
527
+ routes = configRoutesToRouteManifest(appDirectory, routeConfig);
528
+ } catch (error) {
529
+ return err(
530
+ [
531
+ import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
532
+ "",
533
+ error.loc?.file && error.loc?.column && error.frame ? [
534
+ import_pathe3.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
535
+ error.frame.trim?.()
536
+ ] : error.stack
537
+ ].flat().join("\n")
538
+ );
539
+ }
540
+ }
541
+ let future = {
542
+ v8_middleware: reactRouterUserConfig.future?.v8_middleware ?? false,
543
+ unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
544
+ unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
545
+ unstable_subResourceIntegrity: reactRouterUserConfig.future?.unstable_subResourceIntegrity ?? false,
546
+ unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
547
+ };
548
+ let reactRouterConfig = deepFreeze({
549
+ appDirectory,
550
+ basename: basename3,
551
+ buildDirectory,
552
+ buildEnd,
553
+ future,
554
+ prerender,
555
+ routes,
556
+ routeDiscovery,
557
+ serverBuildFile,
558
+ serverBundles,
559
+ serverModuleFormat,
560
+ ssr,
561
+ unstable_routeConfig: routeConfig
562
+ });
563
+ for (let preset of reactRouterUserConfig.presets ?? []) {
564
+ await preset.reactRouterConfigResolved?.({ reactRouterConfig });
565
+ }
566
+ return ok(reactRouterConfig);
567
+ }
568
+ async function createConfigLoader({
569
+ rootDirectory: root,
570
+ watch: watch2,
571
+ mode,
572
+ skipRoutes,
573
+ validateConfig
574
+ }) {
575
+ root = import_pathe3.default.normalize(root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd());
576
+ let vite2 = await import("vite");
577
+ let viteNodeContext = await createContext({
578
+ root,
579
+ mode,
580
+ // Filter out any info level logs from vite-node
581
+ customLogger: vite2.createLogger("warn", {
582
+ prefix: "[react-router]"
583
+ })
584
+ });
585
+ let reactRouterConfigFile;
586
+ let updateReactRouterConfigFile = () => {
587
+ reactRouterConfigFile = findEntry(root, "react-router.config", {
588
+ absolute: true
589
+ });
590
+ };
591
+ updateReactRouterConfigFile();
592
+ let getConfig = () => resolveConfig({
593
+ root,
594
+ viteNodeContext,
595
+ reactRouterConfigFile,
596
+ skipRoutes,
597
+ validateConfig
598
+ });
599
+ let appDirectory;
600
+ let initialConfigResult = await getConfig();
601
+ if (!initialConfigResult.ok) {
602
+ throw new Error(initialConfigResult.error);
603
+ }
604
+ appDirectory = import_pathe3.default.normalize(initialConfigResult.value.appDirectory);
605
+ let currentConfig = initialConfigResult.value;
606
+ let fsWatcher;
607
+ let changeHandlers = [];
608
+ return {
609
+ getConfig,
610
+ onChange: (handler) => {
611
+ if (!watch2) {
612
+ throw new Error(
613
+ "onChange is not supported when watch mode is disabled"
614
+ );
615
+ }
616
+ changeHandlers.push(handler);
617
+ if (!fsWatcher) {
618
+ fsWatcher = import_chokidar.default.watch([root, appDirectory], {
619
+ ignoreInitial: true,
620
+ ignored: (path7) => {
621
+ let dirname4 = import_pathe3.default.dirname(path7);
622
+ return !dirname4.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
623
+ // that are at the root level, not nested in subdirectories
624
+ path7 !== root && // Watch the root directory itself
625
+ dirname4 !== root;
626
+ }
627
+ });
628
+ fsWatcher.on("all", async (...args) => {
629
+ let [event, rawFilepath] = args;
630
+ let filepath = import_pathe3.default.normalize(rawFilepath);
631
+ let fileAddedOrRemoved = event === "add" || event === "unlink";
632
+ let appFileAddedOrRemoved = fileAddedOrRemoved && filepath.startsWith(import_pathe3.default.normalize(appDirectory));
633
+ let rootRelativeFilepath = import_pathe3.default.relative(root, filepath);
634
+ let configFileAddedOrRemoved = fileAddedOrRemoved && isEntryFile("react-router.config", rootRelativeFilepath);
635
+ if (configFileAddedOrRemoved) {
636
+ updateReactRouterConfigFile();
637
+ }
638
+ let moduleGraphChanged = configFileAddedOrRemoved || Boolean(
639
+ viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
640
+ );
641
+ if (!moduleGraphChanged && !appFileAddedOrRemoved) {
642
+ return;
643
+ }
644
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
645
+ viteNodeContext.runner?.moduleCache.clear();
646
+ let result = await getConfig();
647
+ let prevAppDirectory = appDirectory;
648
+ appDirectory = import_pathe3.default.normalize(
649
+ (result.value ?? currentConfig).appDirectory
650
+ );
651
+ if (appDirectory !== prevAppDirectory) {
652
+ fsWatcher.unwatch(prevAppDirectory);
653
+ fsWatcher.add(appDirectory);
654
+ }
655
+ let configCodeChanged = configFileAddedOrRemoved || reactRouterConfigFile !== void 0 && isEntryFileDependency(
656
+ viteNodeContext.devServer.moduleGraph,
657
+ reactRouterConfigFile,
658
+ filepath
659
+ );
660
+ let routeConfigFile = !skipRoutes ? findEntry(appDirectory, "routes", {
661
+ absolute: true
662
+ }) : void 0;
663
+ let routeConfigCodeChanged = routeConfigFile !== void 0 && isEntryFileDependency(
664
+ viteNodeContext.devServer.moduleGraph,
665
+ routeConfigFile,
666
+ filepath
667
+ );
668
+ let configChanged = result.ok && !(0, import_isEqual.default)(omitRoutes(currentConfig), omitRoutes(result.value));
669
+ let routeConfigChanged = result.ok && !(0, import_isEqual.default)(currentConfig?.routes, result.value.routes);
670
+ for (let handler2 of changeHandlers) {
671
+ handler2({
672
+ result,
673
+ configCodeChanged,
674
+ routeConfigCodeChanged,
675
+ configChanged,
676
+ routeConfigChanged,
677
+ path: filepath,
678
+ event
679
+ });
680
+ }
681
+ if (result.ok) {
682
+ currentConfig = result.value;
683
+ }
684
+ });
685
+ }
686
+ return () => {
687
+ changeHandlers = changeHandlers.filter(
688
+ (changeHandler) => changeHandler !== handler
689
+ );
690
+ };
691
+ },
692
+ close: async () => {
693
+ changeHandlers = [];
694
+ await viteNodeContext.devServer.close();
695
+ await fsWatcher?.close();
696
+ }
697
+ };
698
+ }
699
+ async function resolveEntryFiles({
700
+ rootDirectory,
701
+ reactRouterConfig
702
+ }) {
703
+ let { appDirectory } = reactRouterConfig;
704
+ let defaultsDirectory = import_pathe3.default.resolve(
705
+ import_pathe3.default.dirname(require.resolve("@react-router/dev/package.json")),
706
+ "dist",
707
+ "config",
708
+ "defaults"
709
+ );
710
+ let userEntryClientFile = findEntry(appDirectory, "entry.client");
711
+ let userEntryServerFile = findEntry(appDirectory, "entry.server");
712
+ let entryServerFile;
713
+ let entryClientFile = userEntryClientFile || "entry.client.tsx";
714
+ if (userEntryServerFile) {
715
+ entryServerFile = userEntryServerFile;
716
+ } else {
717
+ let packageJsonPath = findEntry(rootDirectory, "package", {
718
+ extensions: [".json"],
719
+ absolute: true,
720
+ walkParents: true
721
+ });
722
+ if (!packageJsonPath) {
723
+ throw new Error(
724
+ `Could not find package.json in ${rootDirectory} or any of its parent directories. Please add a package.json, or provide a custom entry.server.tsx/jsx file in your app directory.`
725
+ );
726
+ }
727
+ let packageJsonDirectory = import_pathe3.default.dirname(packageJsonPath);
728
+ let pkgJson = await import_package_json.default.load(packageJsonDirectory);
729
+ let deps = pkgJson.content.dependencies ?? {};
730
+ if (!deps["@react-router/node"]) {
731
+ throw new Error(
732
+ `Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
733
+ );
734
+ }
735
+ if (!deps["isbot"]) {
736
+ console.log(
737
+ "adding `isbot@5` to your package.json, you should commit this change"
738
+ );
739
+ pkgJson.update({
740
+ dependencies: {
741
+ ...pkgJson.content.dependencies,
742
+ isbot: "^5"
743
+ }
744
+ });
745
+ await pkgJson.save();
746
+ let packageManager = detectPackageManager() ?? "npm";
747
+ (0, import_node_child_process.execSync)(`${packageManager} install`, {
748
+ cwd: packageJsonDirectory,
749
+ stdio: "inherit"
750
+ });
751
+ }
752
+ entryServerFile = `entry.server.node.tsx`;
753
+ }
754
+ let entryClientFilePath = userEntryClientFile ? import_pathe3.default.resolve(reactRouterConfig.appDirectory, userEntryClientFile) : import_pathe3.default.resolve(defaultsDirectory, entryClientFile);
755
+ let entryServerFilePath = userEntryServerFile ? import_pathe3.default.resolve(reactRouterConfig.appDirectory, userEntryServerFile) : import_pathe3.default.resolve(defaultsDirectory, entryServerFile);
756
+ return { entryClientFilePath, entryServerFilePath };
757
+ }
758
+ function omitRoutes(config) {
759
+ return {
760
+ ...config,
761
+ routes: {}
762
+ };
763
+ }
764
+ var entryExts = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".mts"];
765
+ function isEntryFile(entryBasename, filename2) {
766
+ return entryExts.some((ext) => filename2 === `${entryBasename}${ext}`);
767
+ }
768
+ function findEntry(dir, basename3, options) {
769
+ let currentDir = import_pathe3.default.resolve(dir);
770
+ let { root } = import_pathe3.default.parse(currentDir);
771
+ while (true) {
772
+ for (let ext of options?.extensions ?? entryExts) {
773
+ let file = import_pathe3.default.resolve(currentDir, basename3 + ext);
774
+ if (import_node_fs.default.existsSync(file)) {
775
+ return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
776
+ }
777
+ }
778
+ if (!options?.walkParents) {
779
+ return void 0;
780
+ }
781
+ let parentDir = import_pathe3.default.dirname(currentDir);
782
+ if (currentDir === root || parentDir === currentDir) {
783
+ return void 0;
784
+ }
785
+ currentDir = parentDir;
786
+ }
787
+ }
788
+ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /* @__PURE__ */ new Set()) {
789
+ entryFilepath = import_pathe3.default.normalize(entryFilepath);
790
+ filepath = import_pathe3.default.normalize(filepath);
791
+ if (visited.has(filepath)) {
792
+ return false;
793
+ }
794
+ visited.add(filepath);
795
+ if (filepath === entryFilepath) {
796
+ return true;
797
+ }
798
+ let mod = moduleGraph.getModuleById(filepath);
799
+ if (!mod) {
800
+ return false;
801
+ }
802
+ for (let importer of mod.importers) {
803
+ if (!importer.id) {
804
+ continue;
805
+ }
806
+ if (importer.id === entryFilepath || isEntryFileDependency(moduleGraph, entryFilepath, importer.id, visited)) {
807
+ return true;
808
+ }
809
+ }
810
+ return false;
811
+ }
812
+
813
+ // typegen/context.ts
814
+ async function createContext2({
815
+ rootDirectory,
816
+ watch: watch2,
817
+ mode
818
+ }) {
819
+ const configLoader = await createConfigLoader({ rootDirectory, mode, watch: watch2 });
820
+ const configResult = await configLoader.getConfig();
821
+ if (!configResult.ok) {
822
+ throw new Error(configResult.error);
823
+ }
824
+ const config = configResult.value;
825
+ return {
826
+ configLoader,
827
+ rootDirectory,
828
+ config
829
+ };
830
+ }
831
+
832
+ // typegen/generate.ts
833
+ var import_dedent = __toESM(require("dedent"));
834
+ var Path3 = __toESM(require("pathe"));
835
+ var Pathe = __toESM(require("pathe/utils"));
836
+
837
+ // vite/babel.ts
838
+ var babel_exports = {};
839
+ __export(babel_exports, {
840
+ generate: () => generate,
841
+ parse: () => import_parser.parse,
842
+ t: () => t,
843
+ traverse: () => traverse
844
+ });
845
+ var import_parser = require("@babel/parser");
846
+ var t = __toESM(require("@babel/types"));
847
+ var traverse = require("@babel/traverse").default;
848
+ var generate = require("@babel/generator").default;
849
+
850
+ // typegen/params.ts
851
+ function parse2(fullpath2) {
852
+ const result = {};
853
+ let segments = fullpath2.split("/");
854
+ segments.forEach((segment) => {
855
+ const match = segment.match(/^:([\w-]+)(\?)?/);
856
+ if (!match) return;
857
+ const param = match[1];
858
+ const isRequired = match[2] === void 0;
859
+ result[param] ||= isRequired;
860
+ return;
861
+ });
862
+ const hasSplat = segments.at(-1) === "*";
863
+ if (hasSplat) result["*"] = true;
864
+ return result;
865
+ }
866
+
867
+ // typegen/route.ts
868
+ function lineage(routes, route) {
869
+ const result = [];
870
+ while (route) {
871
+ result.push(route);
872
+ if (!route.parentId) break;
873
+ route = routes[route.parentId];
874
+ }
875
+ result.reverse();
876
+ return result;
877
+ }
878
+ function fullpath(lineage2) {
879
+ const route = lineage2.at(-1);
880
+ if (lineage2.length === 1 && route?.id === "root") return "/";
881
+ const isLayout = route && route.index !== true && route.path === void 0;
882
+ if (isLayout) return void 0;
883
+ return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path7) => path7 !== void 0 && path7 !== "").join("/");
884
+ }
885
+
886
+ // typegen/generate.ts
887
+ function typesDirectory(ctx) {
888
+ return Path3.join(ctx.rootDirectory, ".react-router/types");
889
+ }
890
+ function generateFuture(ctx) {
891
+ const filename2 = Path3.join(typesDirectory(ctx), "+future.ts");
892
+ const content = import_dedent.default`
893
+ // Generated by React Router
894
+
895
+ import "react-router";
896
+
897
+ declare module "react-router" {
898
+ interface Future {
899
+ middleware: ${ctx.config.future.v8_middleware}
900
+ }
901
+ }
902
+ `;
903
+ return { filename: filename2, content };
904
+ }
905
+ function generateServerBuild(ctx) {
906
+ const filename2 = Path3.join(typesDirectory(ctx), "+server-build.d.ts");
907
+ const content = import_dedent.default`
908
+ // Generated by React Router
909
+
910
+ declare module "virtual:react-router/server-build" {
911
+ import { ServerBuild } from "react-router";
912
+ export const assets: ServerBuild["assets"];
913
+ export const assetsBuildDirectory: ServerBuild["assetsBuildDirectory"];
914
+ export const basename: ServerBuild["basename"];
915
+ export const entry: ServerBuild["entry"];
916
+ export const future: ServerBuild["future"];
917
+ export const isSpaMode: ServerBuild["isSpaMode"];
918
+ export const prerender: ServerBuild["prerender"];
919
+ export const publicPath: ServerBuild["publicPath"];
920
+ export const routeDiscovery: ServerBuild["routeDiscovery"];
921
+ export const routes: ServerBuild["routes"];
922
+ export const ssr: ServerBuild["ssr"];
923
+ export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
924
+ }
925
+ `;
926
+ return { filename: filename2, content };
927
+ }
928
+ var { t: t2 } = babel_exports;
929
+ function generateRoutes(ctx) {
930
+ const fileToRoutes = /* @__PURE__ */ new Map();
931
+ const lineages = /* @__PURE__ */ new Map();
932
+ const allPages = /* @__PURE__ */ new Set();
933
+ const routeToPages = /* @__PURE__ */ new Map();
934
+ for (const route of Object.values(ctx.config.routes)) {
935
+ let routeIds = fileToRoutes.get(route.file);
936
+ if (!routeIds) {
937
+ routeIds = /* @__PURE__ */ new Set();
938
+ fileToRoutes.set(route.file, routeIds);
939
+ }
940
+ routeIds.add(route.id);
941
+ const lineage2 = lineage(ctx.config.routes, route);
942
+ lineages.set(route.id, lineage2);
943
+ const fullpath2 = fullpath(lineage2);
944
+ if (!fullpath2) continue;
945
+ const pages = expand(fullpath2);
946
+ pages.forEach((page) => allPages.add(page));
947
+ lineage2.forEach(({ id }) => {
948
+ let routePages = routeToPages.get(id);
949
+ if (!routePages) {
950
+ routePages = /* @__PURE__ */ new Set();
951
+ routeToPages.set(id, routePages);
952
+ }
953
+ pages.forEach((page) => routePages.add(page));
954
+ });
955
+ }
956
+ const routesTs = {
957
+ filename: Path3.join(typesDirectory(ctx), "+routes.ts"),
958
+ content: import_dedent.default`
959
+ // Generated by React Router
960
+
961
+ import "react-router"
962
+
963
+ declare module "react-router" {
964
+ interface Register {
965
+ pages: Pages
966
+ routeFiles: RouteFiles
967
+ }
968
+ }
969
+ ` + "\n\n" + generate(pagesType(allPages)).code + "\n\n" + generate(routeFilesType({ fileToRoutes, routeToPages })).code
970
+ };
971
+ const allAnnotations = Array.from(fileToRoutes.entries()).filter(([file]) => isInAppDirectory(ctx, file)).map(
972
+ ([file, routeIds]) => getRouteAnnotations({ ctx, file, routeIds, lineages })
973
+ );
974
+ return [routesTs, ...allAnnotations];
975
+ }
976
+ function pagesType(pages) {
977
+ return t2.tsTypeAliasDeclaration(
978
+ t2.identifier("Pages"),
979
+ null,
980
+ t2.tsTypeLiteral(
981
+ Array.from(pages).map((page) => {
982
+ return t2.tsPropertySignature(
983
+ t2.stringLiteral(page),
984
+ t2.tsTypeAnnotation(
985
+ t2.tsTypeLiteral([
986
+ t2.tsPropertySignature(
987
+ t2.identifier("params"),
988
+ t2.tsTypeAnnotation(paramsType(page))
989
+ )
990
+ ])
991
+ )
992
+ );
993
+ })
994
+ )
995
+ );
996
+ }
997
+ function routeFilesType({
998
+ fileToRoutes,
999
+ routeToPages
1000
+ }) {
1001
+ return t2.tsTypeAliasDeclaration(
1002
+ t2.identifier("RouteFiles"),
1003
+ null,
1004
+ t2.tsTypeLiteral(
1005
+ Array.from(fileToRoutes).map(
1006
+ ([file, routeIds]) => t2.tsPropertySignature(
1007
+ t2.stringLiteral(file),
1008
+ t2.tsTypeAnnotation(
1009
+ t2.tsUnionType(
1010
+ Array.from(routeIds).map((routeId) => {
1011
+ const pages = routeToPages.get(routeId) ?? /* @__PURE__ */ new Set();
1012
+ return t2.tsTypeLiteral([
1013
+ t2.tsPropertySignature(
1014
+ t2.identifier("id"),
1015
+ t2.tsTypeAnnotation(
1016
+ t2.tsLiteralType(t2.stringLiteral(routeId))
1017
+ )
1018
+ ),
1019
+ t2.tsPropertySignature(
1020
+ t2.identifier("page"),
1021
+ t2.tsTypeAnnotation(
1022
+ pages ? t2.tsUnionType(
1023
+ Array.from(pages).map(
1024
+ (page) => t2.tsLiteralType(t2.stringLiteral(page))
1025
+ )
1026
+ ) : t2.tsNeverKeyword()
1027
+ )
1028
+ )
1029
+ ]);
1030
+ })
1031
+ )
1032
+ )
1033
+ )
1034
+ )
1035
+ )
1036
+ );
1037
+ }
1038
+ function isInAppDirectory(ctx, routeFile) {
1039
+ const path7 = Path3.resolve(ctx.config.appDirectory, routeFile);
1040
+ return path7.startsWith(ctx.config.appDirectory);
1041
+ }
1042
+ function getRouteAnnotations({
1043
+ ctx,
1044
+ file,
1045
+ routeIds,
1046
+ lineages
1047
+ }) {
1048
+ const filename2 = Path3.join(
1049
+ typesDirectory(ctx),
1050
+ Path3.relative(ctx.rootDirectory, ctx.config.appDirectory),
1051
+ Path3.dirname(file),
1052
+ "+types",
1053
+ Pathe.filename(file) + ".ts"
1054
+ );
1055
+ const matchesType = t2.tsTypeAliasDeclaration(
1056
+ t2.identifier("Matches"),
1057
+ null,
1058
+ t2.tsUnionType(
1059
+ Array.from(routeIds).map((routeId) => {
1060
+ const lineage2 = lineages.get(routeId);
1061
+ return t2.tsTupleType(
1062
+ lineage2.map(
1063
+ (route) => t2.tsTypeLiteral([
1064
+ t2.tsPropertySignature(
1065
+ t2.identifier("id"),
1066
+ t2.tsTypeAnnotation(t2.tsLiteralType(t2.stringLiteral(route.id)))
1067
+ ),
1068
+ t2.tsPropertySignature(
1069
+ t2.identifier("module"),
1070
+ t2.tsTypeAnnotation(
1071
+ t2.tsTypeQuery(
1072
+ t2.tsImportType(
1073
+ t2.stringLiteral(
1074
+ relativeImportSource(
1075
+ rootDirsPath(ctx, filename2),
1076
+ Path3.resolve(ctx.config.appDirectory, route.file)
1077
+ )
1078
+ )
1079
+ )
1080
+ )
1081
+ )
1082
+ )
1083
+ ])
1084
+ )
1085
+ );
1086
+ })
1087
+ )
1088
+ );
1089
+ const routeImportSource = relativeImportSource(
1090
+ rootDirsPath(ctx, filename2),
1091
+ Path3.resolve(ctx.config.appDirectory, file)
1092
+ );
1093
+ const content = import_dedent.default`
1094
+ // Generated by React Router
1095
+
1096
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
1097
+
1098
+ type Module = typeof import("${routeImportSource}")
1099
+
1100
+ type Info = GetInfo<{
1101
+ file: "${file}",
1102
+ module: Module
1103
+ }>
1104
+ ` + "\n\n" + generate(matchesType).code + "\n\n" + import_dedent.default`
1105
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }>;
1106
+
1107
+ export namespace Route {
1108
+ // links
1109
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
1110
+ export type LinksFunction = Annotations["LinksFunction"];
1111
+
1112
+ // meta
1113
+ export type MetaArgs = Annotations["MetaArgs"];
1114
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
1115
+ export type MetaFunction = Annotations["MetaFunction"];
1116
+
1117
+ // headers
1118
+ export type HeadersArgs = Annotations["HeadersArgs"];
1119
+ export type HeadersFunction = Annotations["HeadersFunction"];
1120
+
1121
+ // middleware
1122
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
1123
+
1124
+ // clientMiddleware
1125
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
1126
+
1127
+ // loader
1128
+ export type LoaderArgs = Annotations["LoaderArgs"];
1129
+
1130
+ // clientLoader
1131
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
1132
+
1133
+ // action
1134
+ export type ActionArgs = Annotations["ActionArgs"];
1135
+
1136
+ // clientAction
1137
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
1138
+
1139
+ // HydrateFallback
1140
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
1141
+
1142
+ // Component
1143
+ export type ComponentProps = Annotations["ComponentProps"];
1144
+
1145
+ // ErrorBoundary
1146
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
1147
+ }
1148
+ `;
1149
+ return { filename: filename2, content };
1150
+ }
1151
+ function relativeImportSource(from, to) {
1152
+ let path7 = Path3.relative(Path3.dirname(from), to);
1153
+ let extension = Path3.extname(path7);
1154
+ path7 = Path3.join(Path3.dirname(path7), Pathe.filename(path7));
1155
+ if (!path7.startsWith("../")) path7 = "./" + path7;
1156
+ if (!extension || /\.(js|ts)x?$/.test(extension)) {
1157
+ extension = ".js";
1158
+ }
1159
+ return path7 + extension;
1160
+ }
1161
+ function rootDirsPath(ctx, typesPath) {
1162
+ const rel = Path3.relative(typesDirectory(ctx), typesPath);
1163
+ return Path3.join(ctx.rootDirectory, rel);
1164
+ }
1165
+ function paramsType(path7) {
1166
+ const params = parse2(path7);
1167
+ return t2.tsTypeLiteral(
1168
+ Object.entries(params).map(([param, isRequired]) => {
1169
+ const property = t2.tsPropertySignature(
1170
+ t2.stringLiteral(param),
1171
+ t2.tsTypeAnnotation(t2.tsStringKeyword())
1172
+ );
1173
+ property.optional = !isRequired;
1174
+ return property;
1175
+ })
1176
+ );
1177
+ }
1178
+ function expand(fullpath2) {
1179
+ function recurse(segments2, index) {
1180
+ if (index === segments2.length) return [""];
1181
+ const segment = segments2[index];
1182
+ const isOptional = segment.endsWith("?");
1183
+ const isDynamic = segment.startsWith(":");
1184
+ const required = segment.replace(/\?$/, "");
1185
+ const keep = !isOptional || isDynamic;
1186
+ const kept = isDynamic ? segment : required;
1187
+ const withoutSegment = recurse(segments2, index + 1);
1188
+ const withSegment = withoutSegment.map((rest) => [kept, rest].join("/"));
1189
+ if (keep) return withSegment;
1190
+ return [...withoutSegment, ...withSegment];
1191
+ }
1192
+ const segments = fullpath2.split("/");
1193
+ const expanded = /* @__PURE__ */ new Set();
1194
+ for (let result of recurse(segments, 0)) {
1195
+ if (result !== "/") result = result.replace(/\/$/, "");
1196
+ expanded.add(result);
1197
+ }
1198
+ return expanded;
1199
+ }
1200
+
1201
+ // typegen/index.ts
1202
+ async function clearRouteModuleAnnotations(ctx) {
1203
+ await import_promises.default.rm(
1204
+ Path4.join(typesDirectory(ctx), Path4.basename(ctx.config.appDirectory)),
1205
+ { recursive: true, force: true }
1206
+ );
1207
+ }
1208
+ async function write(...files) {
1209
+ return Promise.all(
1210
+ files.map(async ({ filename: filename2, content }) => {
1211
+ await import_promises.default.mkdir(Path4.dirname(filename2), { recursive: true });
1212
+ await import_promises.default.writeFile(filename2, content);
1213
+ })
1214
+ );
1215
+ }
1216
+ async function watch(rootDirectory, { mode, logger }) {
1217
+ const ctx = await createContext2({ rootDirectory, mode, watch: true });
1218
+ await import_promises.default.rm(typesDirectory(ctx), { recursive: true, force: true });
1219
+ await write(
1220
+ generateFuture(ctx),
1221
+ generateServerBuild(ctx),
1222
+ ...generateRoutes(ctx)
1223
+ );
1224
+ logger?.info((0, import_picocolors2.green)("generated types"), { timestamp: true, clear: true });
1225
+ ctx.configLoader.onChange(
1226
+ async ({ result, configChanged, routeConfigChanged }) => {
1227
+ if (!result.ok) {
1228
+ logger?.error((0, import_picocolors2.red)(result.error), { timestamp: true, clear: true });
1229
+ return;
1230
+ }
1231
+ ctx.config = result.value;
1232
+ if (configChanged) {
1233
+ await write(generateFuture(ctx));
1234
+ logger?.info((0, import_picocolors2.green)("regenerated types"), {
1235
+ timestamp: true,
1236
+ clear: true
1237
+ });
1238
+ }
1239
+ if (routeConfigChanged) {
1240
+ await clearRouteModuleAnnotations(ctx);
1241
+ await write(...generateRoutes(ctx));
1242
+ logger?.info((0, import_picocolors2.green)("regenerated types"), {
1243
+ timestamp: true,
1244
+ clear: true
1245
+ });
1246
+ }
1247
+ }
1248
+ );
1249
+ return {
1250
+ close: async () => await ctx.configLoader.close()
1251
+ };
1252
+ }
1253
+
1254
+ // vite/node-adapter.ts
1255
+ var import_node_events = require("events");
1256
+ var import_node_tls = require("tls");
1257
+ var import_node_stream = require("stream");
1258
+ var import_set_cookie_parser = require("set-cookie-parser");
1259
+ var import_node = require("@react-router/node");
1260
+ function fromNodeHeaders(nodeReq) {
1261
+ let nodeHeaders = nodeReq.headers;
1262
+ if (nodeReq.httpVersionMajor >= 2) {
1263
+ nodeHeaders = { ...nodeHeaders };
1264
+ if (nodeHeaders[":authority"]) {
1265
+ nodeHeaders.host = nodeHeaders[":authority"];
1266
+ }
1267
+ delete nodeHeaders[":authority"];
1268
+ delete nodeHeaders[":method"];
1269
+ delete nodeHeaders[":path"];
1270
+ delete nodeHeaders[":scheme"];
1271
+ }
1272
+ let headers = new Headers();
1273
+ for (let [key, values] of Object.entries(nodeHeaders)) {
1274
+ if (values) {
1275
+ if (Array.isArray(values)) {
1276
+ for (let value of values) {
1277
+ headers.append(key, value);
1278
+ }
1279
+ } else {
1280
+ headers.set(key, values);
1281
+ }
1282
+ }
1283
+ }
1284
+ return headers;
1285
+ }
1286
+ function fromNodeRequest(nodeReq, nodeRes) {
1287
+ let protocol = nodeReq.socket instanceof import_node_tls.TLSSocket && nodeReq.socket.encrypted ? "https" : "http";
1288
+ let origin = nodeReq.headers.origin && "null" !== nodeReq.headers.origin ? nodeReq.headers.origin : `${protocol}://${nodeReq.headers.host}`;
1289
+ invariant(
1290
+ nodeReq.originalUrl,
1291
+ "Expected `nodeReq.originalUrl` to be defined"
1292
+ );
1293
+ let url2 = new URL(nodeReq.originalUrl, origin);
1294
+ let controller = new AbortController();
1295
+ let init = {
1296
+ method: nodeReq.method,
1297
+ headers: fromNodeHeaders(nodeReq),
1298
+ signal: controller.signal
1299
+ };
1300
+ nodeRes.on("finish", () => controller = null);
1301
+ nodeRes.on("close", () => controller?.abort());
1302
+ if (nodeReq.method !== "GET" && nodeReq.method !== "HEAD") {
1303
+ init.body = (0, import_node.createReadableStreamFromReadable)(nodeReq);
1304
+ init.duplex = "half";
1305
+ }
1306
+ return new Request(url2.href, init);
1307
+ }
1308
+ async function toNodeRequest(res, nodeRes) {
1309
+ nodeRes.statusCode = res.status;
1310
+ if (!nodeRes.req || nodeRes.req.httpVersionMajor < 2) {
1311
+ nodeRes.statusMessage = res.statusText;
1312
+ }
1313
+ let cookiesStrings = [];
1314
+ for (let [name, value] of res.headers) {
1315
+ if (name === "set-cookie") {
1316
+ cookiesStrings.push(...(0, import_set_cookie_parser.splitCookiesString)(value));
1317
+ } else nodeRes.setHeader(name, value);
1318
+ }
1319
+ if (cookiesStrings.length) {
1320
+ nodeRes.setHeader("set-cookie", cookiesStrings);
1321
+ }
1322
+ if (res.body) {
1323
+ let responseBody = res.body;
1324
+ let readable = import_node_stream.Readable.from(responseBody);
1325
+ readable.pipe(nodeRes);
1326
+ await (0, import_node_events.once)(readable, "end");
1327
+ } else {
1328
+ nodeRes.end();
1329
+ }
1330
+ }
1331
+
1332
+ // vite/styles.ts
1333
+ var path4 = __toESM(require("path"));
1334
+ var import_react_router = require("react-router");
1335
+
1336
+ // vite/resolve-file-url.ts
1337
+ var path3 = __toESM(require("path"));
1338
+ var resolveFileUrl = ({ rootDirectory }, filePath) => {
1339
+ let vite2 = getVite();
1340
+ let relativePath = path3.relative(rootDirectory, filePath);
1341
+ let isWithinRoot = !relativePath.startsWith("..") && !path3.isAbsolute(relativePath);
1342
+ if (!isWithinRoot) {
1343
+ return path3.posix.join("/@fs", vite2.normalizePath(filePath));
1344
+ }
1345
+ return "/" + vite2.normalizePath(relativePath);
1346
+ };
1347
+
1348
+ // vite/styles.ts
1349
+ var cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
1350
+ var cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
1351
+ var isCssFile = (file) => cssFileRegExp.test(file);
1352
+ var isCssModulesFile = (file) => cssModulesRegExp.test(file);
1353
+ var cssUrlParamsWithoutSideEffects = ["url", "inline", "raw", "inline-css"];
1354
+ var isCssUrlWithoutSideEffects = (url2) => {
1355
+ let queryString = url2.split("?")[1];
1356
+ if (!queryString) {
1357
+ return false;
1358
+ }
1359
+ let params = new URLSearchParams(queryString);
1360
+ for (let paramWithoutSideEffects of cssUrlParamsWithoutSideEffects) {
1361
+ if (
1362
+ // Parameter is blank and not explicitly set, i.e. "?url", not "?url="
1363
+ params.get(paramWithoutSideEffects) === "" && !url2.includes(`?${paramWithoutSideEffects}=`) && !url2.includes(`&${paramWithoutSideEffects}=`)
1364
+ ) {
1365
+ return true;
1366
+ }
1367
+ }
1368
+ return false;
1369
+ };
1370
+ var getStylesForFiles = async ({
1371
+ viteDevServer,
1372
+ rootDirectory,
1373
+ loadCssContents,
1374
+ files
1375
+ }) => {
1376
+ let styles = {};
1377
+ let deps = /* @__PURE__ */ new Set();
1378
+ try {
1379
+ for (let file of files) {
1380
+ let normalizedPath = path4.resolve(rootDirectory, file).replace(/\\/g, "/");
1381
+ let node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
1382
+ if (!node) {
1383
+ try {
1384
+ await viteDevServer.transformRequest(
1385
+ resolveFileUrl({ rootDirectory }, normalizedPath)
1386
+ );
1387
+ } catch (err2) {
1388
+ console.error(err2);
1389
+ }
1390
+ node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
1391
+ }
1392
+ if (!node) {
1393
+ console.log(`Could not resolve module for file: ${file}`);
1394
+ continue;
1395
+ }
1396
+ await findDeps(viteDevServer, node, deps);
1397
+ }
1398
+ } catch (err2) {
1399
+ console.error(err2);
1400
+ }
1401
+ for (let dep of deps) {
1402
+ if (dep.file && isCssFile(dep.file) && !isCssUrlWithoutSideEffects(dep.url)) {
1403
+ try {
1404
+ styles[dep.url] = await loadCssContents(viteDevServer, dep);
1405
+ } catch {
1406
+ console.warn(`Failed to load CSS for ${dep.file}`);
1407
+ }
1408
+ }
1409
+ }
1410
+ return Object.entries(styles).map(([fileName, css], i) => [
1411
+ `
1412
+ /* ${fileName.replace(/\/\*/g, "/\\*").replace(/\*\//g, "*\\/")} */`,
1413
+ css
1414
+ ]).flat().join("\n") || void 0;
1415
+ };
1416
+ var findDeps = async (vite2, node, deps) => {
1417
+ let branches = [];
1418
+ async function addFromNode(node2) {
1419
+ if (!deps.has(node2)) {
1420
+ deps.add(node2);
1421
+ await findDeps(vite2, node2, deps);
1422
+ }
1423
+ }
1424
+ async function addFromUrl(url2) {
1425
+ let node2 = await vite2.moduleGraph.getModuleByUrl(url2);
1426
+ if (node2) {
1427
+ await addFromNode(node2);
1428
+ }
1429
+ }
1430
+ if (node.ssrTransformResult) {
1431
+ if (node.ssrTransformResult.deps) {
1432
+ node.ssrTransformResult.deps.forEach(
1433
+ (url2) => branches.push(addFromUrl(url2))
1434
+ );
1435
+ }
1436
+ } else {
1437
+ node.importedModules.forEach((node2) => branches.push(addFromNode(node2)));
1438
+ }
1439
+ await Promise.all(branches);
1440
+ };
1441
+ var groupRoutesByParentId = (manifest) => {
1442
+ let routes = {};
1443
+ Object.values(manifest).forEach((route) => {
1444
+ if (route) {
1445
+ let parentId = route.parentId || "";
1446
+ if (!routes[parentId]) {
1447
+ routes[parentId] = [];
1448
+ }
1449
+ routes[parentId].push(route);
1450
+ }
1451
+ });
1452
+ return routes;
1453
+ };
1454
+ var createRoutesWithChildren = (manifest, parentId = "", routesByParentId = groupRoutesByParentId(manifest)) => {
1455
+ return (routesByParentId[parentId] || []).map((route) => ({
1456
+ ...route,
1457
+ ...route.index ? {
1458
+ index: true
1459
+ } : {
1460
+ index: false,
1461
+ children: createRoutesWithChildren(
1462
+ manifest,
1463
+ route.id,
1464
+ routesByParentId
1465
+ )
1466
+ }
1467
+ }));
1468
+ };
1469
+ var getStylesForPathname = async ({
1470
+ viteDevServer,
1471
+ rootDirectory,
1472
+ reactRouterConfig,
1473
+ entryClientFilePath,
1474
+ loadCssContents,
1475
+ pathname
1476
+ }) => {
1477
+ if (pathname === void 0 || pathname.includes("?_data=")) {
1478
+ return void 0;
1479
+ }
1480
+ let routesWithChildren = createRoutesWithChildren(reactRouterConfig.routes);
1481
+ let appPath = path4.relative(process.cwd(), reactRouterConfig.appDirectory);
1482
+ let documentRouteFiles = (0, import_react_router.matchRoutes)(routesWithChildren, pathname, reactRouterConfig.basename)?.map(
1483
+ (match) => path4.resolve(appPath, reactRouterConfig.routes[match.route.id].file)
1484
+ ) ?? [];
1485
+ let styles = await getStylesForFiles({
1486
+ viteDevServer,
1487
+ rootDirectory,
1488
+ loadCssContents,
1489
+ files: [
1490
+ // Always include the client entry file when crawling the module graph for CSS
1491
+ path4.relative(rootDirectory, entryClientFilePath),
1492
+ // Then include any styles from the matched routes
1493
+ ...documentRouteFiles
1494
+ ]
1495
+ });
1496
+ return styles;
1497
+ };
1498
+ var getCssStringFromViteDevModuleCode = (code) => {
1499
+ let cssContent = void 0;
1500
+ const ast = import_parser.parse(code, { sourceType: "module" });
1501
+ traverse(ast, {
1502
+ VariableDeclaration(path7) {
1503
+ const declaration = path7.node.declarations[0];
1504
+ if (declaration?.id?.type === "Identifier" && declaration.id.name === "__vite__css" && declaration.init?.type === "StringLiteral") {
1505
+ cssContent = declaration.init.value;
1506
+ path7.stop();
1507
+ }
1508
+ }
1509
+ });
1510
+ return cssContent;
1511
+ };
1512
+
1513
+ // vite/virtual-module.ts
1514
+ function create(name) {
1515
+ let id = `virtual:react-router/${name}`;
1516
+ return {
1517
+ id,
1518
+ resolvedId: `\0${id}`,
1519
+ url: `/@id/__x00__${id}`
1520
+ };
1521
+ }
1522
+
1523
+ // vite/resolve-relative-route-file-path.ts
1524
+ var import_pathe4 = __toESM(require("pathe"));
1525
+ function resolveRelativeRouteFilePath(route, reactRouterConfig) {
1526
+ let vite2 = getVite();
1527
+ let file = route.file;
1528
+ let fullPath = import_pathe4.default.resolve(reactRouterConfig.appDirectory, file);
1529
+ return vite2.normalizePath(fullPath);
1530
+ }
1531
+
1532
+ // vite/combine-urls.ts
1533
+ function combineURLs(baseURL, relativeURL) {
1534
+ return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
1535
+ }
1536
+
1537
+ // vite/remove-exports.ts
1538
+ var import_babel_dead_code_elimination = require("babel-dead-code-elimination");
1539
+ var removeExports = (ast, exportsToRemove) => {
1540
+ let previouslyReferencedIdentifiers = (0, import_babel_dead_code_elimination.findReferencedIdentifiers)(ast);
1541
+ let exportsFiltered = false;
1542
+ let markedForRemoval = /* @__PURE__ */ new Set();
1543
+ let removedExportLocalNames = /* @__PURE__ */ new Set();
1544
+ traverse(ast, {
1545
+ ExportDeclaration(path7) {
1546
+ if (path7.node.type === "ExportNamedDeclaration") {
1547
+ if (path7.node.specifiers.length) {
1548
+ path7.node.specifiers = path7.node.specifiers.filter((specifier) => {
1549
+ if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
1550
+ if (exportsToRemove.includes(specifier.exported.name)) {
1551
+ exportsFiltered = true;
1552
+ if (specifier.local && specifier.local.name !== specifier.exported.name) {
1553
+ removedExportLocalNames.add(specifier.local.name);
1554
+ }
1555
+ return false;
1556
+ }
1557
+ }
1558
+ return true;
1559
+ });
1560
+ if (path7.node.specifiers.length === 0) {
1561
+ markedForRemoval.add(path7);
1562
+ }
1563
+ }
1564
+ if (path7.node.declaration?.type === "VariableDeclaration") {
1565
+ let declaration = path7.node.declaration;
1566
+ declaration.declarations = declaration.declarations.filter(
1567
+ (declaration2) => {
1568
+ if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
1569
+ exportsFiltered = true;
1570
+ return false;
1571
+ }
1572
+ if (declaration2.id.type === "ArrayPattern" || declaration2.id.type === "ObjectPattern") {
1573
+ validateDestructuredExports(declaration2.id, exportsToRemove);
1574
+ }
1575
+ return true;
1576
+ }
1577
+ );
1578
+ if (declaration.declarations.length === 0) {
1579
+ markedForRemoval.add(path7);
1580
+ }
1581
+ }
1582
+ if (path7.node.declaration?.type === "FunctionDeclaration") {
1583
+ let id = path7.node.declaration.id;
1584
+ if (id && exportsToRemove.includes(id.name)) {
1585
+ markedForRemoval.add(path7);
1586
+ }
1587
+ }
1588
+ if (path7.node.declaration?.type === "ClassDeclaration") {
1589
+ let id = path7.node.declaration.id;
1590
+ if (id && exportsToRemove.includes(id.name)) {
1591
+ markedForRemoval.add(path7);
1592
+ }
1593
+ }
1594
+ }
1595
+ if (path7.node.type === "ExportDefaultDeclaration") {
1596
+ if (exportsToRemove.includes("default")) {
1597
+ markedForRemoval.add(path7);
1598
+ if (path7.node.declaration) {
1599
+ if (path7.node.declaration.type === "Identifier") {
1600
+ removedExportLocalNames.add(path7.node.declaration.name);
1601
+ } else if ((path7.node.declaration.type === "FunctionDeclaration" || path7.node.declaration.type === "ClassDeclaration") && path7.node.declaration.id) {
1602
+ removedExportLocalNames.add(path7.node.declaration.id.name);
1603
+ }
1604
+ }
1605
+ }
1606
+ }
1607
+ }
1608
+ });
1609
+ traverse(ast, {
1610
+ ExpressionStatement(path7) {
1611
+ if (!path7.parentPath.isProgram()) {
1612
+ return;
1613
+ }
1614
+ if (path7.node.expression.type === "AssignmentExpression") {
1615
+ const left = path7.node.expression.left;
1616
+ if (left.type === "MemberExpression" && left.object.type === "Identifier" && (exportsToRemove.includes(left.object.name) || removedExportLocalNames.has(left.object.name))) {
1617
+ markedForRemoval.add(path7);
1618
+ }
1619
+ }
1620
+ }
1621
+ });
1622
+ if (markedForRemoval.size > 0 || exportsFiltered) {
1623
+ for (let path7 of markedForRemoval) {
1624
+ path7.remove();
1625
+ }
1626
+ (0, import_babel_dead_code_elimination.deadCodeElimination)(ast, previouslyReferencedIdentifiers);
1627
+ }
1628
+ };
1629
+ function validateDestructuredExports(id, exportsToRemove) {
1630
+ if (id.type === "ArrayPattern") {
1631
+ for (let element of id.elements) {
1632
+ if (!element) {
1633
+ continue;
1634
+ }
1635
+ if (element.type === "Identifier" && exportsToRemove.includes(element.name)) {
1636
+ throw invalidDestructureError(element.name);
1637
+ }
1638
+ if (element.type === "RestElement" && element.argument.type === "Identifier" && exportsToRemove.includes(element.argument.name)) {
1639
+ throw invalidDestructureError(element.argument.name);
1640
+ }
1641
+ if (element.type === "ArrayPattern" || element.type === "ObjectPattern") {
1642
+ validateDestructuredExports(element, exportsToRemove);
1643
+ }
1644
+ }
1645
+ }
1646
+ if (id.type === "ObjectPattern") {
1647
+ for (let property of id.properties) {
1648
+ if (!property) {
1649
+ continue;
1650
+ }
1651
+ if (property.type === "ObjectProperty" && property.key.type === "Identifier") {
1652
+ if (property.value.type === "Identifier" && exportsToRemove.includes(property.value.name)) {
1653
+ throw invalidDestructureError(property.value.name);
1654
+ }
1655
+ if (property.value.type === "ArrayPattern" || property.value.type === "ObjectPattern") {
1656
+ validateDestructuredExports(property.value, exportsToRemove);
1657
+ }
1658
+ }
1659
+ if (property.type === "RestElement" && property.argument.type === "Identifier" && exportsToRemove.includes(property.argument.name)) {
1660
+ throw invalidDestructureError(property.argument.name);
1661
+ }
1662
+ }
1663
+ }
1664
+ }
1665
+ function invalidDestructureError(name) {
1666
+ return new Error(`Cannot remove destructured export "${name}"`);
1667
+ }
1668
+
1669
+ // vite/has-dependency.ts
1670
+ function hasDependency({
1671
+ name,
1672
+ rootDirectory
1673
+ }) {
1674
+ try {
1675
+ return Boolean(require.resolve(name, { paths: [rootDirectory] }));
1676
+ } catch (err2) {
1677
+ return false;
1678
+ }
1679
+ }
1680
+
1681
+ // vite/cache.ts
1682
+ function getOrSetFromCache(cache, key, version, getValue) {
1683
+ if (!cache) {
1684
+ return getValue();
1685
+ }
1686
+ let entry = cache.get(key);
1687
+ if (entry?.version === version) {
1688
+ return entry.value;
1689
+ }
1690
+ let value = getValue();
1691
+ let newEntry = { value, version };
1692
+ cache.set(key, newEntry);
1693
+ return value;
1694
+ }
1695
+
1696
+ // vite/route-chunks.ts
1697
+ function codeToAst(code, cache, cacheKey) {
1698
+ return structuredClone(
1699
+ getOrSetFromCache(
1700
+ cache,
1701
+ `${cacheKey}::codeToAst`,
1702
+ code,
1703
+ () => (0, import_parser.parse)(code, { sourceType: "module" })
1704
+ )
1705
+ );
1706
+ }
1707
+ function assertNodePath(path7) {
1708
+ invariant(
1709
+ path7 && !Array.isArray(path7),
1710
+ `Expected a Path, but got ${Array.isArray(path7) ? "an array" : path7}`
1711
+ );
1712
+ }
1713
+ function assertNodePathIsStatement(path7) {
1714
+ invariant(
1715
+ path7 && !Array.isArray(path7) && t.isStatement(path7.node),
1716
+ `Expected a Statement path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
1717
+ );
1718
+ }
1719
+ function assertNodePathIsVariableDeclarator(path7) {
1720
+ invariant(
1721
+ path7 && !Array.isArray(path7) && t.isVariableDeclarator(path7.node),
1722
+ `Expected an Identifier path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
1723
+ );
1724
+ }
1725
+ function assertNodePathIsPattern(path7) {
1726
+ invariant(
1727
+ path7 && !Array.isArray(path7) && t.isPattern(path7.node),
1728
+ `Expected a Pattern path, but got ${Array.isArray(path7) ? "an array" : path7?.node?.type}`
1729
+ );
1730
+ }
1731
+ function getExportDependencies(code, cache, cacheKey) {
1732
+ return getOrSetFromCache(
1733
+ cache,
1734
+ `${cacheKey}::getExportDependencies`,
1735
+ code,
1736
+ () => {
1737
+ let exportDependencies = /* @__PURE__ */ new Map();
1738
+ let ast = codeToAst(code, cache, cacheKey);
1739
+ function handleExport(exportName, exportPath, identifiersPath = exportPath) {
1740
+ let identifiers = getDependentIdentifiersForPath(identifiersPath);
1741
+ let topLevelStatements = /* @__PURE__ */ new Set([
1742
+ exportPath.node,
1743
+ ...getTopLevelStatementsForPaths(identifiers)
1744
+ ]);
1745
+ let topLevelNonModuleStatements = new Set(
1746
+ Array.from(topLevelStatements).filter(
1747
+ (statement) => !t.isImportDeclaration(statement) && !t.isExportDeclaration(statement)
1748
+ )
1749
+ );
1750
+ let importedIdentifierNames = /* @__PURE__ */ new Set();
1751
+ for (let identifier of identifiers) {
1752
+ if (identifier.parentPath.parentPath?.isImportDeclaration()) {
1753
+ importedIdentifierNames.add(identifier.node.name);
1754
+ }
1755
+ }
1756
+ let exportedVariableDeclarators = /* @__PURE__ */ new Set();
1757
+ for (let identifier of identifiers) {
1758
+ if (identifier.parentPath.isVariableDeclarator() && identifier.parentPath.parentPath.parentPath?.isExportNamedDeclaration()) {
1759
+ exportedVariableDeclarators.add(identifier.parentPath.node);
1760
+ continue;
1761
+ }
1762
+ let isWithinExportDestructuring = Boolean(
1763
+ identifier.findParent(
1764
+ (path7) => Boolean(
1765
+ path7.isPattern() && path7.parentPath?.isVariableDeclarator() && path7.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
1766
+ )
1767
+ )
1768
+ );
1769
+ if (isWithinExportDestructuring) {
1770
+ let currentPath = identifier;
1771
+ while (currentPath) {
1772
+ if (
1773
+ // Check the identifier is within a variable declaration, and if
1774
+ // so, ensure we're on the left-hand side of the expression
1775
+ // since these identifiers are what make up the export names,
1776
+ // e.g. export const { foo } = { foo: bar }; should pick up
1777
+ // `foo` but not `bar`.
1778
+ currentPath.parentPath?.isVariableDeclarator() && currentPath.parentKey === "id"
1779
+ ) {
1780
+ exportedVariableDeclarators.add(currentPath.parentPath.node);
1781
+ break;
1782
+ }
1783
+ currentPath = currentPath.parentPath;
1784
+ }
1785
+ }
1786
+ }
1787
+ let dependencies = {
1788
+ topLevelStatements,
1789
+ topLevelNonModuleStatements,
1790
+ importedIdentifierNames,
1791
+ exportedVariableDeclarators
1792
+ };
1793
+ exportDependencies.set(exportName, dependencies);
1794
+ }
1795
+ traverse(ast, {
1796
+ ExportDeclaration(exportPath) {
1797
+ let { node } = exportPath;
1798
+ if (t.isExportAllDeclaration(node)) {
1799
+ return;
1800
+ }
1801
+ if (t.isExportDefaultDeclaration(node)) {
1802
+ handleExport("default", exportPath);
1803
+ return;
1804
+ }
1805
+ let { declaration } = node;
1806
+ if (t.isVariableDeclaration(declaration)) {
1807
+ let { declarations } = declaration;
1808
+ for (let i = 0; i < declarations.length; i++) {
1809
+ let declarator = declarations[i];
1810
+ if (t.isIdentifier(declarator.id)) {
1811
+ let declaratorPath = exportPath.get(
1812
+ `declaration.declarations.${i}`
1813
+ );
1814
+ assertNodePathIsVariableDeclarator(declaratorPath);
1815
+ handleExport(declarator.id.name, exportPath, declaratorPath);
1816
+ continue;
1817
+ }
1818
+ if (t.isPattern(declarator.id)) {
1819
+ let exportedPatternPath = exportPath.get(
1820
+ `declaration.declarations.${i}.id`
1821
+ );
1822
+ assertNodePathIsPattern(exportedPatternPath);
1823
+ let identifiers = getIdentifiersForPatternPath(exportedPatternPath);
1824
+ for (let identifier of identifiers) {
1825
+ handleExport(identifier.node.name, exportPath, identifier);
1826
+ }
1827
+ }
1828
+ }
1829
+ return;
1830
+ }
1831
+ if (t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) {
1832
+ invariant(
1833
+ declaration.id,
1834
+ "Expected exported function or class declaration to have a name when not the default export"
1835
+ );
1836
+ handleExport(declaration.id.name, exportPath);
1837
+ return;
1838
+ }
1839
+ if (t.isExportNamedDeclaration(node)) {
1840
+ for (let specifier of node.specifiers) {
1841
+ if (t.isIdentifier(specifier.exported)) {
1842
+ let name = specifier.exported.name;
1843
+ let specifierPath = exportPath.get("specifiers").find((path7) => path7.node === specifier);
1844
+ invariant(
1845
+ specifierPath,
1846
+ `Expected to find specifier path for ${name}`
1847
+ );
1848
+ handleExport(name, exportPath, specifierPath);
1849
+ }
1850
+ }
1851
+ return;
1852
+ }
1853
+ throw new Error(`Unknown export node type: ${node.type}`);
1854
+ }
1855
+ });
1856
+ return exportDependencies;
1857
+ }
1858
+ );
1859
+ }
1860
+ function getDependentIdentifiersForPath(path7, state) {
1861
+ let { visited, identifiers } = state ?? {
1862
+ visited: /* @__PURE__ */ new Set(),
1863
+ identifiers: /* @__PURE__ */ new Set()
1864
+ };
1865
+ if (visited.has(path7)) {
1866
+ return identifiers;
1867
+ }
1868
+ visited.add(path7);
1869
+ path7.traverse({
1870
+ Identifier(path8) {
1871
+ if (identifiers.has(path8)) {
1872
+ return;
1873
+ }
1874
+ identifiers.add(path8);
1875
+ let binding = path8.scope.getBinding(path8.node.name);
1876
+ if (!binding) {
1877
+ return;
1878
+ }
1879
+ getDependentIdentifiersForPath(binding.path, { visited, identifiers });
1880
+ for (let reference of binding.referencePaths) {
1881
+ if (reference.isExportNamedDeclaration()) {
1882
+ continue;
1883
+ }
1884
+ getDependentIdentifiersForPath(reference, {
1885
+ visited,
1886
+ identifiers
1887
+ });
1888
+ }
1889
+ for (let constantViolation of binding.constantViolations) {
1890
+ getDependentIdentifiersForPath(constantViolation, {
1891
+ visited,
1892
+ identifiers
1893
+ });
1894
+ }
1895
+ }
1896
+ });
1897
+ let topLevelStatement = getTopLevelStatementPathForPath(path7);
1898
+ let withinImportStatement = topLevelStatement.isImportDeclaration();
1899
+ let withinExportStatement = topLevelStatement.isExportDeclaration();
1900
+ if (!withinImportStatement && !withinExportStatement) {
1901
+ getDependentIdentifiersForPath(topLevelStatement, {
1902
+ visited,
1903
+ identifiers
1904
+ });
1905
+ }
1906
+ if (withinExportStatement && path7.isIdentifier() && (t.isPattern(path7.parentPath.node) || // [foo]
1907
+ t.isPattern(path7.parentPath.parentPath?.node))) {
1908
+ let variableDeclarator = path7.findParent((p) => p.isVariableDeclarator());
1909
+ assertNodePath(variableDeclarator);
1910
+ getDependentIdentifiersForPath(variableDeclarator, {
1911
+ visited,
1912
+ identifiers
1913
+ });
1914
+ }
1915
+ return identifiers;
1916
+ }
1917
+ function getTopLevelStatementPathForPath(path7) {
1918
+ let ancestry = path7.getAncestry();
1919
+ let topLevelStatement = ancestry[ancestry.length - 2];
1920
+ assertNodePathIsStatement(topLevelStatement);
1921
+ return topLevelStatement;
1922
+ }
1923
+ function getTopLevelStatementsForPaths(paths) {
1924
+ let topLevelStatements = /* @__PURE__ */ new Set();
1925
+ for (let path7 of paths) {
1926
+ let topLevelStatement = getTopLevelStatementPathForPath(path7);
1927
+ topLevelStatements.add(topLevelStatement.node);
1928
+ }
1929
+ return topLevelStatements;
1930
+ }
1931
+ function getIdentifiersForPatternPath(patternPath, identifiers = /* @__PURE__ */ new Set()) {
1932
+ function walk(currentPath) {
1933
+ if (currentPath.isIdentifier()) {
1934
+ identifiers.add(currentPath);
1935
+ return;
1936
+ }
1937
+ if (currentPath.isObjectPattern()) {
1938
+ let { properties } = currentPath.node;
1939
+ for (let i = 0; i < properties.length; i++) {
1940
+ const property = properties[i];
1941
+ if (t.isObjectProperty(property)) {
1942
+ let valuePath = currentPath.get(`properties.${i}.value`);
1943
+ assertNodePath(valuePath);
1944
+ walk(valuePath);
1945
+ } else if (t.isRestElement(property)) {
1946
+ let argumentPath = currentPath.get(`properties.${i}.argument`);
1947
+ assertNodePath(argumentPath);
1948
+ walk(argumentPath);
1949
+ }
1950
+ }
1951
+ } else if (currentPath.isArrayPattern()) {
1952
+ let { elements } = currentPath.node;
1953
+ for (let i = 0; i < elements.length; i++) {
1954
+ const element = elements[i];
1955
+ if (element) {
1956
+ let elementPath = currentPath.get(`elements.${i}`);
1957
+ assertNodePath(elementPath);
1958
+ walk(elementPath);
1959
+ }
1960
+ }
1961
+ } else if (currentPath.isRestElement()) {
1962
+ let argumentPath = currentPath.get("argument");
1963
+ assertNodePath(argumentPath);
1964
+ walk(argumentPath);
1965
+ }
1966
+ }
1967
+ walk(patternPath);
1968
+ return identifiers;
1969
+ }
1970
+ var getExportedName = (exported) => {
1971
+ return t.isIdentifier(exported) ? exported.name : exported.value;
1972
+ };
1973
+ function setsIntersect(set1, set2) {
1974
+ let smallerSet = set1;
1975
+ let largerSet = set2;
1976
+ if (set1.size > set2.size) {
1977
+ smallerSet = set2;
1978
+ largerSet = set1;
1979
+ }
1980
+ for (let element of smallerSet) {
1981
+ if (largerSet.has(element)) {
1982
+ return true;
1983
+ }
1984
+ }
1985
+ return false;
1986
+ }
1987
+ function hasChunkableExport(code, exportName, cache, cacheKey) {
1988
+ return getOrSetFromCache(
1989
+ cache,
1990
+ `${cacheKey}::hasChunkableExport::${exportName}`,
1991
+ code,
1992
+ () => {
1993
+ let exportDependencies = getExportDependencies(code, cache, cacheKey);
1994
+ let dependencies = exportDependencies.get(exportName);
1995
+ if (!dependencies) {
1996
+ return false;
1997
+ }
1998
+ for (let [currentExportName, currentDependencies] of exportDependencies) {
1999
+ if (currentExportName === exportName) {
2000
+ continue;
2001
+ }
2002
+ if (setsIntersect(
2003
+ currentDependencies.topLevelNonModuleStatements,
2004
+ dependencies.topLevelNonModuleStatements
2005
+ )) {
2006
+ return false;
2007
+ }
2008
+ }
2009
+ if (dependencies.exportedVariableDeclarators.size > 1) {
2010
+ return false;
2011
+ }
2012
+ if (dependencies.exportedVariableDeclarators.size > 0) {
2013
+ for (let [
2014
+ currentExportName,
2015
+ currentDependencies
2016
+ ] of exportDependencies) {
2017
+ if (currentExportName === exportName) {
2018
+ continue;
2019
+ }
2020
+ if (setsIntersect(
2021
+ currentDependencies.exportedVariableDeclarators,
2022
+ dependencies.exportedVariableDeclarators
2023
+ )) {
2024
+ return false;
2025
+ }
2026
+ }
2027
+ }
2028
+ return true;
2029
+ }
2030
+ );
2031
+ }
2032
+ function getChunkedExport(code, exportName, generateOptions = {}, cache, cacheKey) {
2033
+ return getOrSetFromCache(
2034
+ cache,
2035
+ `${cacheKey}::getChunkedExport::${exportName}::${JSON.stringify(
2036
+ generateOptions
2037
+ )}`,
2038
+ code,
2039
+ () => {
2040
+ if (!hasChunkableExport(code, exportName, cache, cacheKey)) {
2041
+ return void 0;
2042
+ }
2043
+ let exportDependencies = getExportDependencies(code, cache, cacheKey);
2044
+ let dependencies = exportDependencies.get(exportName);
2045
+ invariant(dependencies, "Expected export to have dependencies");
2046
+ let topLevelStatementsArray = Array.from(dependencies.topLevelStatements);
2047
+ let exportedVariableDeclaratorsArray = Array.from(
2048
+ dependencies.exportedVariableDeclarators
2049
+ );
2050
+ let ast = codeToAst(code, cache, cacheKey);
2051
+ ast.program.body = ast.program.body.filter(
2052
+ (node) => topLevelStatementsArray.some(
2053
+ (statement) => t.isNodesEquivalent(node, statement)
2054
+ )
2055
+ ).map((node) => {
2056
+ if (!t.isImportDeclaration(node)) {
2057
+ return node;
2058
+ }
2059
+ if (dependencies.importedIdentifierNames.size === 0) {
2060
+ return null;
2061
+ }
2062
+ node.specifiers = node.specifiers.filter(
2063
+ (specifier) => dependencies.importedIdentifierNames.has(specifier.local.name)
2064
+ );
2065
+ invariant(
2066
+ node.specifiers.length > 0,
2067
+ "Expected import statement to have used specifiers"
2068
+ );
2069
+ return node;
2070
+ }).map((node) => {
2071
+ if (!t.isExportDeclaration(node)) {
2072
+ return node;
2073
+ }
2074
+ if (t.isExportAllDeclaration(node)) {
2075
+ return null;
2076
+ }
2077
+ if (t.isExportDefaultDeclaration(node)) {
2078
+ return exportName === "default" ? node : null;
2079
+ }
2080
+ let { declaration } = node;
2081
+ if (t.isVariableDeclaration(declaration)) {
2082
+ declaration.declarations = declaration.declarations.filter(
2083
+ (node2) => exportedVariableDeclaratorsArray.some(
2084
+ (declarator) => t.isNodesEquivalent(node2, declarator)
2085
+ )
2086
+ );
2087
+ if (declaration.declarations.length === 0) {
2088
+ return null;
2089
+ }
2090
+ return node;
2091
+ }
2092
+ if (t.isFunctionDeclaration(node.declaration) || t.isClassDeclaration(node.declaration)) {
2093
+ return node.declaration.id?.name === exportName ? node : null;
2094
+ }
2095
+ if (t.isExportNamedDeclaration(node)) {
2096
+ if (node.specifiers.length === 0) {
2097
+ return null;
2098
+ }
2099
+ node.specifiers = node.specifiers.filter(
2100
+ (specifier) => getExportedName(specifier.exported) === exportName
2101
+ );
2102
+ if (node.specifiers.length === 0) {
2103
+ return null;
2104
+ }
2105
+ return node;
2106
+ }
2107
+ throw new Error(`Unknown export node type: ${node.type}`);
2108
+ }).filter((node) => node !== null);
2109
+ return generate(ast, generateOptions);
2110
+ }
2111
+ );
2112
+ }
2113
+ function omitChunkedExports(code, exportNames, generateOptions = {}, cache, cacheKey) {
2114
+ return getOrSetFromCache(
2115
+ cache,
2116
+ `${cacheKey}::omitChunkedExports::${exportNames.join(
2117
+ ","
2118
+ )}::${JSON.stringify(generateOptions)}`,
2119
+ code,
2120
+ () => {
2121
+ const isChunkable = (exportName) => hasChunkableExport(code, exportName, cache, cacheKey);
2122
+ const isOmitted = (exportName) => exportNames.includes(exportName) && isChunkable(exportName);
2123
+ const isRetained = (exportName) => !isOmitted(exportName);
2124
+ let exportDependencies = getExportDependencies(code, cache, cacheKey);
2125
+ let allExportNames = Array.from(exportDependencies.keys());
2126
+ let omittedExportNames = allExportNames.filter(isOmitted);
2127
+ let retainedExportNames = allExportNames.filter(isRetained);
2128
+ let omittedStatements = /* @__PURE__ */ new Set();
2129
+ let omittedExportedVariableDeclarators = /* @__PURE__ */ new Set();
2130
+ for (let omittedExportName of omittedExportNames) {
2131
+ let dependencies = exportDependencies.get(omittedExportName);
2132
+ invariant(
2133
+ dependencies,
2134
+ `Expected dependencies for ${omittedExportName}`
2135
+ );
2136
+ for (let statement of dependencies.topLevelNonModuleStatements) {
2137
+ omittedStatements.add(statement);
2138
+ }
2139
+ for (let declarator of dependencies.exportedVariableDeclarators) {
2140
+ omittedExportedVariableDeclarators.add(declarator);
2141
+ }
2142
+ }
2143
+ let ast = codeToAst(code, cache, cacheKey);
2144
+ let omittedStatementsArray = Array.from(omittedStatements);
2145
+ let omittedExportedVariableDeclaratorsArray = Array.from(
2146
+ omittedExportedVariableDeclarators
2147
+ );
2148
+ ast.program.body = ast.program.body.filter(
2149
+ (node) => omittedStatementsArray.every(
2150
+ (statement) => !t.isNodesEquivalent(node, statement)
2151
+ )
2152
+ ).map((node) => {
2153
+ if (!t.isImportDeclaration(node)) {
2154
+ return node;
2155
+ }
2156
+ if (node.specifiers.length === 0) {
2157
+ return node;
2158
+ }
2159
+ node.specifiers = node.specifiers.filter((specifier) => {
2160
+ let importedName = specifier.local.name;
2161
+ for (let retainedExportName of retainedExportNames) {
2162
+ let dependencies = exportDependencies.get(retainedExportName);
2163
+ if (dependencies?.importedIdentifierNames?.has(importedName)) {
2164
+ return true;
2165
+ }
2166
+ }
2167
+ for (let omittedExportName of omittedExportNames) {
2168
+ let dependencies = exportDependencies.get(omittedExportName);
2169
+ if (dependencies?.importedIdentifierNames?.has(importedName)) {
2170
+ return false;
2171
+ }
2172
+ }
2173
+ return true;
2174
+ });
2175
+ if (node.specifiers.length === 0) {
2176
+ return null;
2177
+ }
2178
+ return node;
2179
+ }).map((node) => {
2180
+ if (!t.isExportDeclaration(node)) {
2181
+ return node;
2182
+ }
2183
+ if (t.isExportAllDeclaration(node)) {
2184
+ return node;
2185
+ }
2186
+ if (t.isExportDefaultDeclaration(node)) {
2187
+ return isOmitted("default") ? null : node;
2188
+ }
2189
+ if (t.isVariableDeclaration(node.declaration)) {
2190
+ node.declaration.declarations = node.declaration.declarations.filter(
2191
+ (node2) => omittedExportedVariableDeclaratorsArray.every(
2192
+ (declarator) => !t.isNodesEquivalent(node2, declarator)
2193
+ )
2194
+ );
2195
+ if (node.declaration.declarations.length === 0) {
2196
+ return null;
2197
+ }
2198
+ return node;
2199
+ }
2200
+ if (t.isFunctionDeclaration(node.declaration) || t.isClassDeclaration(node.declaration)) {
2201
+ invariant(
2202
+ node.declaration.id,
2203
+ "Expected exported function or class declaration to have a name when not the default export"
2204
+ );
2205
+ return isOmitted(node.declaration.id.name) ? null : node;
2206
+ }
2207
+ if (t.isExportNamedDeclaration(node)) {
2208
+ if (node.specifiers.length === 0) {
2209
+ return node;
2210
+ }
2211
+ node.specifiers = node.specifiers.filter((specifier) => {
2212
+ const exportedName = getExportedName(specifier.exported);
2213
+ return !isOmitted(exportedName);
2214
+ });
2215
+ if (node.specifiers.length === 0) {
2216
+ return null;
2217
+ }
2218
+ return node;
2219
+ }
2220
+ throw new Error(`Unknown node type: ${node.type}`);
2221
+ }).filter((node) => node !== null);
2222
+ if (ast.program.body.length === 0) {
2223
+ return void 0;
2224
+ }
2225
+ return generate(ast, generateOptions);
2226
+ }
2227
+ );
2228
+ }
2229
+ function detectRouteChunks(code, cache, cacheKey) {
2230
+ const hasRouteChunkByExportName = Object.fromEntries(
2231
+ routeChunkExportNames.map((exportName) => [
2232
+ exportName,
2233
+ hasChunkableExport(code, exportName, cache, cacheKey)
2234
+ ])
2235
+ );
2236
+ const chunkedExports = Object.entries(hasRouteChunkByExportName).filter(([, isChunked]) => isChunked).map(([exportName]) => exportName);
2237
+ const hasRouteChunks = chunkedExports.length > 0;
2238
+ return {
2239
+ hasRouteChunks,
2240
+ hasRouteChunkByExportName,
2241
+ chunkedExports
2242
+ };
2243
+ }
2244
+ var routeChunkExportNames = [
2245
+ "clientAction",
2246
+ "clientLoader",
2247
+ "clientMiddleware",
2248
+ "HydrateFallback"
2249
+ ];
2250
+ var mainChunkName = "main";
2251
+ var routeChunkNames = ["main", ...routeChunkExportNames];
2252
+ function getRouteChunkCode(code, chunkName, cache, cacheKey) {
2253
+ if (chunkName === mainChunkName) {
2254
+ return omitChunkedExports(code, routeChunkExportNames, {}, cache, cacheKey);
2255
+ }
2256
+ return getChunkedExport(code, chunkName, {}, cache, cacheKey);
2257
+ }
2258
+ var routeChunkQueryStringPrefix = "?route-chunk=";
2259
+ var routeChunkQueryStrings = {
2260
+ main: `${routeChunkQueryStringPrefix}main`,
2261
+ clientAction: `${routeChunkQueryStringPrefix}clientAction`,
2262
+ clientLoader: `${routeChunkQueryStringPrefix}clientLoader`,
2263
+ clientMiddleware: `${routeChunkQueryStringPrefix}clientMiddleware`,
2264
+ HydrateFallback: `${routeChunkQueryStringPrefix}HydrateFallback`
2265
+ };
2266
+ function getRouteChunkModuleId(filePath, chunkName) {
2267
+ return `${filePath}${routeChunkQueryStrings[chunkName]}`;
2268
+ }
2269
+ function isRouteChunkModuleId(id) {
2270
+ return Object.values(routeChunkQueryStrings).some(
2271
+ (queryString) => id.endsWith(queryString)
2272
+ );
2273
+ }
2274
+ function isRouteChunkName(name) {
2275
+ return name === mainChunkName || routeChunkExportNames.includes(name);
2276
+ }
2277
+ function getRouteChunkNameFromModuleId(id) {
2278
+ if (!isRouteChunkModuleId(id)) {
2279
+ return null;
2280
+ }
2281
+ let chunkName = id.split(routeChunkQueryStringPrefix)[1].split("&")[0];
2282
+ if (!isRouteChunkName(chunkName)) {
2283
+ return null;
2284
+ }
2285
+ return chunkName;
2286
+ }
2287
+
2288
+ // vite/optimize-deps-entries.ts
2289
+ var import_tinyglobby = require("tinyglobby");
2290
+ function getOptimizeDepsEntries({
2291
+ entryClientFilePath,
2292
+ reactRouterConfig
2293
+ }) {
2294
+ if (!reactRouterConfig.future.unstable_optimizeDeps) {
2295
+ return [];
2296
+ }
2297
+ const vite2 = getVite();
2298
+ const viteMajorVersion = parseInt(vite2.version.split(".")[0], 10);
2299
+ return [
2300
+ vite2.normalizePath(entryClientFilePath),
2301
+ ...Object.values(reactRouterConfig.routes).map(
2302
+ (route) => resolveRelativeRouteFilePath(route, reactRouterConfig)
2303
+ )
2304
+ ].map(
2305
+ (entry) => (
2306
+ // In Vite 7, the `optimizeDeps.entries` option only accepts glob patterns.
2307
+ // In prior versions, absolute file paths were treated differently.
2308
+ viteMajorVersion >= 7 ? (0, import_tinyglobby.escapePath)(entry) : entry
2309
+ )
2310
+ );
2311
+ }
2312
+
2313
+ // vite/with-props.ts
2314
+ var namedComponentExports = ["HydrateFallback", "ErrorBoundary"];
2315
+ function isNamedComponentExport(name) {
2316
+ return namedComponentExports.includes(name);
2317
+ }
2318
+ var decorateComponentExportsWithProps = (ast) => {
2319
+ const hocs = [];
2320
+ function getHocUid(path7, hocName) {
2321
+ const uid = path7.scope.generateUidIdentifier(hocName);
2322
+ hocs.push([hocName, uid]);
2323
+ return uid;
2324
+ }
2325
+ traverse(ast, {
2326
+ ExportDeclaration(path7) {
2327
+ if (path7.isExportDefaultDeclaration()) {
2328
+ const declaration = path7.get("declaration");
2329
+ const expr = declaration.isExpression() ? declaration.node : declaration.isFunctionDeclaration() ? toFunctionExpression(declaration.node) : void 0;
2330
+ if (expr) {
2331
+ const uid = getHocUid(path7, "UNSAFE_withComponentProps");
2332
+ declaration.replaceWith(t.callExpression(uid, [expr]));
2333
+ }
2334
+ return;
2335
+ }
2336
+ if (path7.isExportNamedDeclaration()) {
2337
+ const decl = path7.get("declaration");
2338
+ if (decl.isVariableDeclaration()) {
2339
+ decl.get("declarations").forEach((varDeclarator) => {
2340
+ const id = varDeclarator.get("id");
2341
+ const init = varDeclarator.get("init");
2342
+ const expr = init.node;
2343
+ if (!expr) return;
2344
+ if (!id.isIdentifier()) return;
2345
+ const { name } = id.node;
2346
+ if (!isNamedComponentExport(name)) return;
2347
+ const uid = getHocUid(path7, `UNSAFE_with${name}Props`);
2348
+ init.replaceWith(t.callExpression(uid, [expr]));
2349
+ });
2350
+ return;
2351
+ }
2352
+ if (decl.isFunctionDeclaration()) {
2353
+ const { id } = decl.node;
2354
+ if (!id) return;
2355
+ const { name } = id;
2356
+ if (!isNamedComponentExport(name)) return;
2357
+ const uid = getHocUid(path7, `UNSAFE_with${name}Props`);
2358
+ decl.replaceWith(
2359
+ t.variableDeclaration("const", [
2360
+ t.variableDeclarator(
2361
+ t.identifier(name),
2362
+ t.callExpression(uid, [toFunctionExpression(decl.node)])
2363
+ )
2364
+ ])
2365
+ );
2366
+ }
2367
+ }
2368
+ }
2369
+ });
2370
+ if (hocs.length > 0) {
2371
+ ast.program.body.unshift(
2372
+ t.importDeclaration(
2373
+ hocs.map(
2374
+ ([name, identifier]) => t.importSpecifier(identifier, t.identifier(name))
2375
+ ),
2376
+ t.stringLiteral("react-router")
2377
+ )
2378
+ );
2379
+ }
2380
+ };
2381
+ function toFunctionExpression(decl) {
2382
+ return t.functionExpression(
2383
+ decl.id,
2384
+ decl.params,
2385
+ decl.body,
2386
+ decl.generator,
2387
+ decl.async
2388
+ );
2389
+ }
2390
+
2391
+ // vite/plugins/validate-plugin-order.ts
2392
+ function validatePluginOrder() {
2393
+ return {
2394
+ name: "react-router:validate-plugin-order",
2395
+ configResolved(viteConfig) {
2396
+ let pluginIndex = (pluginName) => {
2397
+ pluginName = Array.isArray(pluginName) ? pluginName : [pluginName];
2398
+ return viteConfig.plugins.findIndex(
2399
+ (plugin) => pluginName.includes(plugin.name)
2400
+ );
2401
+ };
2402
+ let reactRouterRscPluginIndex = pluginIndex("react-router/rsc");
2403
+ let viteRscPluginIndex = pluginIndex("rsc");
2404
+ if (reactRouterRscPluginIndex >= 0 && viteRscPluginIndex >= 0 && reactRouterRscPluginIndex > viteRscPluginIndex) {
2405
+ throw new Error(
2406
+ `The "@vitejs/plugin-rsc" plugin should be placed after the React Router RSC plugin in your Vite config`
2407
+ );
2408
+ }
2409
+ let reactRouterPluginIndex = pluginIndex([
2410
+ "react-router",
2411
+ "react-router/rsc"
2412
+ ]);
2413
+ let mdxPluginIndex = pluginIndex("@mdx-js/rollup");
2414
+ if (mdxPluginIndex >= 0 && mdxPluginIndex > reactRouterPluginIndex) {
2415
+ throw new Error(
2416
+ `The "@mdx-js/rollup" plugin should be placed before the React Router plugin in your Vite config`
2417
+ );
2418
+ }
2419
+ }
2420
+ };
2421
+ }
2422
+
2423
+ // vite/plugin.ts
2424
+ function extractPluginContext(viteConfig) {
2425
+ return viteConfig["__reactRouterPluginContext"];
2426
+ }
2427
+ var SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "middleware", "headers"];
2428
+ var CLIENT_NON_COMPONENT_EXPORTS = [
2429
+ "clientAction",
2430
+ "clientLoader",
2431
+ "clientMiddleware",
2432
+ "handle",
2433
+ "meta",
2434
+ "links",
2435
+ "shouldRevalidate"
2436
+ ];
2437
+ var CLIENT_ROUTE_EXPORTS = [
2438
+ ...CLIENT_NON_COMPONENT_EXPORTS,
2439
+ "default",
2440
+ "ErrorBoundary",
2441
+ "HydrateFallback",
2442
+ "Layout"
2443
+ ];
2444
+ var BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
2445
+ var SSR_BUNDLE_PREFIX = "ssrBundle_";
2446
+ function isSsrBundleEnvironmentName(name) {
2447
+ return name.startsWith(SSR_BUNDLE_PREFIX);
2448
+ }
2449
+ function getServerEnvironmentEntries(ctx, record) {
2450
+ return Object.entries(record).filter(
2451
+ ([name]) => ctx.buildManifest?.serverBundles ? isSsrBundleEnvironmentName(name) : name === "ssr"
2452
+ );
2453
+ }
2454
+ function getServerEnvironmentValues(ctx, record) {
2455
+ return getServerEnvironmentEntries(ctx, record).map(([, value]) => value);
2456
+ }
2457
+ var isRouteEntryModuleId = (id) => {
2458
+ return id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING);
2459
+ };
2460
+ var isRouteVirtualModule = (id) => {
2461
+ return isRouteEntryModuleId(id) || isRouteChunkModuleId(id);
2462
+ };
2463
+ var isServerBuildVirtualModuleId = (id) => {
2464
+ return id.split("?")[0] === virtual.serverBuild.id;
2465
+ };
2466
+ var getServerBuildFile = (viteManifest) => {
2467
+ let serverBuildIds = Object.keys(viteManifest).filter(
2468
+ isServerBuildVirtualModuleId
2469
+ );
2470
+ invariant(
2471
+ serverBuildIds.length <= 1,
2472
+ "Multiple server build files found in manifest"
2473
+ );
2474
+ invariant(
2475
+ serverBuildIds.length === 1,
2476
+ "Server build file not found in manifest"
2477
+ );
2478
+ return viteManifest[serverBuildIds[0]].file;
2479
+ };
2480
+ var virtualHmrRuntime = create("hmr-runtime");
2481
+ var virtualInjectHmrRuntime = create("inject-hmr-runtime");
2482
+ var normalizeRelativeFilePath = (file, reactRouterConfig) => {
2483
+ let vite2 = getVite();
2484
+ let fullPath = path6.resolve(reactRouterConfig.appDirectory, file);
2485
+ let relativePath = path6.relative(reactRouterConfig.appDirectory, fullPath);
2486
+ return vite2.normalizePath(relativePath).split("?")[0];
2487
+ };
2488
+ var virtual = {
2489
+ serverBuild: create("server-build"),
2490
+ serverManifest: create("server-manifest"),
2491
+ browserManifest: create("browser-manifest")
2492
+ };
2493
+ var invalidateVirtualModules = (viteDevServer) => {
2494
+ Object.values(virtual).forEach((vmod) => {
2495
+ let mod = viteDevServer.moduleGraph.getModuleById(vmod.resolvedId);
2496
+ if (mod) {
2497
+ viteDevServer.moduleGraph.invalidateModule(mod);
2498
+ }
2499
+ });
2500
+ };
2501
+ var getHash = (source, maxLength) => {
2502
+ let hash = (0, import_node_crypto.createHash)("sha256").update(source).digest("hex");
2503
+ return typeof maxLength === "number" ? hash.slice(0, maxLength) : hash;
2504
+ };
2505
+ var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
2506
+ let vite2 = getVite();
2507
+ let rootRelativeFilePath = vite2.normalizePath(
2508
+ path6.relative(ctx.rootDirectory, absoluteFilePath)
2509
+ );
2510
+ let entryChunk = viteManifest[rootRelativeFilePath];
2511
+ if (!entryChunk) {
2512
+ return void 0;
2513
+ }
2514
+ return entryChunk;
2515
+ };
2516
+ var getPublicModulePathForEntry = (ctx, viteManifest, entryFilePath) => {
2517
+ let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
2518
+ return entryChunk ? `${ctx.publicPath}${entryChunk.file}` : void 0;
2519
+ };
2520
+ var getCssCodeSplitDisabledFile = (ctx, viteConfig, viteManifest) => {
2521
+ if (viteConfig.build.cssCodeSplit) {
2522
+ return null;
2523
+ }
2524
+ let cssFile = viteManifest["style.css"]?.file;
2525
+ invariant(
2526
+ cssFile,
2527
+ "Expected `style.css` to be present in Vite manifest when `build.cssCodeSplit` is disabled"
2528
+ );
2529
+ return `${ctx.publicPath}${cssFile}`;
2530
+ };
2531
+ var getClientEntryChunk = (ctx, viteManifest) => {
2532
+ let filePath = ctx.entryClientFilePath;
2533
+ let chunk = resolveChunk(ctx, viteManifest, filePath);
2534
+ invariant(chunk, `Chunk not found: ${filePath}`);
2535
+ return chunk;
2536
+ };
2537
+ var getReactRouterManifestBuildAssets = (ctx, viteConfig, viteManifest, entryFilePath, route) => {
2538
+ let entryChunk = resolveChunk(ctx, viteManifest, entryFilePath);
2539
+ invariant(entryChunk, `Chunk not found: ${entryFilePath}`);
2540
+ let isRootRoute = Boolean(route && route.parentId === void 0);
2541
+ let routeModuleChunks = routeChunkNames.map(
2542
+ (routeChunkName) => resolveChunk(
2543
+ ctx,
2544
+ viteManifest,
2545
+ getRouteChunkModuleId(entryFilePath.split("?")[0], routeChunkName)
2546
+ )
2547
+ ).filter(isNonNullable);
2548
+ let chunks = resolveDependantChunks(
2549
+ viteManifest,
2550
+ [
2551
+ // If this is the root route, we also need to include assets from the
2552
+ // client entry file as this is a common way for consumers to import
2553
+ // global reset styles, etc.
2554
+ isRootRoute ? getClientEntryChunk(ctx, viteManifest) : null,
2555
+ entryChunk,
2556
+ routeModuleChunks
2557
+ ].flat(1).filter(isNonNullable)
2558
+ );
2559
+ return {
2560
+ module: `${ctx.publicPath}${entryChunk.file}`,
2561
+ imports: dedupe(chunks.flatMap((e) => e.imports ?? [])).map((imported) => {
2562
+ return `${ctx.publicPath}${viteManifest[imported].file}`;
2563
+ }) ?? [],
2564
+ css: dedupe(
2565
+ [
2566
+ // If CSS code splitting is disabled, Vite includes a singular 'style.css' asset
2567
+ // in the manifest that isn't tied to any route file. If we want to render these
2568
+ // styles correctly, we need to include them in the root route.
2569
+ isRootRoute ? getCssCodeSplitDisabledFile(ctx, viteConfig, viteManifest) : null,
2570
+ chunks.flatMap((e) => e.css ?? []).map((href) => `${ctx.publicPath}${href}`)
2571
+ ].flat(1).filter(isNonNullable)
2572
+ )
2573
+ };
2574
+ };
2575
+ function resolveDependantChunks(viteManifest, entryChunks) {
2576
+ let chunks = /* @__PURE__ */ new Set();
2577
+ function walk(chunk) {
2578
+ if (chunks.has(chunk)) {
2579
+ return;
2580
+ }
2581
+ chunks.add(chunk);
2582
+ if (chunk.imports) {
2583
+ for (let importKey of chunk.imports) {
2584
+ walk(viteManifest[importKey]);
2585
+ }
2586
+ }
2587
+ }
2588
+ for (let entryChunk of entryChunks) {
2589
+ walk(entryChunk);
2590
+ }
2591
+ return Array.from(chunks);
2592
+ }
2593
+ function dedupe(array2) {
2594
+ return [...new Set(array2)];
2595
+ }
2596
+ var writeFileSafe = async (file, contents) => {
2597
+ await (0, import_promises2.mkdir)(path6.dirname(file), { recursive: true });
2598
+ await (0, import_promises2.writeFile)(file, contents);
2599
+ };
2600
+ var getExportNames = (code) => {
2601
+ let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
2602
+ return exportSpecifiers.map(({ n: name }) => name);
2603
+ };
2604
+ var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
2605
+ let entries = await Promise.all(
2606
+ Object.entries(ctx.reactRouterConfig.routes).map(async ([key, route]) => {
2607
+ let sourceExports = await getRouteModuleExports(
2608
+ viteChildCompiler,
2609
+ ctx,
2610
+ route.file
2611
+ );
2612
+ return [key, sourceExports];
2613
+ })
2614
+ );
2615
+ return Object.fromEntries(entries);
2616
+ };
2617
+ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
2618
+ if (!viteChildCompiler) {
2619
+ throw new Error("Vite child compiler not found");
2620
+ }
2621
+ let ssr = true;
2622
+ let { pluginContainer, moduleGraph } = viteChildCompiler;
2623
+ let routePath = path6.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
2624
+ let url2 = resolveFileUrl(ctx, routePath);
2625
+ let resolveId = async () => {
2626
+ let result = await pluginContainer.resolveId(url2, void 0, { ssr });
2627
+ if (!result) throw new Error(`Could not resolve module ID for ${url2}`);
2628
+ return result.id;
2629
+ };
2630
+ let [id, code] = await Promise.all([
2631
+ resolveId(),
2632
+ readRouteFile?.() ?? (0, import_promises2.readFile)(routePath, "utf-8"),
2633
+ // pluginContainer.transform(...) fails if we don't do this first:
2634
+ moduleGraph.ensureEntryFromUrl(url2, ssr)
2635
+ ]);
2636
+ let transformed = await pluginContainer.transform(code, id, { ssr });
2637
+ return transformed.code;
2638
+ };
2639
+ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
2640
+ if (!viteChildCompiler) {
2641
+ throw new Error("Vite child compiler not found");
2642
+ }
2643
+ let code = await compileRouteFile(
2644
+ viteChildCompiler,
2645
+ ctx,
2646
+ routeFile,
2647
+ readRouteFile
2648
+ );
2649
+ return getExportNames(code);
2650
+ };
2651
+ var resolveEnvironmentBuildContext = ({
2652
+ viteCommand,
2653
+ viteUserConfig
2654
+ }) => {
2655
+ if (!("__reactRouterEnvironmentBuildContext" in viteUserConfig) || !viteUserConfig.__reactRouterEnvironmentBuildContext) {
2656
+ return null;
2657
+ }
2658
+ let buildContext = viteUserConfig.__reactRouterEnvironmentBuildContext;
2659
+ let resolvedBuildContext = {
2660
+ name: buildContext.name,
2661
+ options: buildContext.resolveOptions({ viteUserConfig })
2662
+ };
2663
+ return resolvedBuildContext;
2664
+ };
2665
+ var getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
2666
+ reactRouterConfig.buildDirectory,
2667
+ "server",
2668
+ ...serverBundleId ? [serverBundleId] : []
2669
+ );
2670
+ var getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
2671
+ var getServerBundleRouteIds = (vitePluginContext, ctx) => {
2672
+ if (!ctx.buildManifest) {
2673
+ return void 0;
2674
+ }
2675
+ let environmentName = ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? vitePluginContext.environment.name : ctx.environmentBuildContext?.name;
2676
+ if (!environmentName || !isSsrBundleEnvironmentName(environmentName)) {
2677
+ return void 0;
2678
+ }
2679
+ let serverBundleId = environmentName.replace(SSR_BUNDLE_PREFIX, "");
2680
+ let routesByServerBundleId = getRoutesByServerBundleId(ctx.buildManifest);
2681
+ let serverBundleRoutes = routesByServerBundleId[serverBundleId];
2682
+ invariant(
2683
+ serverBundleRoutes,
2684
+ `Routes not found for server bundle "${serverBundleId}"`
2685
+ );
2686
+ return Object.keys(serverBundleRoutes);
2687
+ };
2688
+ var defaultEntriesDir = path6.resolve(
2689
+ path6.dirname(require.resolve("@react-router/dev/package.json")),
2690
+ "dist",
2691
+ "config",
2692
+ "defaults"
2693
+ );
2694
+ var defaultEntries = (0, import_node_fs2.readdirSync)(defaultEntriesDir).map(
2695
+ (filename2) => path6.join(defaultEntriesDir, filename2)
2696
+ );
2697
+ invariant(defaultEntries.length > 0, "No default entries found");
2698
+ var reactRouterDevLoadContext = () => void 0;
2699
+ var reactRouterVitePlugin = () => {
2700
+ let rootDirectory;
2701
+ let viteCommand;
2702
+ let viteUserConfig;
2703
+ let viteConfigEnv;
2704
+ let viteConfig;
2705
+ let cssModulesManifest = {};
2706
+ let viteChildCompiler = null;
2707
+ let cache = /* @__PURE__ */ new Map();
2708
+ let reactRouterConfigLoader;
2709
+ let typegenWatcherPromise;
2710
+ let logger;
2711
+ let firstLoad = true;
2712
+ let ctx;
2713
+ let updatePluginContext = async () => {
2714
+ let reactRouterConfig;
2715
+ let reactRouterConfigResult = await reactRouterConfigLoader.getConfig();
2716
+ if (reactRouterConfigResult.ok) {
2717
+ reactRouterConfig = reactRouterConfigResult.value;
2718
+ } else {
2719
+ logger.error(reactRouterConfigResult.error);
2720
+ if (firstLoad) {
2721
+ process.exit(1);
2722
+ }
2723
+ return;
2724
+ }
2725
+ let injectedPluginContext = !reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "build" ? extractPluginContext(viteUserConfig) : void 0;
2726
+ let { entryClientFilePath, entryServerFilePath } = await resolveEntryFiles({
2727
+ rootDirectory,
2728
+ reactRouterConfig
2729
+ });
2730
+ let publicPath = viteUserConfig.base ?? "/";
2731
+ if (reactRouterConfig.basename !== "/" && viteCommand === "serve" && !viteUserConfig.server?.middlewareMode && !reactRouterConfig.basename.startsWith(publicPath)) {
2732
+ logger.error(
2733
+ import_picocolors3.default.red(
2734
+ "When using the React Router `basename` and the Vite `base` config, the `basename` config must begin with `base` for the default Vite dev server."
2735
+ )
2736
+ );
2737
+ process.exit(1);
2738
+ }
2739
+ let viteManifestEnabled = viteUserConfig.build?.manifest === true;
2740
+ let buildManifest = viteCommand === "build" ? injectedPluginContext?.buildManifest ?? await getBuildManifest({ reactRouterConfig, rootDirectory }) : null;
2741
+ let environmentBuildContext = viteCommand === "build" ? resolveEnvironmentBuildContext({ viteCommand, viteUserConfig }) : null;
2742
+ firstLoad = false;
2743
+ ctx = {
2744
+ environmentBuildContext,
2745
+ reactRouterConfig,
2746
+ rootDirectory,
2747
+ entryClientFilePath,
2748
+ entryServerFilePath,
2749
+ publicPath,
2750
+ viteManifestEnabled,
2751
+ buildManifest
2752
+ };
2753
+ };
2754
+ let getServerEntry = async ({ routeIds }) => {
2755
+ invariant(viteConfig, "viteconfig required to generate the server entry");
2756
+ let routes = routeIds ? (
2757
+ // For server bundle builds, the server build should only import the
2758
+ // routes for this bundle rather than importing all routes
2759
+ (0, import_pick3.default)(ctx.reactRouterConfig.routes, routeIds)
2760
+ ) : (
2761
+ // Otherwise, all routes are imported as usual
2762
+ ctx.reactRouterConfig.routes
2763
+ );
2764
+ let prerenderPaths = await getPrerenderPaths(
2765
+ ctx.reactRouterConfig.prerender,
2766
+ ctx.reactRouterConfig.ssr,
2767
+ routes
2768
+ );
2769
+ let isSpaMode = isSpaModeEnabled(ctx.reactRouterConfig);
2770
+ return `
2771
+ import * as entryServer from ${JSON.stringify(
2772
+ resolveFileUrl(ctx, ctx.entryServerFilePath)
2773
+ )};
2774
+ ${Object.keys(routes).map((key, index) => {
2775
+ let route = routes[key];
2776
+ if (isSpaMode && key !== "root") {
2777
+ return `const route${index} = { default: () => null };`;
2778
+ } else {
2779
+ return `import * as route${index} from ${JSON.stringify(
2780
+ resolveFileUrl(
2781
+ ctx,
2782
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
2783
+ )
2784
+ )};`;
2785
+ }
2786
+ }).join("\n")}
2787
+ export { default as assets } from ${JSON.stringify(
2788
+ virtual.serverManifest.id
2789
+ )};
2790
+ export const assetsBuildDirectory = ${JSON.stringify(
2791
+ path6.relative(
2792
+ ctx.rootDirectory,
2793
+ getClientBuildDirectory(ctx.reactRouterConfig)
2794
+ )
2795
+ )};
2796
+ export const basename = ${JSON.stringify(ctx.reactRouterConfig.basename)};
2797
+ export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
2798
+ export const ssr = ${ctx.reactRouterConfig.ssr};
2799
+ export const isSpaMode = ${isSpaMode};
2800
+ export const prerender = ${JSON.stringify(prerenderPaths)};
2801
+ export const routeDiscovery = ${JSON.stringify(
2802
+ ctx.reactRouterConfig.routeDiscovery
2803
+ )};
2804
+ export const publicPath = ${JSON.stringify(ctx.publicPath)};
2805
+ export const entry = { module: entryServer };
2806
+ export const routes = {
2807
+ ${Object.keys(routes).map((key, index) => {
2808
+ let route = routes[key];
2809
+ return `${JSON.stringify(key)}: {
2810
+ id: ${JSON.stringify(route.id)},
2811
+ parentId: ${JSON.stringify(route.parentId)},
2812
+ path: ${JSON.stringify(route.path)},
2813
+ index: ${JSON.stringify(route.index)},
2814
+ caseSensitive: ${JSON.stringify(route.caseSensitive)},
2815
+ module: route${index}
2816
+ }`;
2817
+ }).join(",\n ")}
2818
+ };
2819
+ ${ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve" ? `
2820
+ export const unstable_getCriticalCss = ({ pathname }) => {
2821
+ return {
2822
+ rel: "stylesheet",
2823
+ href: "${ctx.publicPath}@react-router/critical.css?pathname=" + pathname,
2824
+ };
2825
+ }
2826
+ ` : ""}`;
2827
+ };
2828
+ let loadViteManifest = async (directory) => {
2829
+ let manifestContents = await (0, import_promises2.readFile)(
2830
+ path6.resolve(directory, ".vite", "manifest.json"),
2831
+ "utf-8"
2832
+ );
2833
+ return JSON.parse(manifestContents);
2834
+ };
2835
+ let getViteManifestAssetPaths = (viteManifest) => {
2836
+ let cssUrlPaths = Object.values(viteManifest).filter((chunk) => chunk.file.endsWith(".css")).map((chunk) => chunk.file);
2837
+ let chunkAssetPaths = Object.values(viteManifest).flatMap(
2838
+ (chunk) => chunk.assets ?? []
2839
+ );
2840
+ return /* @__PURE__ */ new Set([...cssUrlPaths, ...chunkAssetPaths]);
2841
+ };
2842
+ let generateSriManifest = async (ctx2) => {
2843
+ let clientBuildDirectory = getClientBuildDirectory(ctx2.reactRouterConfig);
2844
+ let entries = (0, import_node_fs2.readdirSync)(clientBuildDirectory, {
2845
+ withFileTypes: true,
2846
+ recursive: true
2847
+ });
2848
+ let sriManifest = {};
2849
+ for (const entry of entries) {
2850
+ if (entry.isFile() && entry.name.endsWith(".js")) {
2851
+ const entryNormalizedPath = "parentPath" in entry && typeof entry.parentPath === "string" ? entry.parentPath : entry.path;
2852
+ let contents;
2853
+ try {
2854
+ contents = await (0, import_promises2.readFile)(
2855
+ path6.join(entryNormalizedPath, entry.name),
2856
+ "utf-8"
2857
+ );
2858
+ } catch (e) {
2859
+ logger.error(`Failed to read file for SRI generation: ${entry.name}`);
2860
+ throw e;
2861
+ }
2862
+ let hash = (0, import_node_crypto.createHash)("sha384").update(contents).digest().toString("base64");
2863
+ let filepath = getVite().normalizePath(
2864
+ path6.relative(
2865
+ clientBuildDirectory,
2866
+ path6.join(entryNormalizedPath, entry.name)
2867
+ )
2868
+ );
2869
+ sriManifest[`${ctx2.publicPath}${filepath}`] = `sha384-${hash}`;
2870
+ }
2871
+ }
2872
+ return sriManifest;
2873
+ };
2874
+ let generateReactRouterManifestsForBuild = async ({
2875
+ viteConfig: viteConfig2,
2876
+ routeIds
2877
+ }) => {
2878
+ invariant(viteConfig2);
2879
+ let viteManifest = await loadViteManifest(
2880
+ getClientBuildDirectory(ctx.reactRouterConfig)
2881
+ );
2882
+ let entry = getReactRouterManifestBuildAssets(
2883
+ ctx,
2884
+ viteConfig2,
2885
+ viteManifest,
2886
+ ctx.entryClientFilePath,
2887
+ null
2888
+ );
2889
+ let browserRoutes = {};
2890
+ let serverRoutes = {};
2891
+ let routeManifestExports = await getRouteManifestModuleExports(
2892
+ viteChildCompiler,
2893
+ ctx
2894
+ );
2895
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
2896
+ for (let route of Object.values(ctx.reactRouterConfig.routes)) {
2897
+ let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
2898
+ let sourceExports = routeManifestExports[route.id];
2899
+ let hasClientAction = sourceExports.includes("clientAction");
2900
+ let hasClientLoader = sourceExports.includes("clientLoader");
2901
+ let hasClientMiddleware = sourceExports.includes("clientMiddleware");
2902
+ let hasHydrateFallback = sourceExports.includes("HydrateFallback");
2903
+ let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
2904
+ cache,
2905
+ ctx,
2906
+ routeFile,
2907
+ { routeFile, viteChildCompiler }
2908
+ );
2909
+ if (enforceSplitRouteModules) {
2910
+ validateRouteChunks({
2911
+ ctx,
2912
+ id: route.file,
2913
+ valid: {
2914
+ clientAction: !hasClientAction || hasRouteChunkByExportName.clientAction,
2915
+ clientLoader: !hasClientLoader || hasRouteChunkByExportName.clientLoader,
2916
+ clientMiddleware: !hasClientMiddleware || hasRouteChunkByExportName.clientMiddleware,
2917
+ HydrateFallback: !hasHydrateFallback || hasRouteChunkByExportName.HydrateFallback
2918
+ }
2919
+ });
2920
+ }
2921
+ let routeManifestEntry = {
2922
+ id: route.id,
2923
+ parentId: route.parentId,
2924
+ path: route.path,
2925
+ index: route.index,
2926
+ caseSensitive: route.caseSensitive,
2927
+ hasAction: sourceExports.includes("action"),
2928
+ hasLoader: sourceExports.includes("loader"),
2929
+ hasClientAction,
2930
+ hasClientLoader,
2931
+ hasClientMiddleware,
2932
+ hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
2933
+ ...getReactRouterManifestBuildAssets(
2934
+ ctx,
2935
+ viteConfig2,
2936
+ viteManifest,
2937
+ `${routeFile}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
2938
+ route
2939
+ ),
2940
+ clientActionModule: hasRouteChunkByExportName.clientAction ? getPublicModulePathForEntry(
2941
+ ctx,
2942
+ viteManifest,
2943
+ getRouteChunkModuleId(routeFile, "clientAction")
2944
+ ) : void 0,
2945
+ clientLoaderModule: hasRouteChunkByExportName.clientLoader ? getPublicModulePathForEntry(
2946
+ ctx,
2947
+ viteManifest,
2948
+ getRouteChunkModuleId(routeFile, "clientLoader")
2949
+ ) : void 0,
2950
+ clientMiddlewareModule: hasRouteChunkByExportName.clientMiddleware ? getPublicModulePathForEntry(
2951
+ ctx,
2952
+ viteManifest,
2953
+ getRouteChunkModuleId(routeFile, "clientMiddleware")
2954
+ ) : void 0,
2955
+ hydrateFallbackModule: hasRouteChunkByExportName.HydrateFallback ? getPublicModulePathForEntry(
2956
+ ctx,
2957
+ viteManifest,
2958
+ getRouteChunkModuleId(routeFile, "HydrateFallback")
2959
+ ) : void 0
2960
+ };
2961
+ browserRoutes[route.id] = routeManifestEntry;
2962
+ if (!routeIds || routeIds.includes(route.id)) {
2963
+ serverRoutes[route.id] = routeManifestEntry;
2964
+ }
2965
+ }
2966
+ let fingerprintedValues = { entry, routes: browserRoutes };
2967
+ let version = getHash(JSON.stringify(fingerprintedValues), 8);
2968
+ let manifestPath = path6.posix.join(
2969
+ viteConfig2.build.assetsDir,
2970
+ `manifest-${version}.js`
2971
+ );
2972
+ let url2 = `${ctx.publicPath}${manifestPath}`;
2973
+ let nonFingerprintedValues = { url: url2, version };
2974
+ let reactRouterBrowserManifest = {
2975
+ ...fingerprintedValues,
2976
+ ...nonFingerprintedValues,
2977
+ sri: void 0
2978
+ };
2979
+ await writeFileSafe(
2980
+ path6.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
2981
+ `window.__reactRouterManifest=${JSON.stringify(
2982
+ reactRouterBrowserManifest
2983
+ )};`
2984
+ );
2985
+ let sri = void 0;
2986
+ if (ctx.reactRouterConfig.future.unstable_subResourceIntegrity) {
2987
+ sri = await generateSriManifest(ctx);
2988
+ }
2989
+ let reactRouterServerManifest = {
2990
+ ...reactRouterBrowserManifest,
2991
+ routes: serverRoutes,
2992
+ sri
2993
+ };
2994
+ return {
2995
+ reactRouterBrowserManifest,
2996
+ reactRouterServerManifest
2997
+ };
2998
+ };
2999
+ let currentReactRouterManifestForDev = null;
3000
+ let getReactRouterManifestForDev = async () => {
3001
+ let routes = {};
3002
+ let routeManifestExports = await getRouteManifestModuleExports(
3003
+ viteChildCompiler,
3004
+ ctx
3005
+ );
3006
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
3007
+ for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
3008
+ let routeFile = route.file;
3009
+ let sourceExports = routeManifestExports[key];
3010
+ let hasClientAction = sourceExports.includes("clientAction");
3011
+ let hasClientLoader = sourceExports.includes("clientLoader");
3012
+ let hasClientMiddleware = sourceExports.includes("clientMiddleware");
3013
+ let hasHydrateFallback = sourceExports.includes("HydrateFallback");
3014
+ let routeModulePath = combineURLs(
3015
+ ctx.publicPath,
3016
+ `${resolveFileUrl(
3017
+ ctx,
3018
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
3019
+ )}`
3020
+ );
3021
+ if (enforceSplitRouteModules) {
3022
+ let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
3023
+ cache,
3024
+ ctx,
3025
+ routeFile,
3026
+ { routeFile, viteChildCompiler }
3027
+ );
3028
+ validateRouteChunks({
3029
+ ctx,
3030
+ id: route.file,
3031
+ valid: {
3032
+ clientAction: !hasClientAction || hasRouteChunkByExportName.clientAction,
3033
+ clientLoader: !hasClientLoader || hasRouteChunkByExportName.clientLoader,
3034
+ clientMiddleware: !hasClientMiddleware || hasRouteChunkByExportName.clientMiddleware,
3035
+ HydrateFallback: !hasHydrateFallback || hasRouteChunkByExportName.HydrateFallback
3036
+ }
3037
+ });
3038
+ }
3039
+ routes[key] = {
3040
+ id: route.id,
3041
+ parentId: route.parentId,
3042
+ path: route.path,
3043
+ index: route.index,
3044
+ caseSensitive: route.caseSensitive,
3045
+ module: routeModulePath,
3046
+ // Split route modules are a build-time optimization
3047
+ clientActionModule: void 0,
3048
+ clientLoaderModule: void 0,
3049
+ clientMiddlewareModule: void 0,
3050
+ hydrateFallbackModule: void 0,
3051
+ hasAction: sourceExports.includes("action"),
3052
+ hasLoader: sourceExports.includes("loader"),
3053
+ hasClientAction,
3054
+ hasClientLoader,
3055
+ hasClientMiddleware,
3056
+ hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
3057
+ imports: []
3058
+ };
3059
+ }
3060
+ let sri = void 0;
3061
+ let reactRouterManifestForDev = {
3062
+ version: String(Math.random()),
3063
+ url: combineURLs(ctx.publicPath, virtual.browserManifest.url),
3064
+ hmr: {
3065
+ runtime: combineURLs(ctx.publicPath, virtualInjectHmrRuntime.url)
3066
+ },
3067
+ entry: {
3068
+ module: combineURLs(
3069
+ ctx.publicPath,
3070
+ resolveFileUrl(ctx, ctx.entryClientFilePath)
3071
+ ),
3072
+ imports: []
3073
+ },
3074
+ sri,
3075
+ routes
3076
+ };
3077
+ currentReactRouterManifestForDev = reactRouterManifestForDev;
3078
+ return reactRouterManifestForDev;
3079
+ };
3080
+ const loadCssContents = async (viteDevServer, dep) => {
3081
+ invariant(
3082
+ viteCommand === "serve",
3083
+ "loadCssContents is only available in dev mode"
3084
+ );
3085
+ if (dep.file && isCssModulesFile(dep.file)) {
3086
+ return cssModulesManifest[dep.file];
3087
+ }
3088
+ let transformedCssCode = (await viteDevServer.transformRequest(dep.url))?.code;
3089
+ invariant(
3090
+ transformedCssCode,
3091
+ `Failed to load CSS for ${dep.file ?? dep.url}`
3092
+ );
3093
+ let cssString = getCssStringFromViteDevModuleCode(transformedCssCode);
3094
+ invariant(
3095
+ typeof cssString === "string",
3096
+ `Failed to extract CSS for ${dep.file ?? dep.url}`
3097
+ );
3098
+ return cssString;
3099
+ };
3100
+ return [
3101
+ {
3102
+ name: "react-router",
3103
+ config: async (_viteUserConfig, _viteConfigEnv) => {
3104
+ await preloadVite();
3105
+ let vite2 = getVite();
3106
+ viteUserConfig = _viteUserConfig;
3107
+ viteConfigEnv = _viteConfigEnv;
3108
+ viteCommand = viteConfigEnv.command;
3109
+ let viteClientConditions = [
3110
+ ...vite2.defaultClientConditions ?? []
3111
+ ];
3112
+ logger = vite2.createLogger(viteUserConfig.logLevel, {
3113
+ prefix: "[react-router]"
3114
+ });
3115
+ rootDirectory = viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
3116
+ let mode = viteConfigEnv.mode;
3117
+ if (viteCommand === "serve") {
3118
+ typegenWatcherPromise = watch(rootDirectory, {
3119
+ mode,
3120
+ // ignore `info` logs from typegen since they are redundant when Vite plugin logs are active
3121
+ logger: vite2.createLogger("warn", { prefix: "[react-router]" })
3122
+ });
3123
+ }
3124
+ reactRouterConfigLoader = await createConfigLoader({
3125
+ rootDirectory,
3126
+ mode,
3127
+ watch: viteCommand === "serve"
3128
+ });
3129
+ await updatePluginContext();
3130
+ Object.assign(
3131
+ process.env,
3132
+ vite2.loadEnv(
3133
+ viteConfigEnv.mode,
3134
+ viteUserConfig.envDir ?? ctx.rootDirectory,
3135
+ // We override the default prefix of "VITE_" with a blank string since
3136
+ // we're targeting the server, so we want to load all environment
3137
+ // variables, not just those explicitly marked for the client
3138
+ ""
3139
+ )
3140
+ );
3141
+ let environments = await getEnvironmentsOptions(ctx, viteCommand, {
3142
+ viteUserConfig
3143
+ });
3144
+ let serverEnvironment = getServerEnvironmentValues(
3145
+ ctx,
3146
+ environments
3147
+ )[0];
3148
+ invariant(serverEnvironment);
3149
+ let clientEnvironment = environments.client;
3150
+ invariant(clientEnvironment);
3151
+ return {
3152
+ __reactRouterPluginContext: ctx,
3153
+ appType: viteCommand === "serve" && viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr === false ? "spa" : "custom",
3154
+ ssr: {
3155
+ external: serverEnvironment.resolve?.external,
3156
+ resolve: serverEnvironment.resolve
3157
+ },
3158
+ optimizeDeps: {
3159
+ entries: getOptimizeDepsEntries({
3160
+ entryClientFilePath: ctx.entryClientFilePath,
3161
+ reactRouterConfig: ctx.reactRouterConfig
3162
+ }),
3163
+ include: [
3164
+ // Pre-bundle React dependencies to avoid React duplicates,
3165
+ // even if React dependencies are not direct dependencies.
3166
+ // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
3167
+ "react",
3168
+ "react/jsx-runtime",
3169
+ "react/jsx-dev-runtime",
3170
+ "react-dom",
3171
+ "react-dom/client",
3172
+ // Pre-bundle router dependencies to avoid router duplicates.
3173
+ // Mismatching routers cause `Error: You must render this element inside a <Remix> element`.
3174
+ "react-router",
3175
+ "react-router/dom",
3176
+ // Check to avoid "Failed to resolve dependency: react-router-dom, present in 'optimizeDeps.include'"
3177
+ ...hasDependency({
3178
+ name: "react-router-dom",
3179
+ rootDirectory: ctx.rootDirectory
3180
+ }) ? ["react-router-dom"] : []
3181
+ ]
3182
+ },
3183
+ esbuild: {
3184
+ jsx: "automatic",
3185
+ jsxDev: viteCommand !== "build"
3186
+ },
3187
+ resolve: {
3188
+ dedupe: [
3189
+ // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
3190
+ "react",
3191
+ "react-dom",
3192
+ // see description for `optimizeDeps.include`
3193
+ "react-router",
3194
+ "react-router/dom",
3195
+ "react-router-dom"
3196
+ ],
3197
+ conditions: viteCommand === "build" ? viteClientConditions : ["development", ...viteClientConditions]
3198
+ },
3199
+ base: viteUserConfig.base,
3200
+ // When consumer provides an allowlist for files that can be read by
3201
+ // the server, ensure that the default entry files are included.
3202
+ // If we don't do this and a default entry file is used, the server
3203
+ // will throw an error that the file is not allowed to be read.
3204
+ // https://vitejs.dev/config/server-options#server-fs-allow
3205
+ server: viteUserConfig.server?.fs?.allow ? { fs: { allow: defaultEntries } } : void 0,
3206
+ ...ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? {
3207
+ environments,
3208
+ build: {
3209
+ // This isn't honored by the SSR environment config (which seems
3210
+ // to be a Vite bug?) so we set it here too.
3211
+ ssrEmitAssets: true
3212
+ },
3213
+ builder: {
3214
+ sharedConfigBuild: true,
3215
+ sharedPlugins: true,
3216
+ async buildApp(builder) {
3217
+ invariant(viteConfig);
3218
+ viteConfig.logger.info(
3219
+ "Using Vite Environment API (experimental)"
3220
+ );
3221
+ let { reactRouterConfig } = ctx;
3222
+ await cleanBuildDirectory(viteConfig, ctx);
3223
+ await builder.build(builder.environments.client);
3224
+ let serverEnvironments = getServerEnvironmentValues(
3225
+ ctx,
3226
+ builder.environments
3227
+ );
3228
+ await Promise.all(serverEnvironments.map(builder.build));
3229
+ await cleanViteManifests(environments, ctx);
3230
+ let { buildManifest } = ctx;
3231
+ invariant(buildManifest, "Expected build manifest");
3232
+ await reactRouterConfig.buildEnd?.({
3233
+ buildManifest,
3234
+ reactRouterConfig,
3235
+ viteConfig
3236
+ });
3237
+ }
3238
+ }
3239
+ } : {
3240
+ build: ctx.environmentBuildContext?.options.build ?? (viteConfigEnv.isSsrBuild ? serverEnvironment.build : clientEnvironment.build)
3241
+ }
3242
+ };
3243
+ },
3244
+ configEnvironment(name, options) {
3245
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && (ctx.buildManifest?.serverBundles ? isSsrBundleEnvironmentName(name) : name === "ssr")) {
3246
+ const vite2 = getVite();
3247
+ return {
3248
+ resolve: {
3249
+ external: (
3250
+ // This check is required to honor the "noExternal: true" config
3251
+ // provided by vite-plugin-cloudflare within this repo. When compiling
3252
+ // for Cloudflare, all server dependencies are pre-bundled, but our
3253
+ // `ssrExternals` config inadvertently overrides this. This doesn't
3254
+ // impact consumers because for them `ssrExternals` is undefined and
3255
+ // Cloudflare's "noExternal: true" config remains intact.
3256
+ options.resolve?.noExternal === true ? void 0 : ssrExternals
3257
+ )
3258
+ },
3259
+ optimizeDeps: options.optimizeDeps?.noDiscovery === false ? {
3260
+ entries: [
3261
+ vite2.normalizePath(ctx.entryServerFilePath),
3262
+ ...Object.values(ctx.reactRouterConfig.routes).map(
3263
+ (route) => resolveRelativeRouteFilePath(
3264
+ route,
3265
+ ctx.reactRouterConfig
3266
+ )
3267
+ )
3268
+ ],
3269
+ include: [
3270
+ "react",
3271
+ "react/jsx-dev-runtime",
3272
+ "react-dom/server",
3273
+ "react-router"
3274
+ ]
3275
+ } : void 0
3276
+ };
3277
+ }
3278
+ },
3279
+ async configResolved(resolvedViteConfig) {
3280
+ await import_es_module_lexer.init;
3281
+ viteConfig = resolvedViteConfig;
3282
+ invariant(viteConfig);
3283
+ if (!viteConfig.configFile) {
3284
+ throw new Error(
3285
+ "The React Router Vite plugin requires the use of a Vite config file"
3286
+ );
3287
+ }
3288
+ let vite2 = getVite();
3289
+ let childCompilerConfigFile = await vite2.loadConfigFromFile(
3290
+ {
3291
+ command: viteConfig.command,
3292
+ mode: viteConfig.mode
3293
+ },
3294
+ viteConfig.configFile
3295
+ );
3296
+ invariant(
3297
+ childCompilerConfigFile,
3298
+ "Vite config file was unable to be resolved for React Router child compiler"
3299
+ );
3300
+ const childCompilerPlugins = await asyncFlatten(
3301
+ childCompilerConfigFile.config.plugins ?? []
3302
+ );
3303
+ viteChildCompiler = await vite2.createServer({
3304
+ ...viteUserConfig,
3305
+ // Ensure child compiler cannot overwrite the default cache directory
3306
+ cacheDir: "node_modules/.vite-child-compiler",
3307
+ mode: viteConfig.mode,
3308
+ server: {
3309
+ watch: viteConfig.command === "build" ? null : viteConfig.server.watch,
3310
+ preTransformRequests: false,
3311
+ hmr: false
3312
+ },
3313
+ configFile: false,
3314
+ envFile: false,
3315
+ plugins: [
3316
+ childCompilerPlugins.filter(
3317
+ (plugin) => typeof plugin === "object" && plugin !== null && "name" in plugin && plugin.name !== "react-router" && plugin.name !== "react-router:route-exports" && plugin.name !== "react-router:hmr-updates" && plugin.name !== "react-router:validate-plugin-order"
3318
+ ).map((plugin) => ({
3319
+ ...plugin,
3320
+ configureServer: void 0,
3321
+ configurePreviewServer: void 0
3322
+ }))
3323
+ ]
3324
+ });
3325
+ await viteChildCompiler.pluginContainer.buildStart({});
3326
+ },
3327
+ async transform(code, id) {
3328
+ if (isCssModulesFile(id)) {
3329
+ cssModulesManifest[id] = code;
3330
+ }
3331
+ },
3332
+ buildStart() {
3333
+ invariant(viteConfig);
3334
+ if (viteCommand === "build" && viteConfig.mode === "production" && !viteConfig.build.ssr && viteConfig.build.sourcemap) {
3335
+ viteConfig.logger.warn(
3336
+ import_picocolors3.default.yellow(
3337
+ "\n" + import_picocolors3.default.bold(" \u26A0\uFE0F Source maps are enabled in production\n") + [
3338
+ "This makes your server code publicly",
3339
+ "visible in the browser. This is highly",
3340
+ "discouraged! If you insist, ensure that",
3341
+ "you are using environment variables for",
3342
+ "secrets and not hard-coding them in",
3343
+ "your source code."
3344
+ ].map((line) => " " + line).join("\n") + "\n"
3345
+ )
3346
+ );
3347
+ }
3348
+ },
3349
+ async configureServer(viteDevServer) {
3350
+ (0, import_react_router2.unstable_setDevServerHooks)({
3351
+ // Give the request handler access to the critical CSS in dev to avoid a
3352
+ // flash of unstyled content since Vite injects CSS file contents via JS
3353
+ getCriticalCss: async (pathname) => {
3354
+ return getStylesForPathname({
3355
+ rootDirectory: ctx.rootDirectory,
3356
+ entryClientFilePath: ctx.entryClientFilePath,
3357
+ reactRouterConfig: ctx.reactRouterConfig,
3358
+ viteDevServer,
3359
+ loadCssContents,
3360
+ pathname
3361
+ });
3362
+ },
3363
+ // If an error is caught within the request handler, let Vite fix the
3364
+ // stack trace so it maps back to the actual source code
3365
+ processRequestError: (error) => {
3366
+ if (error instanceof Error) {
3367
+ viteDevServer.ssrFixStacktrace(error);
3368
+ }
3369
+ }
3370
+ });
3371
+ reactRouterConfigLoader.onChange(
3372
+ async ({
3373
+ result,
3374
+ configCodeChanged,
3375
+ routeConfigCodeChanged,
3376
+ configChanged,
3377
+ routeConfigChanged
3378
+ }) => {
3379
+ if (!result.ok) {
3380
+ invalidateVirtualModules(viteDevServer);
3381
+ logger.error(result.error, {
3382
+ clear: true,
3383
+ timestamp: true
3384
+ });
3385
+ return;
3386
+ }
3387
+ let message = configChanged ? "Config changed." : routeConfigChanged ? "Route config changed." : configCodeChanged ? "Config saved." : routeConfigCodeChanged ? " Route config saved." : "Config saved";
3388
+ logger.info(import_picocolors3.default.green(message), {
3389
+ clear: true,
3390
+ timestamp: true
3391
+ });
3392
+ await updatePluginContext();
3393
+ if (configChanged || routeConfigChanged) {
3394
+ invalidateVirtualModules(viteDevServer);
3395
+ }
3396
+ }
3397
+ );
3398
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi) {
3399
+ viteDevServer.middlewares.use(async (req, res, next) => {
3400
+ let [reqPathname, reqSearch] = (req.url ?? "").split("?");
3401
+ if (reqPathname.endsWith("/@react-router/critical.css")) {
3402
+ let pathname = new URLSearchParams(reqSearch).get("pathname");
3403
+ if (!pathname) {
3404
+ return next("No pathname provided");
3405
+ }
3406
+ let css = await getStylesForPathname({
3407
+ rootDirectory: ctx.rootDirectory,
3408
+ entryClientFilePath: ctx.entryClientFilePath,
3409
+ reactRouterConfig: ctx.reactRouterConfig,
3410
+ viteDevServer,
3411
+ loadCssContents,
3412
+ pathname
3413
+ });
3414
+ res.setHeader("Content-Type", "text/css");
3415
+ res.end(css);
3416
+ } else {
3417
+ next();
3418
+ }
3419
+ });
3420
+ }
3421
+ return () => {
3422
+ if (!viteDevServer.config.server.middlewareMode) {
3423
+ viteDevServer.middlewares.use(async (req, res, next) => {
3424
+ try {
3425
+ let build;
3426
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi) {
3427
+ let vite2 = getVite();
3428
+ let ssrEnvironment = viteDevServer.environments.ssr;
3429
+ if (!vite2.isRunnableDevEnvironment(ssrEnvironment)) {
3430
+ next();
3431
+ return;
3432
+ }
3433
+ build = await ssrEnvironment.runner.import(
3434
+ virtual.serverBuild.id
3435
+ );
3436
+ } else {
3437
+ build = await viteDevServer.ssrLoadModule(
3438
+ virtual.serverBuild.id
3439
+ );
3440
+ }
3441
+ let handler = (0, import_react_router2.createRequestHandler)(build, "development");
3442
+ let nodeHandler = async (nodeReq, nodeRes) => {
3443
+ let req2 = fromNodeRequest(nodeReq, nodeRes);
3444
+ let res2 = await handler(
3445
+ req2,
3446
+ await reactRouterDevLoadContext(req2)
3447
+ );
3448
+ await toNodeRequest(res2, nodeRes);
3449
+ };
3450
+ await nodeHandler(req, res);
3451
+ } catch (error) {
3452
+ next(error);
3453
+ }
3454
+ });
3455
+ }
3456
+ };
3457
+ },
3458
+ writeBundle: {
3459
+ // After the SSR build is finished, we inspect the Vite manifest for
3460
+ // the SSR build and move server-only assets to client assets directory
3461
+ async handler() {
3462
+ let { future } = ctx.reactRouterConfig;
3463
+ if (future.unstable_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
3464
+ return;
3465
+ }
3466
+ invariant(viteConfig);
3467
+ let clientBuildDirectory = getClientBuildDirectory(
3468
+ ctx.reactRouterConfig
3469
+ );
3470
+ let serverBuildDirectory = future.unstable_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx.reactRouterConfig);
3471
+ let ssrViteManifest = await loadViteManifest(serverBuildDirectory);
3472
+ let ssrAssetPaths = getViteManifestAssetPaths(ssrViteManifest);
3473
+ let userSsrEmitAssets = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.ssrEmitAssets ?? viteUserConfig.environments?.ssr?.build?.emitAssets : null) ?? viteUserConfig.build?.ssrEmitAssets ?? false;
3474
+ let movedAssetPaths = [];
3475
+ let removedAssetPaths = [];
3476
+ let copiedAssetPaths = [];
3477
+ for (let ssrAssetPath of ssrAssetPaths) {
3478
+ let src = path6.join(serverBuildDirectory, ssrAssetPath);
3479
+ let dest = path6.join(clientBuildDirectory, ssrAssetPath);
3480
+ if (!userSsrEmitAssets) {
3481
+ if (!(0, import_node_fs2.existsSync)(dest)) {
3482
+ await (0, import_promises2.mkdir)(path6.dirname(dest), { recursive: true });
3483
+ await (0, import_promises2.rename)(src, dest);
3484
+ movedAssetPaths.push(dest);
3485
+ } else {
3486
+ await (0, import_promises2.rm)(src, { force: true, recursive: true });
3487
+ removedAssetPaths.push(dest);
3488
+ }
3489
+ } else if (!(0, import_node_fs2.existsSync)(dest)) {
3490
+ await (0, import_promises2.cp)(src, dest, { recursive: true });
3491
+ copiedAssetPaths.push(dest);
3492
+ }
3493
+ }
3494
+ if (!userSsrEmitAssets) {
3495
+ let ssrCssPaths = Object.values(ssrViteManifest).flatMap(
3496
+ (chunk) => chunk.css ?? []
3497
+ );
3498
+ await Promise.all(
3499
+ ssrCssPaths.map(async (cssPath) => {
3500
+ let src = path6.join(serverBuildDirectory, cssPath);
3501
+ await (0, import_promises2.rm)(src, { force: true, recursive: true });
3502
+ removedAssetPaths.push(src);
3503
+ })
3504
+ );
3505
+ }
3506
+ let cleanedAssetPaths = [...removedAssetPaths, ...movedAssetPaths];
3507
+ let handledAssetPaths = [...cleanedAssetPaths, ...copiedAssetPaths];
3508
+ let cleanedAssetDirs = new Set(cleanedAssetPaths.map(path6.dirname));
3509
+ await Promise.all(
3510
+ Array.from(cleanedAssetDirs).map(async (dir) => {
3511
+ try {
3512
+ const files = await (0, import_promises2.readdir)(dir, { recursive: true });
3513
+ if (files.length === 0) {
3514
+ await (0, import_promises2.rm)(dir, { force: true, recursive: true });
3515
+ }
3516
+ } catch {
3517
+ }
3518
+ })
3519
+ );
3520
+ if (handledAssetPaths.length) {
3521
+ viteConfig.logger.info("");
3522
+ }
3523
+ function logHandledAssets(paths, message) {
3524
+ invariant(viteConfig);
3525
+ if (paths.length) {
3526
+ viteConfig.logger.info(
3527
+ [
3528
+ `${import_picocolors3.default.green("\u2713")} ${message}`,
3529
+ ...paths.map(
3530
+ (assetPath) => import_picocolors3.default.dim(path6.relative(ctx.rootDirectory, assetPath))
3531
+ )
3532
+ ].join("\n")
3533
+ );
3534
+ }
3535
+ }
3536
+ logHandledAssets(
3537
+ removedAssetPaths,
3538
+ `${removedAssetPaths.length} asset${removedAssetPaths.length > 1 ? "s" : ""} cleaned from React Router server build.`
3539
+ );
3540
+ logHandledAssets(
3541
+ movedAssetPaths,
3542
+ `${movedAssetPaths.length} asset${movedAssetPaths.length > 1 ? "s" : ""} moved from React Router server build to client assets.`
3543
+ );
3544
+ logHandledAssets(
3545
+ copiedAssetPaths,
3546
+ `${copiedAssetPaths.length} asset${copiedAssetPaths.length > 1 ? "s" : ""} copied from React Router server build to client assets.`
3547
+ );
3548
+ if (handledAssetPaths.length) {
3549
+ viteConfig.logger.info("");
3550
+ }
3551
+ process.env.IS_RR_BUILD_REQUEST = "yes";
3552
+ if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
3553
+ await handlePrerender(
3554
+ viteConfig,
3555
+ ctx.reactRouterConfig,
3556
+ serverBuildDirectory,
3557
+ getServerBuildFile(ssrViteManifest),
3558
+ clientBuildDirectory
3559
+ );
3560
+ }
3561
+ if (!ctx.reactRouterConfig.ssr) {
3562
+ await handleSpaMode(
3563
+ viteConfig,
3564
+ ctx.reactRouterConfig,
3565
+ serverBuildDirectory,
3566
+ getServerBuildFile(ssrViteManifest),
3567
+ clientBuildDirectory
3568
+ );
3569
+ }
3570
+ if (!ctx.reactRouterConfig.ssr) {
3571
+ viteConfig.logger.info(
3572
+ [
3573
+ "Removing the server build in",
3574
+ import_picocolors3.default.green(serverBuildDirectory),
3575
+ "due to ssr:false"
3576
+ ].join(" ")
3577
+ );
3578
+ (0, import_node_fs2.rmSync)(serverBuildDirectory, { force: true, recursive: true });
3579
+ }
3580
+ }
3581
+ },
3582
+ async buildEnd() {
3583
+ await viteChildCompiler?.close();
3584
+ await reactRouterConfigLoader.close();
3585
+ let typegenWatcher = await typegenWatcherPromise;
3586
+ await typegenWatcher?.close();
3587
+ }
3588
+ },
3589
+ {
3590
+ name: "react-router:route-chunks-index",
3591
+ // This plugin provides the route module "index" since route modules can
3592
+ // be chunked and may be made up of multiple smaller modules. This plugin
3593
+ // primarily ensures code is never duplicated across a route module and
3594
+ // its chunks. If we didn't have this plugin, any app that explicitly
3595
+ // imports a route module would result in duplicate code since the app
3596
+ // would contain code for both the unprocessed route module and its
3597
+ // individual chunks. This is because, since they have different module
3598
+ // IDs, they are treated as completely separate modules even though they
3599
+ // all reference the same underlying file. This plugin addresses this by
3600
+ // ensuring that any explicit imports of a route module resolve to a
3601
+ // module that simply re-exports from its underlying chunks, if present.
3602
+ async transform(code, id, options) {
3603
+ if (viteCommand !== "build") return;
3604
+ if (options?.ssr) {
3605
+ return;
3606
+ }
3607
+ if (!isRoute(ctx.reactRouterConfig, id)) {
3608
+ return;
3609
+ }
3610
+ if (isRouteVirtualModule(id)) {
3611
+ return;
3612
+ }
3613
+ let { hasRouteChunks, chunkedExports } = await detectRouteChunksIfEnabled(cache, ctx, id, code);
3614
+ if (!hasRouteChunks) {
3615
+ return;
3616
+ }
3617
+ let sourceExports = await getRouteModuleExports(
3618
+ viteChildCompiler,
3619
+ ctx,
3620
+ id
3621
+ );
3622
+ let isMainChunkExport = (name) => !chunkedExports.includes(name);
3623
+ let mainChunkReexports = sourceExports.filter(isMainChunkExport).join(", ");
3624
+ let chunkBasePath = `./${path6.basename(id)}`;
3625
+ return [
3626
+ `export { ${mainChunkReexports} } from "${getRouteChunkModuleId(
3627
+ chunkBasePath,
3628
+ "main"
3629
+ )}";`,
3630
+ ...chunkedExports.map(
3631
+ (exportName) => `export { ${exportName} } from "${getRouteChunkModuleId(
3632
+ chunkBasePath,
3633
+ exportName
3634
+ )}";`
3635
+ )
3636
+ ].filter(Boolean).join("\n");
3637
+ }
3638
+ },
3639
+ {
3640
+ name: "react-router:build-client-route",
3641
+ async transform(code, id, options) {
3642
+ if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
3643
+ let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
3644
+ let routeFileName = path6.basename(routeModuleId);
3645
+ let sourceExports = await getRouteModuleExports(
3646
+ viteChildCompiler,
3647
+ ctx,
3648
+ routeModuleId
3649
+ );
3650
+ let { chunkedExports = [] } = options?.ssr ? {} : await detectRouteChunksIfEnabled(cache, ctx, id, code);
3651
+ let reexports = sourceExports.filter((exportName) => {
3652
+ let isRouteEntryExport = options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName);
3653
+ let isChunkedExport = chunkedExports.includes(
3654
+ exportName
3655
+ );
3656
+ return isRouteEntryExport && !isChunkedExport;
3657
+ }).join(", ");
3658
+ return `export { ${reexports} } from "./${routeFileName}";`;
3659
+ }
3660
+ },
3661
+ {
3662
+ name: "react-router:split-route-modules",
3663
+ async transform(code, id, options) {
3664
+ if (options?.ssr) return;
3665
+ if (!isRouteChunkModuleId(id)) return;
3666
+ invariant(
3667
+ viteCommand === "build",
3668
+ "Route modules are only split in build mode"
3669
+ );
3670
+ let chunkName = getRouteChunkNameFromModuleId(id);
3671
+ if (!chunkName) {
3672
+ throw new Error(`Invalid route chunk name "${chunkName}" in "${id}"`);
3673
+ }
3674
+ let chunk = await getRouteChunkIfEnabled(
3675
+ cache,
3676
+ ctx,
3677
+ id,
3678
+ chunkName,
3679
+ code
3680
+ );
3681
+ let preventEmptyChunkSnippet = ({ reason }) => `Math.random()<0&&console.log(${JSON.stringify(reason)});`;
3682
+ if (chunk === null) {
3683
+ return preventEmptyChunkSnippet({
3684
+ reason: "Split round modules disabled"
3685
+ });
3686
+ }
3687
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
3688
+ if (enforceSplitRouteModules && chunkName === "main" && chunk) {
3689
+ let exportNames = getExportNames(chunk.code);
3690
+ validateRouteChunks({
3691
+ ctx,
3692
+ id,
3693
+ valid: {
3694
+ clientAction: !exportNames.includes("clientAction"),
3695
+ clientLoader: !exportNames.includes("clientLoader"),
3696
+ clientMiddleware: !exportNames.includes("clientMiddleware"),
3697
+ HydrateFallback: !exportNames.includes("HydrateFallback")
3698
+ }
3699
+ });
3700
+ }
3701
+ return chunk ?? preventEmptyChunkSnippet({ reason: `No ${chunkName} chunk` });
3702
+ }
3703
+ },
3704
+ {
3705
+ name: "react-router:virtual-modules",
3706
+ enforce: "pre",
3707
+ resolveId(id) {
3708
+ const vmod = Object.values(virtual).find((vmod2) => vmod2.id === id);
3709
+ if (vmod) return vmod.resolvedId;
3710
+ },
3711
+ async load(id) {
3712
+ switch (id) {
3713
+ case virtual.serverBuild.resolvedId: {
3714
+ let routeIds = getServerBundleRouteIds(this, ctx);
3715
+ return await getServerEntry({ routeIds });
3716
+ }
3717
+ case virtual.serverManifest.resolvedId: {
3718
+ let routeIds = getServerBundleRouteIds(this, ctx);
3719
+ invariant(viteConfig);
3720
+ let reactRouterManifest = viteCommand === "build" ? (await generateReactRouterManifestsForBuild({
3721
+ viteConfig,
3722
+ routeIds
3723
+ })).reactRouterServerManifest : await getReactRouterManifestForDev();
3724
+ if (!ctx.reactRouterConfig.ssr) {
3725
+ invariant(viteConfig);
3726
+ validateSsrFalsePrerenderExports(
3727
+ viteConfig,
3728
+ ctx,
3729
+ reactRouterManifest,
3730
+ viteChildCompiler
3731
+ );
3732
+ }
3733
+ return `export default ${(0, import_jsesc.default)(reactRouterManifest, {
3734
+ es6: true
3735
+ })};`;
3736
+ }
3737
+ case virtual.browserManifest.resolvedId: {
3738
+ if (viteCommand === "build") {
3739
+ throw new Error("This module only exists in development");
3740
+ }
3741
+ let reactRouterManifest = await getReactRouterManifestForDev();
3742
+ let reactRouterManifestString = (0, import_jsesc.default)(reactRouterManifest, {
3743
+ es6: true
3744
+ });
3745
+ return `window.__reactRouterManifest=${reactRouterManifestString};`;
3746
+ }
3747
+ }
3748
+ }
3749
+ },
3750
+ {
3751
+ name: "react-router:dot-server",
3752
+ enforce: "pre",
3753
+ async resolveId(id, importer, options) {
3754
+ let isOptimizeDeps = viteCommand === "serve" && options?.scan === true;
3755
+ if (isOptimizeDeps || options?.ssr) return;
3756
+ let isResolving = options?.custom?.["react-router:dot-server"] ?? false;
3757
+ if (isResolving) return;
3758
+ options.custom = { ...options.custom, "react-router:dot-server": true };
3759
+ let resolved = await this.resolve(id, importer, options);
3760
+ if (!resolved) return;
3761
+ let serverFileRE = /\.server(\.[cm]?[jt]sx?)?$/;
3762
+ let serverDirRE = /\/\.server\//;
3763
+ let isDotServer = serverFileRE.test(resolved.id) || serverDirRE.test(resolved.id);
3764
+ if (!isDotServer) return;
3765
+ if (!importer) return;
3766
+ if (viteCommand !== "build" && importer.endsWith(".html")) {
3767
+ return;
3768
+ }
3769
+ let vite2 = getVite();
3770
+ let importerShort = vite2.normalizePath(
3771
+ path6.relative(ctx.rootDirectory, importer)
3772
+ );
3773
+ if (isRoute(ctx.reactRouterConfig, importer)) {
3774
+ let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
3775
+ (xport) => `\`${xport}\``
3776
+ ).join(", ");
3777
+ throw Error(
3778
+ [
3779
+ import_picocolors3.default.red(`Server-only module referenced by client`),
3780
+ "",
3781
+ ` '${id}' imported by route '${importerShort}'`,
3782
+ "",
3783
+ ` React Router automatically removes server-code from these exports:`,
3784
+ ` ${serverOnlyExports}`,
3785
+ "",
3786
+ ` But other route exports in '${importerShort}' depend on '${id}'.`,
3787
+ "",
3788
+ " See https://remix.run/docs/en/main/guides/vite#splitting-up-client-and-server-code",
3789
+ ""
3790
+ ].join("\n")
3791
+ );
3792
+ }
3793
+ throw Error(
3794
+ [
3795
+ import_picocolors3.default.red(`Server-only module referenced by client`),
3796
+ "",
3797
+ ` '${id}' imported by '${importerShort}'`,
3798
+ "",
3799
+ " See https://remix.run/docs/en/main/guides/vite#splitting-up-client-and-server-code",
3800
+ ""
3801
+ ].join("\n")
3802
+ );
3803
+ }
3804
+ },
3805
+ {
3806
+ name: "react-router:dot-client",
3807
+ async transform(code, id, options) {
3808
+ if (!options?.ssr) return;
3809
+ let clientFileRE = /\.client(\.[cm]?[jt]sx?)?$/;
3810
+ let clientDirRE = /\/\.client\//;
3811
+ if (clientFileRE.test(id) || clientDirRE.test(id)) {
3812
+ let exports2 = getExportNames(code);
3813
+ return {
3814
+ code: exports2.map(
3815
+ (name) => name === "default" ? "export default undefined;" : `export const ${name} = undefined;`
3816
+ ).join("\n"),
3817
+ map: null
3818
+ };
3819
+ }
3820
+ }
3821
+ },
3822
+ {
3823
+ name: "react-router:route-exports",
3824
+ async transform(code, id, options) {
3825
+ if (isRouteChunkModuleId(id)) {
3826
+ id = id.split("?")[0];
3827
+ }
3828
+ let route = getRoute(ctx.reactRouterConfig, id);
3829
+ if (!route) return;
3830
+ if (!options?.ssr && isSpaModeEnabled(ctx.reactRouterConfig)) {
3831
+ let exportNames = getExportNames(code);
3832
+ let serverOnlyExports = exportNames.filter((exp) => {
3833
+ if (route.id === "root" && exp === "loader") {
3834
+ return false;
3835
+ }
3836
+ return SERVER_ONLY_ROUTE_EXPORTS.includes(exp);
3837
+ });
3838
+ if (serverOnlyExports.length > 0) {
3839
+ let str = serverOnlyExports.map((e) => `\`${e}\``).join(", ");
3840
+ let message = `SPA Mode: ${serverOnlyExports.length} invalid route export(s) in \`${route.file}\`: ${str}. See https://reactrouter.com/how-to/spa for more information.`;
3841
+ throw Error(message);
3842
+ }
3843
+ if (route.id !== "root") {
3844
+ let hasHydrateFallback = exportNames.some(
3845
+ (exp) => exp === "HydrateFallback"
3846
+ );
3847
+ if (hasHydrateFallback) {
3848
+ let message = `SPA Mode: Invalid \`HydrateFallback\` export found in \`${route.file}\`. \`HydrateFallback\` is only permitted on the root route in SPA Mode. See https://reactrouter.com/how-to/spa for more information.`;
3849
+ throw Error(message);
3850
+ }
3851
+ }
3852
+ }
3853
+ let [filepath] = id.split("?");
3854
+ let ast = (0, import_parser.parse)(code, { sourceType: "module" });
3855
+ if (!options?.ssr) {
3856
+ removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
3857
+ }
3858
+ decorateComponentExportsWithProps(ast);
3859
+ return generate(ast, {
3860
+ sourceMaps: true,
3861
+ filename: id,
3862
+ sourceFileName: filepath
3863
+ });
3864
+ }
3865
+ },
3866
+ {
3867
+ name: "react-router:inject-hmr-runtime",
3868
+ enforce: "pre",
3869
+ resolveId(id) {
3870
+ if (id === virtualInjectHmrRuntime.id) {
3871
+ return virtualInjectHmrRuntime.resolvedId;
3872
+ }
3873
+ },
3874
+ async load(id) {
3875
+ if (id !== virtualInjectHmrRuntime.resolvedId) return;
3876
+ return [
3877
+ `import RefreshRuntime from "${virtualHmrRuntime.id}"`,
3878
+ "RefreshRuntime.injectIntoGlobalHook(window)",
3879
+ "window.$RefreshReg$ = () => {}",
3880
+ "window.$RefreshSig$ = () => (type) => type",
3881
+ "window.__vite_plugin_react_preamble_installed__ = true"
3882
+ ].join("\n");
3883
+ }
3884
+ },
3885
+ {
3886
+ name: "react-router:hmr-runtime",
3887
+ enforce: "pre",
3888
+ resolveId(id) {
3889
+ if (id === virtualHmrRuntime.id) return virtualHmrRuntime.resolvedId;
3890
+ },
3891
+ async load(id) {
3892
+ if (id !== virtualHmrRuntime.resolvedId) return;
3893
+ let reactRefreshDir = path6.dirname(
3894
+ require.resolve("react-refresh/package.json")
3895
+ );
3896
+ let reactRefreshRuntimePath = path6.join(
3897
+ reactRefreshDir,
3898
+ "cjs/react-refresh-runtime.development.js"
3899
+ );
3900
+ return [
3901
+ "const exports = {}",
3902
+ await (0, import_promises2.readFile)(reactRefreshRuntimePath, "utf8"),
3903
+ await (0, import_promises2.readFile)(require.resolve("./static/refresh-utils.mjs"), "utf8"),
3904
+ "export default exports"
3905
+ ].join("\n");
3906
+ }
3907
+ },
3908
+ {
3909
+ name: "react-router:react-refresh-babel",
3910
+ async transform(code, id, options) {
3911
+ if (viteCommand !== "serve") return;
3912
+ if (id.includes("/node_modules/")) return;
3913
+ let [filepath] = id.split("?");
3914
+ let extensionsRE = /\.(jsx?|tsx?|mdx?)$/;
3915
+ if (!extensionsRE.test(filepath)) return;
3916
+ let devRuntime = "react/jsx-dev-runtime";
3917
+ let ssr = options?.ssr === true;
3918
+ let isJSX = filepath.endsWith("x");
3919
+ let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
3920
+ if (!useFastRefresh) return;
3921
+ if (isRouteVirtualModule(id)) {
3922
+ return { code: addRefreshWrapper(ctx.reactRouterConfig, code, id) };
3923
+ }
3924
+ let result = await babel.transformAsync(code, {
3925
+ babelrc: false,
3926
+ configFile: false,
3927
+ filename: id,
3928
+ sourceFileName: filepath,
3929
+ parserOpts: {
3930
+ sourceType: "module",
3931
+ allowAwaitOutsideFunction: true
3932
+ },
3933
+ plugins: [[require("react-refresh/babel"), { skipEnvCheck: true }]],
3934
+ sourceMaps: true
3935
+ });
3936
+ if (result === null) return;
3937
+ code = result.code;
3938
+ let refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
3939
+ if (refreshContentRE.test(code)) {
3940
+ code = addRefreshWrapper(ctx.reactRouterConfig, code, id);
3941
+ }
3942
+ return { code, map: result.map };
3943
+ }
3944
+ },
3945
+ {
3946
+ name: "react-router:hmr-updates",
3947
+ async handleHotUpdate({ server, file, modules, read }) {
3948
+ let route = getRoute(ctx.reactRouterConfig, file);
3949
+ let hmrEventData = { route: null };
3950
+ if (route) {
3951
+ let oldRouteMetadata = currentReactRouterManifestForDev?.routes[route.id];
3952
+ let newRouteMetadata = await getRouteMetadata(
3953
+ cache,
3954
+ ctx,
3955
+ viteChildCompiler,
3956
+ route,
3957
+ read
3958
+ );
3959
+ hmrEventData.route = newRouteMetadata;
3960
+ if (!oldRouteMetadata || [
3961
+ "hasLoader",
3962
+ "hasClientLoader",
3963
+ "clientLoaderModule",
3964
+ "hasAction",
3965
+ "hasClientAction",
3966
+ "clientActionModule",
3967
+ "hasClientMiddleware",
3968
+ "clientMiddlewareModule",
3969
+ "hasErrorBoundary",
3970
+ "hydrateFallbackModule"
3971
+ ].some((key) => oldRouteMetadata[key] !== newRouteMetadata[key])) {
3972
+ invalidateVirtualModules(server);
3973
+ }
3974
+ }
3975
+ server.hot.send({
3976
+ type: "custom",
3977
+ event: "react-router:hmr",
3978
+ data: hmrEventData
3979
+ });
3980
+ return modules;
3981
+ }
3982
+ },
3983
+ {
3984
+ name: "react-router-server-change-trigger-client-hmr",
3985
+ // This hook is only available in Vite v6+ so this is a no-op in v5.
3986
+ // Previously, the server and client modules were shared in a single module
3987
+ // graph. This meant that changes to server code automatically resulted in
3988
+ // client HMR updates. In Vite v6+, these module graphs are separate from
3989
+ // each other, so we need to manually trigger client HMR updates if server
3990
+ // code has changed.
3991
+ hotUpdate({ server, modules }) {
3992
+ if (this.environment.name !== "ssr" && modules.length <= 0) {
3993
+ return;
3994
+ }
3995
+ let clientModules = uniqueNodes(
3996
+ modules.flatMap(
3997
+ (mod) => getParentClientNodes(server.environments.client.moduleGraph, mod)
3998
+ )
3999
+ );
4000
+ for (let clientModule of clientModules) {
4001
+ server.environments.client.reloadModule(clientModule);
4002
+ }
4003
+ }
4004
+ },
4005
+ validatePluginOrder()
4006
+ ];
4007
+ };
4008
+ function getParentClientNodes(clientModuleGraph, module2) {
4009
+ if (!module2.id) {
4010
+ return [];
4011
+ }
4012
+ let clientModule = clientModuleGraph.getModuleById(module2.id);
4013
+ if (clientModule) {
4014
+ return [clientModule];
4015
+ }
4016
+ return [...module2.importers].flatMap(
4017
+ (importer) => getParentClientNodes(clientModuleGraph, importer)
4018
+ );
4019
+ }
4020
+ function uniqueNodes(nodes) {
4021
+ let nodeUrls = /* @__PURE__ */ new Set();
4022
+ let unique = [];
4023
+ for (let node of nodes) {
4024
+ if (nodeUrls.has(node.url)) {
4025
+ continue;
4026
+ }
4027
+ nodeUrls.add(node.url);
4028
+ unique.push(node);
4029
+ }
4030
+ return unique;
4031
+ }
4032
+ function addRefreshWrapper(reactRouterConfig, code, id) {
4033
+ let route = getRoute(reactRouterConfig, id);
4034
+ let acceptExports = route ? CLIENT_NON_COMPONENT_EXPORTS : [];
4035
+ return REACT_REFRESH_HEADER.replaceAll("__SOURCE__", JSON.stringify(id)) + code + REACT_REFRESH_FOOTER.replaceAll("__SOURCE__", JSON.stringify(id)).replaceAll("__ACCEPT_EXPORTS__", JSON.stringify(acceptExports)).replaceAll("__ROUTE_ID__", JSON.stringify(route?.id));
4036
+ }
4037
+ var REACT_REFRESH_HEADER = `
4038
+ import RefreshRuntime from "${virtualHmrRuntime.id}";
4039
+
4040
+ const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
4041
+ let prevRefreshReg;
4042
+ let prevRefreshSig;
4043
+
4044
+ if (import.meta.hot && !inWebWorker) {
4045
+ if (!window.__vite_plugin_react_preamble_installed__) {
4046
+ throw new Error(
4047
+ "React Router Vite plugin can't detect preamble. Something is wrong."
4048
+ );
4049
+ }
4050
+
4051
+ prevRefreshReg = window.$RefreshReg$;
4052
+ prevRefreshSig = window.$RefreshSig$;
4053
+ window.$RefreshReg$ = (type, id) => {
4054
+ RefreshRuntime.register(type, __SOURCE__ + " " + id)
4055
+ };
4056
+ window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
4057
+ }`.replaceAll("\n", "");
4058
+ var REACT_REFRESH_FOOTER = `
4059
+ if (import.meta.hot && !inWebWorker) {
4060
+ window.$RefreshReg$ = prevRefreshReg;
4061
+ window.$RefreshSig$ = prevRefreshSig;
4062
+ RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
4063
+ RefreshRuntime.registerExportsForReactRefresh(__SOURCE__, currentExports);
4064
+ import.meta.hot.accept((nextExports) => {
4065
+ if (!nextExports) return;
4066
+ __ROUTE_ID__ && window.__reactRouterRouteModuleUpdates.set(__ROUTE_ID__, nextExports);
4067
+ const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports, __ACCEPT_EXPORTS__);
4068
+ if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
4069
+ });
4070
+ });
4071
+ }`;
4072
+ function getRoute(pluginConfig, file) {
4073
+ let vite2 = getVite();
4074
+ let routePath = vite2.normalizePath(
4075
+ path6.relative(pluginConfig.appDirectory, file)
4076
+ );
4077
+ let route = Object.values(pluginConfig.routes).find(
4078
+ (r) => vite2.normalizePath(r.file) === routePath
4079
+ );
4080
+ return route;
4081
+ }
4082
+ function isRoute(pluginConfig, file) {
4083
+ return Boolean(getRoute(pluginConfig, file));
4084
+ }
4085
+ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteFile) {
4086
+ let routeFile = route.file;
4087
+ let sourceExports = await getRouteModuleExports(
4088
+ viteChildCompiler,
4089
+ ctx,
4090
+ route.file,
4091
+ readRouteFile
4092
+ );
4093
+ let { hasRouteChunkByExportName } = await detectRouteChunksIfEnabled(
4094
+ cache,
4095
+ ctx,
4096
+ routeFile,
4097
+ { routeFile, readRouteFile, viteChildCompiler }
4098
+ );
4099
+ let moduleUrl = combineURLs(
4100
+ ctx.publicPath,
4101
+ `${resolveFileUrl(
4102
+ ctx,
4103
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
4104
+ )}`
4105
+ );
4106
+ let info = {
4107
+ id: route.id,
4108
+ parentId: route.parentId,
4109
+ path: route.path,
4110
+ index: route.index,
4111
+ caseSensitive: route.caseSensitive,
4112
+ url: combineURLs(
4113
+ ctx.publicPath,
4114
+ "/" + path6.relative(
4115
+ ctx.rootDirectory,
4116
+ resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
4117
+ )
4118
+ ),
4119
+ module: `${moduleUrl}?import`,
4120
+ // Ensure the Vite dev server responds with a JS module
4121
+ clientActionModule: hasRouteChunkByExportName.clientAction ? `${getRouteChunkModuleId(moduleUrl, "clientAction")}` : void 0,
4122
+ clientLoaderModule: hasRouteChunkByExportName.clientLoader ? `${getRouteChunkModuleId(moduleUrl, "clientLoader")}` : void 0,
4123
+ clientMiddlewareModule: hasRouteChunkByExportName.clientMiddleware ? `${getRouteChunkModuleId(moduleUrl, "clientMiddleware")}` : void 0,
4124
+ hydrateFallbackModule: hasRouteChunkByExportName.HydrateFallback ? `${getRouteChunkModuleId(moduleUrl, "HydrateFallback")}` : void 0,
4125
+ hasAction: sourceExports.includes("action"),
4126
+ hasClientAction: sourceExports.includes("clientAction"),
4127
+ hasLoader: sourceExports.includes("loader"),
4128
+ hasClientLoader: sourceExports.includes("clientLoader"),
4129
+ hasClientMiddleware: sourceExports.includes("clientMiddleware"),
4130
+ hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
4131
+ imports: []
4132
+ };
4133
+ return info;
4134
+ }
4135
+ function isPrerenderingEnabled(reactRouterConfig) {
4136
+ return reactRouterConfig.prerender != null && reactRouterConfig.prerender !== false;
4137
+ }
4138
+ function isSpaModeEnabled(reactRouterConfig) {
4139
+ return reactRouterConfig.ssr === false && !isPrerenderingEnabled(reactRouterConfig);
4140
+ }
4141
+ async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
4142
+ let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
4143
+ let build = await import(url.pathToFileURL(serverBuildPath).toString());
4144
+ let { createRequestHandler: createHandler } = await import("react-router");
4145
+ return {
4146
+ build,
4147
+ handler: createHandler(build, viteConfig.mode)
4148
+ };
4149
+ }
4150
+ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildFile, clientBuildDirectory) {
4151
+ let { build, handler } = await getPrerenderBuildAndHandler(
4152
+ viteConfig,
4153
+ serverBuildDirectory,
4154
+ serverBuildFile
4155
+ );
4156
+ let request = new Request(`http://localhost${reactRouterConfig.basename}`, {
4157
+ headers: {
4158
+ // Enable SPA mode in the server runtime and only render down to the root
4159
+ "X-React-Router-SPA-Mode": "yes"
4160
+ }
4161
+ });
4162
+ let response = await handler(request);
4163
+ let html = await response.text();
4164
+ let isPrerenderSpaFallback = build.prerender.includes("/");
4165
+ let filename2 = isPrerenderSpaFallback ? "__spa-fallback.html" : "index.html";
4166
+ if (response.status !== 200) {
4167
+ if (isPrerenderSpaFallback) {
4168
+ throw new Error(
4169
+ `Prerender: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename2}\` file.
4170
+ ` + html
4171
+ );
4172
+ } else {
4173
+ throw new Error(
4174
+ `SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename2}\` file.
4175
+ ` + html
4176
+ );
4177
+ }
4178
+ }
4179
+ if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
4180
+ throw new Error(
4181
+ "SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
4182
+ );
4183
+ }
4184
+ await (0, import_promises2.writeFile)(path6.join(clientBuildDirectory, filename2), html);
4185
+ let prettyDir = path6.relative(viteConfig.root, clientBuildDirectory);
4186
+ let prettyPath = path6.join(prettyDir, filename2);
4187
+ if (build.prerender.length > 0) {
4188
+ viteConfig.logger.info(
4189
+ `Prerender (html): SPA Fallback -> ${import_picocolors3.default.bold(prettyPath)}`
4190
+ );
4191
+ } else {
4192
+ viteConfig.logger.info(`SPA Mode: Generated ${import_picocolors3.default.bold(prettyPath)}`);
4193
+ }
4194
+ }
4195
+ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, serverBuildPath, clientBuildDirectory) {
4196
+ let { build, handler } = await getPrerenderBuildAndHandler(
4197
+ viteConfig,
4198
+ serverBuildDirectory,
4199
+ serverBuildPath
4200
+ );
4201
+ let routes = createPrerenderRoutes(reactRouterConfig.routes);
4202
+ for (let path7 of build.prerender) {
4203
+ let matches = (0, import_react_router2.matchRoutes)(routes, `/${path7}/`.replace(/^\/\/+/, "/"));
4204
+ if (!matches) {
4205
+ throw new Error(
4206
+ `Unable to prerender path because it does not match any routes: ${path7}`
4207
+ );
4208
+ }
4209
+ }
4210
+ let buildRoutes = createPrerenderRoutes(build.routes);
4211
+ for (let path7 of build.prerender) {
4212
+ let matches = (0, import_react_router2.matchRoutes)(buildRoutes, `/${path7}/`.replace(/^\/\/+/, "/"));
4213
+ if (!matches) {
4214
+ continue;
4215
+ }
4216
+ let leafRoute = matches ? matches[matches.length - 1].route : null;
4217
+ let manifestRoute = leafRoute ? build.routes[leafRoute.id]?.module : null;
4218
+ let isResourceRoute = manifestRoute && !manifestRoute.default && !manifestRoute.ErrorBoundary;
4219
+ if (isResourceRoute) {
4220
+ invariant(leafRoute);
4221
+ invariant(manifestRoute);
4222
+ if (manifestRoute.loader) {
4223
+ await prerenderData(
4224
+ handler,
4225
+ path7,
4226
+ [leafRoute.id],
4227
+ clientBuildDirectory,
4228
+ reactRouterConfig,
4229
+ viteConfig
4230
+ );
4231
+ await prerenderResourceRoute(
4232
+ handler,
4233
+ path7,
4234
+ clientBuildDirectory,
4235
+ reactRouterConfig,
4236
+ viteConfig
4237
+ );
4238
+ } else {
4239
+ viteConfig.logger.warn(
4240
+ `\u26A0\uFE0F Skipping prerendering for resource route without a loader: ${leafRoute?.id}`
4241
+ );
4242
+ }
4243
+ } else {
4244
+ let hasLoaders = matches.some(
4245
+ (m) => build.assets.routes[m.route.id]?.hasLoader
4246
+ );
4247
+ let data;
4248
+ if (!isResourceRoute && hasLoaders) {
4249
+ data = await prerenderData(
4250
+ handler,
4251
+ path7,
4252
+ null,
4253
+ clientBuildDirectory,
4254
+ reactRouterConfig,
4255
+ viteConfig
4256
+ );
4257
+ }
4258
+ await prerenderRoute(
4259
+ handler,
4260
+ path7,
4261
+ clientBuildDirectory,
4262
+ reactRouterConfig,
4263
+ viteConfig,
4264
+ data ? {
4265
+ headers: {
4266
+ "X-React-Router-Prerender-Data": encodeURI(data)
4267
+ }
4268
+ } : void 0
4269
+ );
4270
+ }
4271
+ }
4272
+ }
4273
+ function getStaticPrerenderPaths(routes) {
4274
+ let paths = ["/"];
4275
+ let paramRoutes = [];
4276
+ function recurse(subtree, prefix = "") {
4277
+ for (let route of subtree) {
4278
+ let newPath = [prefix, route.path].join("/").replace(/\/\/+/g, "/");
4279
+ if (route.path) {
4280
+ let segments = route.path.split("/");
4281
+ if (segments.some((s) => s.startsWith(":") || s === "*")) {
4282
+ paramRoutes.push(route.path);
4283
+ } else {
4284
+ paths.push(newPath);
4285
+ }
4286
+ }
4287
+ if (route.children) {
4288
+ recurse(route.children, newPath);
4289
+ }
4290
+ }
4291
+ }
4292
+ recurse(routes);
4293
+ return {
4294
+ paths: paths.map((p) => p.replace(/\/\/+/g, "/").replace(/(.+)\/$/, "$1")),
4295
+ paramRoutes
4296
+ };
4297
+ }
4298
+ async function prerenderData(handler, prerenderPath, onlyRoutes, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
4299
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
4300
+ let url2 = new URL(`http://localhost${normalizedPath}`);
4301
+ if (onlyRoutes?.length) {
4302
+ url2.searchParams.set("_routes", onlyRoutes.join(","));
4303
+ }
4304
+ let request = new Request(url2, requestInit);
4305
+ let response = await handler(request);
4306
+ let data = await response.text();
4307
+ if (response.status !== 200 && response.status !== 202) {
4308
+ throw new Error(
4309
+ `Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${prerenderPath}\` path.
4310
+ ${normalizedPath}`
4311
+ );
4312
+ }
4313
+ let outfile = path6.join(clientBuildDirectory, ...normalizedPath.split("/"));
4314
+ await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4315
+ await (0, import_promises2.writeFile)(outfile, data);
4316
+ viteConfig.logger.info(
4317
+ `Prerender (data): ${prerenderPath} -> ${import_picocolors3.default.bold(
4318
+ path6.relative(viteConfig.root, outfile)
4319
+ )}`
4320
+ );
4321
+ return data;
4322
+ }
4323
+ var redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
4324
+ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
4325
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(
4326
+ /\/\/+/g,
4327
+ "/"
4328
+ );
4329
+ let request = new Request(`http://localhost${normalizedPath}`, requestInit);
4330
+ let response = await handler(request);
4331
+ let html = await response.text();
4332
+ if (redirectStatusCodes.has(response.status)) {
4333
+ let location = response.headers.get("Location");
4334
+ let delay = response.status === 302 ? 2 : 0;
4335
+ html = `<!doctype html>
4336
+ <head>
4337
+ <title>Redirecting to: ${location}</title>
4338
+ <meta http-equiv="refresh" content="${delay};url=${location}">
4339
+ <meta name="robots" content="noindex">
4340
+ </head>
4341
+ <body>
4342
+ <a href="${location}">
4343
+ Redirecting from <code>${normalizedPath}</code> to <code>${location}</code>
4344
+ </a>
4345
+ </body>
4346
+ </html>`;
4347
+ } else if (response.status !== 200) {
4348
+ throw new Error(
4349
+ `Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
4350
+ ${html}`
4351
+ );
4352
+ }
4353
+ let outfile = path6.join(
4354
+ clientBuildDirectory,
4355
+ ...normalizedPath.split("/"),
4356
+ "index.html"
4357
+ );
4358
+ await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4359
+ await (0, import_promises2.writeFile)(outfile, html);
4360
+ viteConfig.logger.info(
4361
+ `Prerender (html): ${prerenderPath} -> ${import_picocolors3.default.bold(
4362
+ path6.relative(viteConfig.root, outfile)
4363
+ )}`
4364
+ );
4365
+ }
4366
+ async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
4367
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
4368
+ let request = new Request(`http://localhost${normalizedPath}`, requestInit);
4369
+ let response = await handler(request);
4370
+ let content = Buffer.from(await response.arrayBuffer());
4371
+ if (response.status !== 200) {
4372
+ throw new Error(
4373
+ `Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
4374
+ ${content.toString("utf8")}`
4375
+ );
4376
+ }
4377
+ let outfile = path6.join(clientBuildDirectory, ...normalizedPath.split("/"));
4378
+ await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4379
+ await (0, import_promises2.writeFile)(outfile, content);
4380
+ viteConfig.logger.info(
4381
+ `Prerender (resource): ${prerenderPath} -> ${import_picocolors3.default.bold(
4382
+ path6.relative(viteConfig.root, outfile)
4383
+ )}`
4384
+ );
4385
+ }
4386
+ async function getPrerenderPaths(prerender, ssr, routes, logWarning = false) {
4387
+ let prerenderPaths = [];
4388
+ if (prerender != null && prerender !== false) {
4389
+ let prerenderRoutes = createPrerenderRoutes(routes);
4390
+ if (prerender === true) {
4391
+ let { paths, paramRoutes } = getStaticPrerenderPaths(prerenderRoutes);
4392
+ if (logWarning && !ssr && paramRoutes.length > 0) {
4393
+ console.warn(
4394
+ import_picocolors3.default.yellow(
4395
+ [
4396
+ "\u26A0\uFE0F Paths with dynamic/splat params cannot be prerendered when using `prerender: true`. You may want to use the `prerender()` API to prerender the following paths:",
4397
+ ...paramRoutes.map((p) => " - " + p)
4398
+ ].join("\n")
4399
+ )
4400
+ );
4401
+ }
4402
+ prerenderPaths = paths;
4403
+ } else if (typeof prerender === "function") {
4404
+ prerenderPaths = await prerender({
4405
+ getStaticPaths: () => getStaticPrerenderPaths(prerenderRoutes).paths
4406
+ });
4407
+ } else {
4408
+ prerenderPaths = prerender || ["/"];
4409
+ }
4410
+ }
4411
+ return prerenderPaths;
4412
+ }
4413
+ function groupRoutesByParentId2(manifest) {
4414
+ let routes = {};
4415
+ Object.values(manifest).forEach((route) => {
4416
+ if (route) {
4417
+ let parentId = route.parentId || "";
4418
+ if (!routes[parentId]) {
4419
+ routes[parentId] = [];
4420
+ }
4421
+ routes[parentId].push(route);
4422
+ }
4423
+ });
4424
+ return routes;
4425
+ }
4426
+ function createPrerenderRoutes(manifest, parentId = "", routesByParentId = groupRoutesByParentId2(manifest)) {
4427
+ return (routesByParentId[parentId] || []).map((route) => {
4428
+ let commonRoute = {
4429
+ id: route.id,
4430
+ path: route.path
4431
+ };
4432
+ if (route.index) {
4433
+ return {
4434
+ index: true,
4435
+ ...commonRoute
4436
+ };
4437
+ }
4438
+ return {
4439
+ children: createPrerenderRoutes(manifest, route.id, routesByParentId),
4440
+ ...commonRoute
4441
+ };
4442
+ });
4443
+ }
4444
+ async function validateSsrFalsePrerenderExports(viteConfig, ctx, manifest, viteChildCompiler) {
4445
+ let prerenderPaths = await getPrerenderPaths(
4446
+ ctx.reactRouterConfig.prerender,
4447
+ ctx.reactRouterConfig.ssr,
4448
+ manifest.routes,
4449
+ true
4450
+ );
4451
+ if (prerenderPaths.length === 0) {
4452
+ return;
4453
+ }
4454
+ let prerenderRoutes = createPrerenderRoutes(manifest.routes);
4455
+ let prerenderedRoutes = /* @__PURE__ */ new Set();
4456
+ for (let path7 of prerenderPaths) {
4457
+ let matches = (0, import_react_router2.matchRoutes)(
4458
+ prerenderRoutes,
4459
+ `/${path7}/`.replace(/^\/\/+/, "/")
4460
+ );
4461
+ invariant(
4462
+ matches,
4463
+ `Unable to prerender path because it does not match any routes: ${path7}`
4464
+ );
4465
+ matches.forEach((m) => prerenderedRoutes.add(m.route.id));
4466
+ }
4467
+ let errors = [];
4468
+ let routeExports = await getRouteManifestModuleExports(
4469
+ viteChildCompiler,
4470
+ ctx
4471
+ );
4472
+ for (let [routeId, route] of Object.entries(manifest.routes)) {
4473
+ let invalidApis = [];
4474
+ invariant(route, "Expected a route object in validateSsrFalseExports");
4475
+ let exports2 = routeExports[route.id];
4476
+ if (exports2.includes("headers")) invalidApis.push("headers");
4477
+ if (exports2.includes("action")) invalidApis.push("action");
4478
+ if (invalidApis.length > 0) {
4479
+ errors.push(
4480
+ `Prerender: ${invalidApis.length} invalid route export(s) in \`${route.id}\` when pre-rendering with \`ssr:false\`: ${invalidApis.map((a) => `\`${a}\``).join(", ")}. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`
4481
+ );
4482
+ }
4483
+ if (!prerenderedRoutes.has(routeId)) {
4484
+ if (exports2.includes("loader")) {
4485
+ errors.push(
4486
+ `Prerender: 1 invalid route export in \`${route.id}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`
4487
+ );
4488
+ }
4489
+ let parentRoute = route.parentId ? manifest.routes[route.parentId] : null;
4490
+ while (parentRoute && parentRoute.id !== "root") {
4491
+ if (parentRoute.hasLoader && !parentRoute.hasClientLoader) {
4492
+ errors.push(
4493
+ `Prerender: 1 invalid route export in \`${parentRoute.id}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`
4494
+ );
4495
+ }
4496
+ parentRoute = parentRoute.parentId && parentRoute.parentId !== "root" ? manifest.routes[parentRoute.parentId] : null;
4497
+ }
4498
+ }
4499
+ }
4500
+ if (errors.length > 0) {
4501
+ viteConfig.logger.error(import_picocolors3.default.red(errors.join("\n")));
4502
+ throw new Error(
4503
+ "Invalid route exports found when prerendering with `ssr:false`"
4504
+ );
4505
+ }
4506
+ }
4507
+ function getAddressableRoutes(routes) {
4508
+ let nonAddressableIds = /* @__PURE__ */ new Set();
4509
+ for (let id in routes) {
4510
+ let route = routes[id];
4511
+ if (route.index) {
4512
+ invariant(
4513
+ route.parentId,
4514
+ `Expected index route "${route.id}" to have "parentId" set`
4515
+ );
4516
+ nonAddressableIds.add(route.parentId);
4517
+ }
4518
+ if (typeof route.path !== "string" && !route.index) {
4519
+ nonAddressableIds.add(id);
4520
+ }
4521
+ }
4522
+ return Object.values(routes).filter(
4523
+ (route) => !nonAddressableIds.has(route.id)
4524
+ );
4525
+ }
4526
+ function getRouteBranch(routes, routeId) {
4527
+ let branch = [];
4528
+ let currentRouteId = routeId;
4529
+ while (currentRouteId) {
4530
+ let route = routes[currentRouteId];
4531
+ invariant(route, `Missing route for ${currentRouteId}`);
4532
+ branch.push(route);
4533
+ currentRouteId = route.parentId;
4534
+ }
4535
+ return branch.reverse();
4536
+ }
4537
+ function getServerBundleIds(ctx) {
4538
+ return ctx.buildManifest?.serverBundles ? Object.keys(ctx.buildManifest.serverBundles) : void 0;
4539
+ }
4540
+ function getRoutesByServerBundleId(buildManifest) {
4541
+ if (!buildManifest.routeIdToServerBundleId) {
4542
+ return {};
4543
+ }
4544
+ let routesByServerBundleId = {};
4545
+ for (let [routeId, serverBundleId] of Object.entries(
4546
+ buildManifest.routeIdToServerBundleId
4547
+ )) {
4548
+ routesByServerBundleId[serverBundleId] ??= {};
4549
+ let branch = getRouteBranch(buildManifest.routes, routeId);
4550
+ for (let route of branch) {
4551
+ routesByServerBundleId[serverBundleId][route.id] = route;
4552
+ }
4553
+ }
4554
+ return routesByServerBundleId;
4555
+ }
4556
+ var resolveRouteFileCode = async (ctx, input) => {
4557
+ if (typeof input === "string") return input;
4558
+ invariant(input.viteChildCompiler);
4559
+ return await compileRouteFile(
4560
+ input.viteChildCompiler,
4561
+ ctx,
4562
+ input.routeFile,
4563
+ input.readRouteFile
4564
+ );
4565
+ };
4566
+ function isRootRouteModuleId(ctx, id) {
4567
+ return normalizeRelativeFilePath(id, ctx.reactRouterConfig) === ctx.reactRouterConfig.routes.root.file;
4568
+ }
4569
+ async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
4570
+ function noRouteChunks() {
4571
+ return {
4572
+ chunkedExports: [],
4573
+ hasRouteChunks: false,
4574
+ hasRouteChunkByExportName: {
4575
+ clientAction: false,
4576
+ clientLoader: false,
4577
+ clientMiddleware: false,
4578
+ HydrateFallback: false
4579
+ }
4580
+ };
4581
+ }
4582
+ if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
4583
+ return noRouteChunks();
4584
+ }
4585
+ if (isRootRouteModuleId(ctx, id)) {
4586
+ return noRouteChunks();
4587
+ }
4588
+ let code = await resolveRouteFileCode(ctx, input);
4589
+ if (!routeChunkExportNames.some((exportName) => code.includes(exportName))) {
4590
+ return noRouteChunks();
4591
+ }
4592
+ let cacheKey = normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read");
4593
+ return detectRouteChunks(code, cache, cacheKey);
4594
+ }
4595
+ async function getRouteChunkIfEnabled(cache, ctx, id, chunkName, input) {
4596
+ if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
4597
+ return null;
4598
+ }
4599
+ let code = await resolveRouteFileCode(ctx, input);
4600
+ let cacheKey = normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read");
4601
+ return getRouteChunkCode(code, chunkName, cache, cacheKey);
4602
+ }
4603
+ function validateRouteChunks({
4604
+ ctx,
4605
+ id,
4606
+ valid
4607
+ }) {
4608
+ if (isRootRouteModuleId(ctx, id)) {
4609
+ return;
4610
+ }
4611
+ let invalidChunks = Object.entries(valid).filter(([_, isValid]) => !isValid).map(([chunkName]) => chunkName);
4612
+ if (invalidChunks.length === 0) {
4613
+ return;
4614
+ }
4615
+ let plural = invalidChunks.length > 1;
4616
+ throw new Error(
4617
+ [
4618
+ `Error splitting route module: ${normalizeRelativeFilePath(
4619
+ id,
4620
+ ctx.reactRouterConfig
4621
+ )}`,
4622
+ invalidChunks.map((name) => `- ${name}`).join("\n"),
4623
+ `${plural ? "These exports" : "This export"} could not be split into ${plural ? "their own chunks" : "its own chunk"} because ${plural ? "they share" : "it shares"} code with other exports. You should extract any shared code into its own module and then import it within the route module.`
4624
+ ].join("\n\n")
4625
+ );
4626
+ }
4627
+ async function cleanBuildDirectory(viteConfig, ctx) {
4628
+ let buildDirectory = ctx.reactRouterConfig.buildDirectory;
4629
+ let isWithinRoot = () => {
4630
+ let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
4631
+ return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
4632
+ };
4633
+ if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
4634
+ await (0, import_promises2.rm)(buildDirectory, { force: true, recursive: true });
4635
+ }
4636
+ }
4637
+ async function cleanViteManifests(environmentsOptions, ctx) {
4638
+ let viteManifestPaths = Object.entries(environmentsOptions).map(
4639
+ ([environmentName, options]) => {
4640
+ let outDir = options.build?.outDir;
4641
+ invariant(outDir, `Expected build.outDir for ${environmentName}`);
4642
+ return path6.join(outDir, ".vite/manifest.json");
4643
+ }
4644
+ );
4645
+ await Promise.all(
4646
+ viteManifestPaths.map(async (viteManifestPath) => {
4647
+ let manifestExists = (0, import_node_fs2.existsSync)(viteManifestPath);
4648
+ if (!manifestExists) return;
4649
+ if (!ctx.viteManifestEnabled) {
4650
+ await (0, import_promises2.rm)(viteManifestPath, { force: true, recursive: true });
4651
+ }
4652
+ let viteDir = path6.dirname(viteManifestPath);
4653
+ let viteDirFiles = await (0, import_promises2.readdir)(viteDir, { recursive: true });
4654
+ if (viteDirFiles.length === 0) {
4655
+ await (0, import_promises2.rm)(viteDir, { force: true, recursive: true });
4656
+ }
4657
+ })
4658
+ );
4659
+ }
4660
+ async function getBuildManifest({
4661
+ reactRouterConfig,
4662
+ rootDirectory
4663
+ }) {
4664
+ let { routes, serverBundles, appDirectory } = reactRouterConfig;
4665
+ if (!serverBundles) {
4666
+ return { routes };
4667
+ }
4668
+ let { normalizePath } = await import("vite");
4669
+ let serverBuildDirectory = getServerBuildDirectory(reactRouterConfig);
4670
+ let resolvedAppDirectory = path6.resolve(rootDirectory, appDirectory);
4671
+ let rootRelativeRoutes = Object.fromEntries(
4672
+ Object.entries(routes).map(([id, route]) => {
4673
+ let filePath = path6.join(resolvedAppDirectory, route.file);
4674
+ let rootRelativeFilePath = normalizePath(
4675
+ path6.relative(rootDirectory, filePath)
4676
+ );
4677
+ return [id, { ...route, file: rootRelativeFilePath }];
4678
+ })
4679
+ );
4680
+ let buildManifest = {
4681
+ serverBundles: {},
4682
+ routeIdToServerBundleId: {},
4683
+ routes: rootRelativeRoutes
4684
+ };
4685
+ await Promise.all(
4686
+ getAddressableRoutes(routes).map(async (route) => {
4687
+ let branch = getRouteBranch(routes, route.id);
4688
+ let serverBundleId = await serverBundles({
4689
+ branch: branch.map(
4690
+ (route2) => configRouteToBranchRoute({
4691
+ ...route2,
4692
+ // Ensure absolute paths are passed to the serverBundles function
4693
+ file: path6.join(resolvedAppDirectory, route2.file)
4694
+ })
4695
+ )
4696
+ });
4697
+ if (typeof serverBundleId !== "string") {
4698
+ throw new Error(`The "serverBundles" function must return a string`);
4699
+ }
4700
+ if (reactRouterConfig.future.unstable_viteEnvironmentApi) {
4701
+ if (!/^[a-zA-Z0-9_]+$/.test(serverBundleId)) {
4702
+ throw new Error(
4703
+ `The "serverBundles" function must only return strings containing alphanumeric characters and underscores.`
4704
+ );
4705
+ }
4706
+ } else {
4707
+ if (!/^[a-zA-Z0-9-_]+$/.test(serverBundleId)) {
4708
+ throw new Error(
4709
+ `The "serverBundles" function must only return strings containing alphanumeric characters, hyphens and underscores.`
4710
+ );
4711
+ }
4712
+ }
4713
+ buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;
4714
+ buildManifest.serverBundles[serverBundleId] ??= {
4715
+ id: serverBundleId,
4716
+ file: normalizePath(
4717
+ path6.join(
4718
+ path6.relative(
4719
+ rootDirectory,
4720
+ path6.join(serverBuildDirectory, serverBundleId)
4721
+ ),
4722
+ reactRouterConfig.serverBuildFile
4723
+ )
4724
+ )
4725
+ };
4726
+ })
4727
+ );
4728
+ return buildManifest;
4729
+ }
4730
+ function mergeEnvironmentOptions(base, ...overrides) {
4731
+ let vite2 = getVite();
4732
+ return overrides.reduce(
4733
+ (merged, override) => vite2.mergeConfig(merged, override, false),
4734
+ base
4735
+ );
4736
+ }
4737
+ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4738
+ let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
4739
+ let packageRoot = path6.dirname(
4740
+ require.resolve("@react-router/dev/package.json")
4741
+ );
4742
+ let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
4743
+ let vite2 = getVite();
4744
+ function getBaseOptions({
4745
+ viteUserConfig
4746
+ }) {
4747
+ const rollupOptions = {
4748
+ preserveEntrySignatures: "exports-only",
4749
+ // Silence Rollup "use client" warnings
4750
+ // Adapted from https://github.com/vitejs/vite-plugin-react/pull/144
4751
+ onwarn(warning, defaultHandler) {
4752
+ if (warning.code === "MODULE_LEVEL_DIRECTIVE" && warning.message.includes("use client")) {
4753
+ return;
4754
+ }
4755
+ let userHandler = viteUserConfig.build?.rollupOptions?.onwarn;
4756
+ if (userHandler) {
4757
+ userHandler(warning, defaultHandler);
4758
+ } else {
4759
+ defaultHandler(warning);
4760
+ }
4761
+ }
4762
+ };
4763
+ return {
4764
+ build: {
4765
+ cssMinify: viteUserConfig.build?.cssMinify ?? true,
4766
+ manifest: true,
4767
+ // The manifest is enabled for all builds to detect SSR-only assets
4768
+ rollupOptions
4769
+ }
4770
+ };
4771
+ }
4772
+ function getBaseServerOptions({
4773
+ viteUserConfig
4774
+ }) {
4775
+ let maybeModuleSyncConditions = [
4776
+ ...moduleSyncEnabled ? ["module-sync"] : []
4777
+ ];
4778
+ let maybeDevelopmentConditions = viteCommand === "build" ? [] : ["development"];
4779
+ let maybeDefaultServerConditions = vite2.defaultServerConditions || [];
4780
+ let defaultExternalConditions = ["node"];
4781
+ let baseConditions = [
4782
+ ...maybeDevelopmentConditions,
4783
+ ...maybeModuleSyncConditions
4784
+ ];
4785
+ return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
4786
+ resolve: {
4787
+ external: (
4788
+ // If `unstable_viteEnvironmentApi` is `true`, `resolve.external` is set in the `configEnvironment` hook
4789
+ ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? void 0 : ssrExternals
4790
+ ),
4791
+ conditions: [...baseConditions, ...maybeDefaultServerConditions],
4792
+ externalConditions: [...baseConditions, ...defaultExternalConditions]
4793
+ },
4794
+ build: {
4795
+ // We move SSR-only assets to client assets. Note that the
4796
+ // SSR build can also emit code-split JS files (e.g., by
4797
+ // dynamic import) under the same assets directory
4798
+ // regardless of "ssrEmitAssets" option, so we also need to
4799
+ // keep these JS files to be kept as-is.
4800
+ ssrEmitAssets: true,
4801
+ copyPublicDir: false,
4802
+ // The client only uses assets in the public directory
4803
+ rollupOptions: {
4804
+ input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
4805
+ output: {
4806
+ entryFileNames: serverBuildFile,
4807
+ format: serverModuleFormat
4808
+ }
4809
+ }
4810
+ }
4811
+ });
4812
+ }
4813
+ let environmentOptionsResolvers = {
4814
+ client: ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
4815
+ build: {
4816
+ rollupOptions: {
4817
+ input: [
4818
+ ctx.entryClientFilePath,
4819
+ ...Object.values(ctx.reactRouterConfig.routes).flatMap(
4820
+ (route) => {
4821
+ let routeFilePath = path6.resolve(
4822
+ ctx.reactRouterConfig.appDirectory,
4823
+ route.file
4824
+ );
4825
+ let isRootRoute = route.file === ctx.reactRouterConfig.routes.root.file;
4826
+ let code = (0, import_node_fs2.readFileSync)(routeFilePath, "utf-8");
4827
+ return [
4828
+ `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
4829
+ ...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
4830
+ (exportName) => code.includes(exportName) ? getRouteChunkModuleId(routeFilePath, exportName) : null
4831
+ ) : []
4832
+ ].filter(isNonNullable);
4833
+ }
4834
+ )
4835
+ ],
4836
+ output: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.rollupOptions?.output : viteUserConfig?.build?.rollupOptions?.output) ?? {
4837
+ entryFileNames: ({ moduleIds }) => {
4838
+ let routeChunkModuleId = moduleIds.find(isRouteChunkModuleId);
4839
+ let routeChunkName = routeChunkModuleId ? getRouteChunkNameFromModuleId(routeChunkModuleId)?.replace(
4840
+ "unstable_",
4841
+ ""
4842
+ ) : null;
4843
+ let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
4844
+ let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
4845
+ return path6.posix.join(
4846
+ assetsDir,
4847
+ `[name]${routeChunkSuffix}-[hash].js`
4848
+ );
4849
+ }
4850
+ }
4851
+ },
4852
+ outDir: getClientBuildDirectory(ctx.reactRouterConfig)
4853
+ }
4854
+ })
4855
+ };
4856
+ let serverBundleIds = getServerBundleIds(ctx);
4857
+ if (serverBundleIds) {
4858
+ for (let serverBundleId of serverBundleIds) {
4859
+ const environmentName = `${SSR_BUNDLE_PREFIX}${serverBundleId}`;
4860
+ environmentOptionsResolvers[environmentName] = ({ viteUserConfig }) => mergeEnvironmentOptions(
4861
+ getBaseServerOptions({ viteUserConfig }),
4862
+ {
4863
+ build: {
4864
+ outDir: getServerBuildDirectory(ctx.reactRouterConfig, {
4865
+ serverBundleId
4866
+ })
4867
+ }
4868
+ },
4869
+ // Ensure server bundle environments extend the user's SSR
4870
+ // environment config if it exists
4871
+ viteUserConfig.environments?.ssr ?? {}
4872
+ );
4873
+ }
4874
+ } else {
4875
+ environmentOptionsResolvers.ssr = ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseServerOptions({ viteUserConfig }), {
4876
+ build: {
4877
+ outDir: getServerBuildDirectory(ctx.reactRouterConfig)
4878
+ }
4879
+ });
4880
+ }
4881
+ return environmentOptionsResolvers;
4882
+ }
4883
+ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
4884
+ let environmentOptions = {};
4885
+ for (let [environmentName, resolver] of Object.entries(
4886
+ environmentResolvers
4887
+ )) {
4888
+ environmentOptions[environmentName] = resolver(resolverOptions);
4889
+ }
4890
+ return environmentOptions;
4891
+ }
4892
+ async function getEnvironmentsOptions(ctx, viteCommand, resolverOptions) {
4893
+ let environmentOptionsResolvers = await getEnvironmentOptionsResolvers(
4894
+ ctx,
4895
+ viteCommand
4896
+ );
4897
+ return resolveEnvironmentsOptions(
4898
+ environmentOptionsResolvers,
4899
+ resolverOptions
4900
+ );
4901
+ }
4902
+ function isNonNullable(x) {
4903
+ return x != null;
4904
+ }
4905
+ async function asyncFlatten(arr) {
4906
+ do {
4907
+ arr = (await Promise.all(arr)).flat(Infinity);
4908
+ } while (arr.some((v2) => v2?.then));
4909
+ return arr;
4910
+ }
4911
+ // Annotate the CommonJS export names for ESM import in node:
4912
+ 0 && (module.exports = {
4913
+ reactRouter
4914
+ });