@react-router/dev 0.0.0-experimental-e56aa53bc → 0.0.0-experimental-5bbc45fb6

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/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v0.0.0-experimental-e56aa53bc
3
+ * @react-router/dev v0.0.0-experimental-5bbc45fb6
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -125,13 +125,15 @@ var init_ssr_externals = __esm({
125
125
  // vite/vite-node.ts
126
126
  async function createContext({
127
127
  root,
128
- mode
128
+ mode,
129
+ customLogger
129
130
  }) {
130
131
  await preloadVite();
131
132
  const vite2 = getVite();
132
133
  const devServer = await vite2.createServer({
133
134
  root,
134
135
  mode,
136
+ customLogger,
135
137
  server: {
136
138
  preTransformRequests: false,
137
139
  hmr: false,
@@ -143,6 +145,15 @@ async function createContext({
143
145
  optimizeDeps: {
144
146
  noDiscovery: true
145
147
  },
148
+ css: {
149
+ // This empty PostCSS config object prevents the PostCSS config file from
150
+ // being loaded. We don't need it in a React Router config context, and
151
+ // there's also an issue in Vite 5 when using a .ts PostCSS config file in
152
+ // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers
153
+ // can work around this in their own Vite config file, but they can't
154
+ // configure this internal usage of vite-node.
155
+ postcss: {}
156
+ },
146
157
  configFile: false,
147
158
  envFile: false,
148
159
  plugins: []
@@ -205,7 +216,7 @@ function validateRouteConfig({
205
216
  `Route config in "${routeConfigFile}" is invalid.`,
206
217
  root ? `${root}` : [],
207
218
  nested ? Object.entries(nested).map(
208
- ([path9, message]) => `Path: routes.${path9}
219
+ ([path8, message]) => `Path: routes.${path8}
209
220
  ${message}`
210
221
  ) : []
211
222
  ].flat().join("\n\n")
@@ -290,7 +301,8 @@ function err(error) {
290
301
  async function resolveConfig({
291
302
  root,
292
303
  viteNodeContext,
293
- reactRouterConfigFile
304
+ reactRouterConfigFile,
305
+ skipRoutes
294
306
  }) {
295
307
  let reactRouterUserConfig = {};
296
308
  if (reactRouterConfigFile) {
@@ -339,12 +351,17 @@ async function resolveConfig({
339
351
  serverModuleFormat: "esm",
340
352
  ssr: true
341
353
  };
354
+ let userAndPresetConfigs = mergeReactRouterConfig(
355
+ ...presets,
356
+ reactRouterUserConfig
357
+ );
342
358
  let {
343
359
  appDirectory: userAppDirectory,
344
- basename: basename2,
360
+ basename: basename3,
345
361
  buildDirectory: userBuildDirectory,
346
362
  buildEnd,
347
363
  prerender,
364
+ routeDiscovery: userRouteDiscovery,
348
365
  serverBuildFile,
349
366
  serverBundles,
350
367
  serverModuleFormat,
@@ -352,7 +369,7 @@ async function resolveConfig({
352
369
  } = {
353
370
  ...defaults,
354
371
  // Default values should be completely overridden by user/preset config, not merged
355
- ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
372
+ ...userAndPresetConfigs
356
373
  };
357
374
  if (!ssr && serverBundles) {
358
375
  serverBundles = void 0;
@@ -363,6 +380,32 @@ async function resolveConfig({
363
380
  "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
364
381
  );
365
382
  }
383
+ let routeDiscovery;
384
+ if (userRouteDiscovery == null) {
385
+ if (ssr) {
386
+ routeDiscovery = {
387
+ mode: "lazy",
388
+ manifestPath: "/__manifest"
389
+ };
390
+ } else {
391
+ routeDiscovery = { mode: "initial" };
392
+ }
393
+ } else if (userRouteDiscovery.mode === "initial") {
394
+ routeDiscovery = userRouteDiscovery;
395
+ } else if (userRouteDiscovery.mode === "lazy") {
396
+ if (!ssr) {
397
+ return err(
398
+ 'The `routeDiscovery.mode` config cannot be set to "lazy" when setting `ssr:false`'
399
+ );
400
+ }
401
+ let { manifestPath } = userRouteDiscovery;
402
+ if (manifestPath != null && !manifestPath.startsWith("/")) {
403
+ return err(
404
+ 'The `routeDiscovery.manifestPath` config must be a root-relative pathname beginning with a slash (i.e., "/__manifest")'
405
+ );
406
+ }
407
+ routeDiscovery = userRouteDiscovery;
408
+ }
366
409
  let appDirectory = import_pathe3.default.resolve(root, userAppDirectory || "app");
367
410
  let buildDirectory = import_pathe3.default.resolve(root, userBuildDirectory);
368
411
  let rootRouteFile = findEntry(appDirectory, "root");
@@ -375,45 +418,50 @@ async function resolveConfig({
375
418
  `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
376
419
  );
377
420
  }
378
- let routes2 = {
379
- root: { path: "", id: "root", file: rootRouteFile }
380
- };
381
- let routeConfigFile = findEntry(appDirectory, "routes");
382
- try {
383
- if (!routeConfigFile) {
384
- let routeConfigDisplayPath = import_pathe3.default.relative(
385
- root,
386
- import_pathe3.default.join(appDirectory, "routes.ts")
387
- );
388
- return err(`Route config file not found at "${routeConfigDisplayPath}".`);
389
- }
390
- setAppDirectory(appDirectory);
391
- let routeConfigExport = (await viteNodeContext.runner.executeFile(
392
- import_pathe3.default.join(appDirectory, routeConfigFile)
393
- )).default;
394
- let routeConfig = await routeConfigExport;
395
- let result = validateRouteConfig({
396
- routeConfigFile,
397
- routeConfig
398
- });
399
- if (!result.valid) {
400
- return err(result.message);
401
- }
421
+ let routes2 = {};
422
+ if (!skipRoutes) {
402
423
  routes2 = {
403
- ...routes2,
404
- ...configRoutesToRouteManifest(appDirectory, routeConfig)
424
+ root: { path: "", id: "root", file: rootRouteFile }
405
425
  };
406
- } catch (error) {
407
- return err(
408
- [
409
- import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
410
- "",
411
- error.loc?.file && error.loc?.column && error.frame ? [
412
- import_pathe3.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
413
- error.frame.trim?.()
414
- ] : error.stack
415
- ].flat().join("\n")
416
- );
426
+ let routeConfigFile = findEntry(appDirectory, "routes");
427
+ try {
428
+ if (!routeConfigFile) {
429
+ let routeConfigDisplayPath = import_pathe3.default.relative(
430
+ root,
431
+ import_pathe3.default.join(appDirectory, "routes.ts")
432
+ );
433
+ return err(
434
+ `Route config file not found at "${routeConfigDisplayPath}".`
435
+ );
436
+ }
437
+ setAppDirectory(appDirectory);
438
+ let routeConfigExport = (await viteNodeContext.runner.executeFile(
439
+ import_pathe3.default.join(appDirectory, routeConfigFile)
440
+ )).default;
441
+ let routeConfig = await routeConfigExport;
442
+ let result = validateRouteConfig({
443
+ routeConfigFile,
444
+ routeConfig
445
+ });
446
+ if (!result.valid) {
447
+ return err(result.message);
448
+ }
449
+ routes2 = {
450
+ ...routes2,
451
+ ...configRoutesToRouteManifest(appDirectory, routeConfig)
452
+ };
453
+ } catch (error) {
454
+ return err(
455
+ [
456
+ import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
457
+ "",
458
+ error.loc?.file && error.loc?.column && error.frame ? [
459
+ import_pathe3.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
460
+ error.frame.trim?.()
461
+ ] : error.stack
462
+ ].flat().join("\n")
463
+ );
464
+ }
417
465
  }
418
466
  let future = {
419
467
  unstable_middleware: reactRouterUserConfig.future?.unstable_middleware ?? false,
@@ -424,12 +472,13 @@ async function resolveConfig({
424
472
  };
425
473
  let reactRouterConfig = deepFreeze({
426
474
  appDirectory,
427
- basename: basename2,
475
+ basename: basename3,
428
476
  buildDirectory,
429
477
  buildEnd,
430
478
  future,
431
479
  prerender,
432
480
  routes: routes2,
481
+ routeDiscovery,
433
482
  serverBuildFile,
434
483
  serverBundles,
435
484
  serverModuleFormat,
@@ -442,24 +491,35 @@ async function resolveConfig({
442
491
  }
443
492
  async function createConfigLoader({
444
493
  rootDirectory: root,
445
- watch: watch2
494
+ watch: watch2,
495
+ mode,
496
+ skipRoutes
446
497
  }) {
447
- root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
498
+ root = import_pathe3.default.normalize(root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd());
499
+ let vite2 = await import("vite");
448
500
  let viteNodeContext = await createContext({
449
501
  root,
450
- mode: watch2 ? "development" : "production"
451
- });
452
- let reactRouterConfigFile = findEntry(root, "react-router.config", {
453
- absolute: true
502
+ mode,
503
+ // Filter out any info level logs from vite-node
504
+ customLogger: vite2.createLogger("warn", {
505
+ prefix: "[react-router]"
506
+ })
454
507
  });
455
- let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
508
+ let reactRouterConfigFile;
509
+ let updateReactRouterConfigFile = () => {
510
+ reactRouterConfigFile = findEntry(root, "react-router.config", {
511
+ absolute: true
512
+ });
513
+ };
514
+ updateReactRouterConfigFile();
515
+ let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile, skipRoutes });
456
516
  let appDirectory;
457
517
  let initialConfigResult = await getConfig();
458
518
  if (!initialConfigResult.ok) {
459
519
  throw new Error(initialConfigResult.error);
460
520
  }
461
- appDirectory = initialConfigResult.value.appDirectory;
462
- let lastConfig = initialConfigResult.value;
521
+ appDirectory = import_pathe3.default.normalize(initialConfigResult.value.appDirectory);
522
+ let currentConfig = initialConfigResult.value;
463
523
  let fsWatcher;
464
524
  let changeHandlers = [];
465
525
  return {
@@ -472,41 +532,71 @@ async function createConfigLoader({
472
532
  }
473
533
  changeHandlers.push(handler);
474
534
  if (!fsWatcher) {
475
- fsWatcher = import_chokidar.default.watch(
476
- [
477
- ...reactRouterConfigFile ? [reactRouterConfigFile] : [],
478
- appDirectory
479
- ],
480
- { ignoreInitial: true }
481
- );
535
+ fsWatcher = import_chokidar.default.watch([root, appDirectory], {
536
+ ignoreInitial: true,
537
+ ignored: (path8) => {
538
+ let dirname5 = import_pathe3.default.dirname(path8);
539
+ return !dirname5.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
540
+ // that are at the root level, not nested in subdirectories
541
+ path8 !== root && // Watch the root directory itself
542
+ dirname5 !== root;
543
+ }
544
+ });
482
545
  fsWatcher.on("all", async (...args) => {
483
546
  let [event, rawFilepath] = args;
484
547
  let filepath = import_pathe3.default.normalize(rawFilepath);
485
- let appFileAddedOrRemoved = appDirectory && (event === "add" || event === "unlink") && filepath.startsWith(import_pathe3.default.normalize(appDirectory));
486
- let configCodeUpdated = Boolean(
548
+ let fileAddedOrRemoved = event === "add" || event === "unlink";
549
+ let appFileAddedOrRemoved = fileAddedOrRemoved && filepath.startsWith(import_pathe3.default.normalize(appDirectory));
550
+ let rootRelativeFilepath = import_pathe3.default.relative(root, filepath);
551
+ let configFileAddedOrRemoved = fileAddedOrRemoved && isEntryFile("react-router.config", rootRelativeFilepath);
552
+ if (configFileAddedOrRemoved) {
553
+ updateReactRouterConfigFile();
554
+ }
555
+ let moduleGraphChanged = configFileAddedOrRemoved || Boolean(
487
556
  viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
488
557
  );
489
- if (configCodeUpdated || appFileAddedOrRemoved) {
490
- viteNodeContext.devServer?.moduleGraph.invalidateAll();
491
- viteNodeContext.runner?.moduleCache.clear();
558
+ if (!moduleGraphChanged && !appFileAddedOrRemoved) {
559
+ return;
492
560
  }
493
- if (appFileAddedOrRemoved || configCodeUpdated) {
494
- let result = await getConfig();
495
- let configChanged = result.ok && !(0, import_isEqual.default)(lastConfig, result.value);
496
- let routeConfigChanged = result.ok && !(0, import_isEqual.default)(lastConfig?.routes, result.value.routes);
497
- for (let handler2 of changeHandlers) {
498
- handler2({
499
- result,
500
- configCodeUpdated,
501
- configChanged,
502
- routeConfigChanged,
503
- path: filepath,
504
- event
505
- });
506
- }
507
- if (result.ok) {
508
- lastConfig = result.value;
509
- }
561
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
562
+ viteNodeContext.runner?.moduleCache.clear();
563
+ let result = await getConfig();
564
+ let prevAppDirectory = appDirectory;
565
+ appDirectory = import_pathe3.default.normalize(
566
+ (result.value ?? currentConfig).appDirectory
567
+ );
568
+ if (appDirectory !== prevAppDirectory) {
569
+ fsWatcher.unwatch(prevAppDirectory);
570
+ fsWatcher.add(appDirectory);
571
+ }
572
+ let configCodeChanged = configFileAddedOrRemoved || reactRouterConfigFile !== void 0 && isEntryFileDependency(
573
+ viteNodeContext.devServer.moduleGraph,
574
+ reactRouterConfigFile,
575
+ filepath
576
+ );
577
+ let routeConfigFile = !skipRoutes ? findEntry(appDirectory, "routes", {
578
+ absolute: true
579
+ }) : void 0;
580
+ let routeConfigCodeChanged = routeConfigFile !== void 0 && isEntryFileDependency(
581
+ viteNodeContext.devServer.moduleGraph,
582
+ routeConfigFile,
583
+ filepath
584
+ );
585
+ let configChanged = result.ok && !(0, import_isEqual.default)(omitRoutes(currentConfig), omitRoutes(result.value));
586
+ let routeConfigChanged = result.ok && !(0, import_isEqual.default)(currentConfig?.routes, result.value.routes);
587
+ for (let handler2 of changeHandlers) {
588
+ handler2({
589
+ result,
590
+ configCodeChanged,
591
+ routeConfigCodeChanged,
592
+ configChanged,
593
+ routeConfigChanged,
594
+ path: filepath,
595
+ event
596
+ });
597
+ }
598
+ if (result.ok) {
599
+ currentConfig = result.value;
510
600
  }
511
601
  });
512
602
  }
@@ -523,23 +613,73 @@ async function createConfigLoader({
523
613
  }
524
614
  };
525
615
  }
526
- async function loadConfig({ rootDirectory }) {
616
+ async function loadConfig({
617
+ rootDirectory,
618
+ mode,
619
+ skipRoutes
620
+ }) {
527
621
  let configLoader = await createConfigLoader({
528
622
  rootDirectory,
623
+ mode,
624
+ skipRoutes,
529
625
  watch: false
530
626
  });
531
627
  let config = await configLoader.getConfig();
532
628
  await configLoader.close();
533
629
  return config;
534
630
  }
535
- function findEntry(dir, basename2, options) {
536
- for (let ext of entryExts) {
537
- let file = import_pathe3.default.resolve(dir, basename2 + ext);
538
- if (import_node_fs.default.existsSync(file)) {
539
- return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
631
+ function omitRoutes(config) {
632
+ return {
633
+ ...config,
634
+ routes: {}
635
+ };
636
+ }
637
+ function isEntryFile(entryBasename, filename2) {
638
+ return entryExts.some((ext) => filename2 === `${entryBasename}${ext}`);
639
+ }
640
+ function findEntry(dir, basename3, options) {
641
+ let currentDir = import_pathe3.default.resolve(dir);
642
+ let { root } = import_pathe3.default.parse(currentDir);
643
+ while (true) {
644
+ for (let ext of options?.extensions ?? entryExts) {
645
+ let file = import_pathe3.default.resolve(currentDir, basename3 + ext);
646
+ if (import_node_fs.default.existsSync(file)) {
647
+ return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
648
+ }
540
649
  }
650
+ if (!options?.walkParents) {
651
+ return void 0;
652
+ }
653
+ let parentDir = import_pathe3.default.dirname(currentDir);
654
+ if (currentDir === root || parentDir === currentDir) {
655
+ return void 0;
656
+ }
657
+ currentDir = parentDir;
541
658
  }
542
- return void 0;
659
+ }
660
+ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /* @__PURE__ */ new Set()) {
661
+ entryFilepath = import_pathe3.default.normalize(entryFilepath);
662
+ filepath = import_pathe3.default.normalize(filepath);
663
+ if (visited.has(filepath)) {
664
+ return false;
665
+ }
666
+ visited.add(filepath);
667
+ if (filepath === entryFilepath) {
668
+ return true;
669
+ }
670
+ let mod = moduleGraph.getModuleById(filepath);
671
+ if (!mod) {
672
+ return false;
673
+ }
674
+ for (let importer of mod.importers) {
675
+ if (!importer.id) {
676
+ continue;
677
+ }
678
+ if (importer.id === entryFilepath || isEntryFileDependency(moduleGraph, entryFilepath, importer.id, visited)) {
679
+ return true;
680
+ }
681
+ }
682
+ return false;
543
683
  }
544
684
  var import_node_fs, import_node_child_process, import_package_json, import_pathe3, import_chokidar, import_picocolors, import_pick2, import_omit, import_cloneDeep, import_isEqual, excludedConfigPresetKeys, mergeReactRouterConfig, deepFreeze, entryExts;
545
685
  var init_config = __esm({
@@ -640,6 +780,31 @@ var init_profiler = __esm({
640
780
  }
641
781
  });
642
782
 
783
+ // typegen/context.ts
784
+ async function createContext2({
785
+ rootDirectory,
786
+ watch: watch2,
787
+ mode
788
+ }) {
789
+ const configLoader = await createConfigLoader({ rootDirectory, mode, watch: watch2 });
790
+ const configResult = await configLoader.getConfig();
791
+ if (!configResult.ok) {
792
+ throw new Error(configResult.error);
793
+ }
794
+ const config = configResult.value;
795
+ return {
796
+ configLoader,
797
+ rootDirectory,
798
+ config
799
+ };
800
+ }
801
+ var init_context = __esm({
802
+ "typegen/context.ts"() {
803
+ "use strict";
804
+ init_config();
805
+ }
806
+ });
807
+
643
808
  // vite/babel.ts
644
809
  var babel_exports = {};
645
810
  __export(babel_exports, {
@@ -659,27 +824,6 @@ var init_babel = __esm({
659
824
  }
660
825
  });
661
826
 
662
- // typegen/paths.ts
663
- function getTypesDir(ctx) {
664
- return Path2.join(ctx.rootDirectory, ".react-router/types");
665
- }
666
- function getTypesPath(ctx, route) {
667
- return Path2.join(
668
- getTypesDir(ctx),
669
- Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
670
- Path2.dirname(route.file),
671
- "+types/" + Pathe.filename(route.file) + ".ts"
672
- );
673
- }
674
- var Path2, Pathe;
675
- var init_paths = __esm({
676
- "typegen/paths.ts"() {
677
- "use strict";
678
- Path2 = __toESM(require("pathe"));
679
- Pathe = __toESM(require("pathe/utils"));
680
- }
681
- });
682
-
683
827
  // typegen/params.ts
684
828
  function parse2(fullpath2) {
685
829
  const result = {};
@@ -715,7 +859,7 @@ function lineage(routes2, route) {
715
859
  }
716
860
  function fullpath(lineage2) {
717
861
  if (lineage2.length === 1 && lineage2[0].id === "root") return "/";
718
- return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path9) => path9 !== void 0 && path9 !== "").join("/");
862
+ return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path8) => path8 !== void 0 && path8 !== "").join("/");
719
863
  }
720
864
  var init_route = __esm({
721
865
  "typegen/route.ts"() {
@@ -724,220 +868,354 @@ var init_route = __esm({
724
868
  });
725
869
 
726
870
  // typegen/generate.ts
727
- function generate2(ctx, route) {
871
+ function typesDirectory(ctx) {
872
+ return Path3.join(ctx.rootDirectory, ".react-router/types");
873
+ }
874
+ function generateFuture(ctx) {
875
+ const filename2 = Path3.join(typesDirectory(ctx), "+future.ts");
876
+ const content = import_dedent.default`
877
+ // Generated by React Router
878
+
879
+ import "react-router";
880
+
881
+ declare module "react-router" {
882
+ interface Future {
883
+ unstable_middleware: ${ctx.config.future.unstable_middleware}
884
+ }
885
+ }
886
+ `;
887
+ return { filename: filename2, content };
888
+ }
889
+ function generateServerBuild(ctx) {
890
+ const filename2 = Path3.join(typesDirectory(ctx), "+server-build.d.ts");
891
+ const content = import_dedent.default`
892
+ // Generated by React Router
893
+
894
+ declare module "virtual:react-router/server-build" {
895
+ import { ServerBuild } from "react-router";
896
+ export const assets: ServerBuild["assets"];
897
+ export const assetsBuildDirectory: ServerBuild["assetsBuildDirectory"];
898
+ export const basename: ServerBuild["basename"];
899
+ export const entry: ServerBuild["entry"];
900
+ export const future: ServerBuild["future"];
901
+ export const isSpaMode: ServerBuild["isSpaMode"];
902
+ export const prerender: ServerBuild["prerender"];
903
+ export const publicPath: ServerBuild["publicPath"];
904
+ export const routeDiscovery: ServerBuild["routeDiscovery"];
905
+ export const routes: ServerBuild["routes"];
906
+ export const ssr: ServerBuild["ssr"];
907
+ export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
908
+ }
909
+ `;
910
+ return { filename: filename2, content };
911
+ }
912
+ function generatePages(ctx) {
913
+ const filename2 = Path3.join(typesDirectory(ctx), "+pages.ts");
914
+ const fullpaths = /* @__PURE__ */ new Set();
915
+ Object.values(ctx.config.routes).forEach((route) => {
916
+ if (route.id !== "root" && !route.path) return;
917
+ const lineage2 = lineage(ctx.config.routes, route);
918
+ const fullpath2 = fullpath(lineage2);
919
+ fullpaths.add(fullpath2);
920
+ });
921
+ const pagesType = t2.tsTypeAliasDeclaration(
922
+ t2.identifier("Pages"),
923
+ null,
924
+ t2.tsTypeLiteral(
925
+ Array.from(fullpaths).map((fullpath2) => {
926
+ return t2.tsPropertySignature(
927
+ t2.stringLiteral(fullpath2),
928
+ t2.tsTypeAnnotation(
929
+ t2.tsTypeLiteral([
930
+ t2.tsPropertySignature(
931
+ t2.identifier("params"),
932
+ t2.tsTypeAnnotation(paramsType(fullpath2))
933
+ )
934
+ ])
935
+ )
936
+ );
937
+ })
938
+ )
939
+ );
940
+ const content = import_dedent.default`
941
+ // Generated by React Router
942
+
943
+ import "react-router"
944
+
945
+ declare module "react-router" {
946
+ interface Register {
947
+ pages: Pages
948
+ }
949
+ }
950
+ ` + "\n\n" + generate(pagesType).code;
951
+ return { filename: filename2, content };
952
+ }
953
+ function generateRoutes(ctx) {
954
+ const filename2 = Path3.join(typesDirectory(ctx), "+routes-pre.ts");
955
+ const routesType = t2.tsTypeAliasDeclaration(
956
+ t2.identifier("routesPre"),
957
+ null,
958
+ t2.tsTypeLiteral(
959
+ Object.values(ctx.config.routes).map((route) => {
960
+ return t2.tsPropertySignature(
961
+ t2.stringLiteral(route.id),
962
+ t2.tsTypeAnnotation(
963
+ t2.tsTypeLiteral([
964
+ t2.tsPropertySignature(
965
+ t2.identifier("parentId"),
966
+ t2.tsTypeAnnotation(
967
+ route.parentId ? t2.tsLiteralType(t2.stringLiteral(route.parentId)) : t2.tsUndefinedKeyword()
968
+ )
969
+ ),
970
+ t2.tsPropertySignature(
971
+ t2.identifier("path"),
972
+ t2.tsTypeAnnotation(
973
+ route.path ? t2.tsLiteralType(t2.stringLiteral(route.path)) : t2.tsUndefinedKeyword()
974
+ )
975
+ ),
976
+ t2.tsPropertySignature(
977
+ t2.identifier("params"),
978
+ t2.tsTypeAnnotation(paramsType(route.path ?? ""))
979
+ ),
980
+ t2.tsPropertySignature(
981
+ t2.identifier("index"),
982
+ t2.tsTypeAnnotation(
983
+ t2.tsLiteralType(t2.booleanLiteral(route.index ?? false))
984
+ )
985
+ ),
986
+ t2.tsPropertySignature(
987
+ t2.identifier("file"),
988
+ t2.tsTypeAnnotation(t2.tsLiteralType(t2.stringLiteral(route.file)))
989
+ )
990
+ ])
991
+ )
992
+ );
993
+ })
994
+ )
995
+ );
996
+ const content = import_dedent.default`
997
+ // Generated by React Router
998
+
999
+ import "react-router"
1000
+
1001
+ declare module "react-router" {
1002
+ interface Register {
1003
+ routesPre: routesPre
1004
+ }
1005
+ }
1006
+ ` + "\n\n" + generate(routesType).code;
1007
+ return { filename: filename2, content };
1008
+ }
1009
+ function generateRouteModuleAnnotations(ctx) {
1010
+ return Object.values(ctx.config.routes).map((route) => {
1011
+ const filename2 = getRouteModuleAnnotationsFilepath(ctx, route);
1012
+ const parents = getParents(ctx, route);
1013
+ const content = import_dedent.default`
1014
+ // Generated by React Router
1015
+
1016
+ import type {
1017
+ Params,
1018
+ RouteModuleAnnotations,
1019
+ CreateLoaderData,
1020
+ CreateActionData,
1021
+ } from "react-router/internal";
1022
+
1023
+ ${parents.map((parent) => parent.import).join("\n" + " ".repeat(3))}
1024
+ type Parents = [${parents.map((parent) => parent.name).join(", ")}]
1025
+
1026
+ type Id = "${route.id}"
1027
+ type Module = typeof import("../${Pathe.filename(route.file)}.js")
1028
+
1029
+ export type unstable_Props = {
1030
+ params: Params[Id]
1031
+ loaderData: CreateLoaderData<Module>
1032
+ actionData: CreateActionData<Module>
1033
+ }
1034
+
1035
+ type Annotations = RouteModuleAnnotations<unstable_Props & {
1036
+ parents: Parents,
1037
+ module: Module,
1038
+ }>;
1039
+
1040
+ export namespace Route {
1041
+ // links
1042
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
1043
+ export type LinksFunction = Annotations["LinksFunction"];
1044
+
1045
+ // meta
1046
+ export type MetaArgs = Annotations["MetaArgs"];
1047
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
1048
+ export type MetaFunction = Annotations["MetaFunction"];
1049
+
1050
+ // headers
1051
+ export type HeadersArgs = Annotations["HeadersArgs"];
1052
+ export type HeadersFunction = Annotations["HeadersFunction"];
1053
+
1054
+ // unstable_middleware
1055
+ export type unstable_MiddlewareFunction = Annotations["unstable_MiddlewareFunction"];
1056
+
1057
+ // unstable_clientMiddleware
1058
+ export type unstable_ClientMiddlewareFunction = Annotations["unstable_ClientMiddlewareFunction"];
1059
+
1060
+ // loader
1061
+ export type LoaderArgs = Annotations["LoaderArgs"];
1062
+
1063
+ // clientLoader
1064
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
1065
+
1066
+ // action
1067
+ export type ActionArgs = Annotations["ActionArgs"];
1068
+
1069
+ // clientAction
1070
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
1071
+
1072
+ // HydrateFallback
1073
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
1074
+
1075
+ // Component
1076
+ export type ComponentProps = Annotations["ComponentProps"];
1077
+
1078
+ // ErrorBoundary
1079
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
1080
+ }
1081
+ `;
1082
+ return { filename: filename2, content };
1083
+ });
1084
+ }
1085
+ function getRouteModuleAnnotationsFilepath(ctx, route) {
1086
+ return Path3.join(
1087
+ typesDirectory(ctx),
1088
+ Path3.relative(ctx.rootDirectory, ctx.config.appDirectory),
1089
+ Path3.dirname(route.file),
1090
+ "+types/" + Pathe.filename(route.file) + ".ts"
1091
+ );
1092
+ }
1093
+ function getParents(ctx, route) {
1094
+ const typesPath = getRouteModuleAnnotationsFilepath(ctx, route);
728
1095
  const lineage2 = lineage(ctx.config.routes, route);
729
- const fullpath2 = fullpath(lineage2);
730
- const typesPath = getTypesPath(ctx, route);
731
1096
  const parents = lineage2.slice(0, -1);
732
- const parentTypeImports = parents.map((parent, i) => {
1097
+ return parents.map((parent, i) => {
733
1098
  const rel = Path3.relative(
734
1099
  Path3.dirname(typesPath),
735
- getTypesPath(ctx, parent)
1100
+ getRouteModuleAnnotationsFilepath(ctx, parent)
736
1101
  );
737
- const indent = i === 0 ? "" : " ".repeat(2);
738
1102
  let source = noExtension(rel);
739
1103
  if (!source.startsWith("../")) source = "./" + source;
740
- return `${indent}import type { Info as Parent${i} } from "${source}.js"`;
741
- }).join("\n");
742
- return import_dedent.default`
743
- // React Router generated types for route:
744
- // ${route.file}
745
-
746
- import type * as T from "react-router/route-module"
747
-
748
- ${parentTypeImports}
749
-
750
- type Module = typeof import("../${Pathe2.filename(route.file)}.js")
751
-
752
- export type Info = {
753
- parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
754
- id: "${route.id}"
755
- file: "${route.file}"
756
- path: "${route.path}"
757
- params: {${formatParamProperties(
758
- fullpath2
759
- )}} & { [key: string]: string | undefined }
760
- module: Module
761
- loaderData: T.CreateLoaderData<Module>
762
- actionData: T.CreateActionData<Module>
763
- }
764
-
765
- export namespace Route {
766
- export type LinkDescriptors = T.LinkDescriptors
767
- export type LinksFunction = () => LinkDescriptors
768
-
769
- export type MetaArgs = T.CreateMetaArgs<Info>
770
- export type MetaDescriptors = T.MetaDescriptors
771
- export type MetaFunction = (args: MetaArgs) => MetaDescriptors
772
-
773
- export type HeadersArgs = T.HeadersArgs
774
- export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
775
-
776
- export type unstable_MiddlewareFunction = T.CreateServerMiddlewareFunction<Info>
777
- export type unstable_ClientMiddlewareFunction = T.CreateClientMiddlewareFunction<Info>
778
- export type LoaderArgs = T.CreateServerLoaderArgs<Info>
779
- export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
780
- export type ActionArgs = T.CreateServerActionArgs<Info>
781
- export type ClientActionArgs = T.CreateClientActionArgs<Info>
782
-
783
- export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Info>
784
- export type ComponentProps = T.CreateComponentProps<Info>
785
- export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Info>
786
- }
787
- `;
1104
+ const name = `Parent${i}`;
1105
+ return {
1106
+ name,
1107
+ import: `import type { unstable_Props as ${name} } from "${source}.js"`
1108
+ };
1109
+ });
1110
+ }
1111
+ function noExtension(path8) {
1112
+ return Path3.join(Path3.dirname(path8), Pathe.filename(path8));
788
1113
  }
789
- function formatParamProperties(fullpath2) {
790
- const params = parse2(fullpath2);
791
- const properties = Object.entries(params).map(
792
- ([name, isRequired]) => isRequired ? `"${name}": string` : `"${name}"?: string`
1114
+ function paramsType(path8) {
1115
+ const params = parse2(path8);
1116
+ return t2.tsTypeLiteral(
1117
+ Object.entries(params).map(([param, isRequired]) => {
1118
+ const property = t2.tsPropertySignature(
1119
+ t2.stringLiteral(param),
1120
+ t2.tsTypeAnnotation(t2.tsStringKeyword())
1121
+ );
1122
+ property.optional = !isRequired;
1123
+ return property;
1124
+ })
793
1125
  );
794
- return properties.join("; ");
795
1126
  }
796
- var import_dedent, Path3, Pathe2, noExtension;
1127
+ var import_dedent, Path3, Pathe, t2;
797
1128
  var init_generate = __esm({
798
1129
  "typegen/generate.ts"() {
799
1130
  "use strict";
800
1131
  import_dedent = __toESM(require("dedent"));
801
1132
  Path3 = __toESM(require("pathe"));
802
- Pathe2 = __toESM(require("pathe/utils"));
803
- init_paths();
1133
+ Pathe = __toESM(require("pathe/utils"));
1134
+ init_babel();
804
1135
  init_params();
805
1136
  init_route();
806
- noExtension = (path9) => Path3.join(Path3.dirname(path9), Pathe2.filename(path9));
1137
+ ({ t: t2 } = babel_exports);
807
1138
  }
808
1139
  });
809
1140
 
810
1141
  // typegen/index.ts
811
- async function run(rootDirectory) {
812
- const ctx = await createContext2({ rootDirectory, watch: false });
813
- await writeAll(ctx);
814
- }
815
- async function watch(rootDirectory, { logger } = {}) {
816
- const ctx = await createContext2({ rootDirectory, watch: true });
817
- await writeAll(ctx);
818
- logger?.info(import_picocolors3.default.green("generated types"), { timestamp: true, clear: true });
819
- ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
820
- if (!result.ok) {
821
- logger?.error(import_picocolors3.default.red(result.error), { timestamp: true, clear: true });
822
- return;
823
- }
824
- ctx.config = result.value;
825
- if (routeConfigChanged) {
826
- await writeAll(ctx);
827
- logger?.info(import_picocolors3.default.green("regenerated types"), {
828
- timestamp: true,
829
- clear: true
830
- });
831
- }
832
- });
833
- return {
834
- close: async () => await ctx.configLoader.close()
835
- };
1142
+ async function clearRouteModuleAnnotations(ctx) {
1143
+ await import_promises.default.rm(
1144
+ Path4.join(typesDirectory(ctx), Path4.basename(ctx.config.appDirectory)),
1145
+ { recursive: true, force: true }
1146
+ );
836
1147
  }
837
- async function createContext2({
838
- rootDirectory,
839
- watch: watch2
840
- }) {
841
- const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
842
- const configResult = await configLoader.getConfig();
843
- if (!configResult.ok) {
844
- throw new Error(configResult.error);
845
- }
846
- const config = configResult.value;
847
- return {
848
- configLoader,
849
- rootDirectory,
850
- config
851
- };
1148
+ async function write(...files) {
1149
+ return Promise.all(
1150
+ files.map(async ({ filename: filename2, content }) => {
1151
+ await import_promises.default.mkdir(Path4.dirname(filename2), { recursive: true });
1152
+ await import_promises.default.writeFile(filename2, content);
1153
+ })
1154
+ );
852
1155
  }
853
- async function writeAll(ctx) {
854
- const typegenDir = getTypesDir(ctx);
855
- import_node_fs3.default.rmSync(typegenDir, { recursive: true, force: true });
856
- Object.values(ctx.config.routes).forEach((route) => {
857
- const typesPath = getTypesPath(ctx, route);
858
- const content = generate2(ctx, route);
859
- import_node_fs3.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
860
- import_node_fs3.default.writeFileSync(typesPath, content);
861
- });
862
- const registerPath = Path4.join(typegenDir, "+register.ts");
863
- import_node_fs3.default.writeFileSync(registerPath, register(ctx));
864
- const virtualPath = Path4.join(typegenDir, "+virtual.d.ts");
865
- import_node_fs3.default.writeFileSync(virtualPath, virtual);
1156
+ async function run(rootDirectory, { mode }) {
1157
+ const ctx = await createContext2({ rootDirectory, mode, watch: false });
1158
+ await clearRouteModuleAnnotations(ctx);
1159
+ await write(
1160
+ generateFuture(ctx),
1161
+ generatePages(ctx),
1162
+ generateRoutes(ctx),
1163
+ generateServerBuild(ctx),
1164
+ ...generateRouteModuleAnnotations(ctx)
1165
+ );
866
1166
  }
867
- function register(ctx) {
868
- const register2 = import_dedent2.default`
869
- import "react-router";
870
-
871
- declare module "react-router" {
872
- interface Register {
873
- params: Params;
874
- }
875
- }
876
- `;
877
- const { t: t2 } = babel_exports;
878
- const indexPaths = new Set(
879
- Object.values(ctx.config.routes).filter((route) => route.index).map((route) => route.path)
1167
+ async function watch(rootDirectory, { mode, logger }) {
1168
+ const ctx = await createContext2({ rootDirectory, mode, watch: true });
1169
+ await clearRouteModuleAnnotations(ctx);
1170
+ await write(
1171
+ generateFuture(ctx),
1172
+ generatePages(ctx),
1173
+ generateRoutes(ctx),
1174
+ generateServerBuild(ctx),
1175
+ ...generateRouteModuleAnnotations(ctx)
880
1176
  );
881
- const typeParams = t2.tsTypeAliasDeclaration(
882
- t2.identifier("Params"),
883
- null,
884
- t2.tsTypeLiteral(
885
- Object.values(ctx.config.routes).map((route) => {
886
- if (route.id !== "root" && !route.path) return void 0;
887
- if (!route.index && indexPaths.has(route.path)) return void 0;
888
- const lineage2 = lineage(ctx.config.routes, route);
889
- const fullpath2 = fullpath(lineage2);
890
- const params = parse2(fullpath2);
891
- return t2.tsPropertySignature(
892
- t2.stringLiteral(fullpath2),
893
- t2.tsTypeAnnotation(
894
- t2.tsTypeLiteral(
895
- Object.entries(params).map(([param, isRequired]) => {
896
- const property = t2.tsPropertySignature(
897
- t2.stringLiteral(param),
898
- t2.tsTypeAnnotation(t2.tsStringKeyword())
899
- );
900
- property.optional = !isRequired;
901
- return property;
902
- })
903
- )
904
- )
1177
+ logger?.info((0, import_picocolors3.green)("generated types"), { timestamp: true, clear: true });
1178
+ ctx.configLoader.onChange(
1179
+ async ({ result, configChanged, routeConfigChanged }) => {
1180
+ if (!result.ok) {
1181
+ logger?.error((0, import_picocolors3.red)(result.error), { timestamp: true, clear: true });
1182
+ return;
1183
+ }
1184
+ ctx.config = result.value;
1185
+ if (configChanged) {
1186
+ await write(generateFuture(ctx));
1187
+ logger?.info((0, import_picocolors3.green)("regenerated types"), {
1188
+ timestamp: true,
1189
+ clear: true
1190
+ });
1191
+ }
1192
+ if (routeConfigChanged) {
1193
+ await clearRouteModuleAnnotations(ctx);
1194
+ await write(
1195
+ generatePages(ctx),
1196
+ generateRoutes(ctx),
1197
+ ...generateRouteModuleAnnotations(ctx)
905
1198
  );
906
- }).filter((x) => x !== void 0)
907
- )
1199
+ logger?.info((0, import_picocolors3.green)("regenerated types"), {
1200
+ timestamp: true,
1201
+ clear: true
1202
+ });
1203
+ }
1204
+ }
908
1205
  );
909
- return [register2, generate(typeParams).code].join("\n\n");
1206
+ return {
1207
+ close: async () => await ctx.configLoader.close()
1208
+ };
910
1209
  }
911
- var import_node_fs3, import_dedent2, Path4, import_picocolors3, virtual;
1210
+ var import_promises, Path4, import_picocolors3;
912
1211
  var init_typegen = __esm({
913
1212
  "typegen/index.ts"() {
914
1213
  "use strict";
915
- import_node_fs3 = __toESM(require("fs"));
916
- import_dedent2 = __toESM(require("dedent"));
1214
+ import_promises = __toESM(require("fs/promises"));
917
1215
  Path4 = __toESM(require("pathe"));
918
- import_picocolors3 = __toESM(require("picocolors"));
919
- init_config();
920
- init_babel();
1216
+ import_picocolors3 = require("picocolors");
1217
+ init_context();
921
1218
  init_generate();
922
- init_paths();
923
- init_params();
924
- init_route();
925
- virtual = import_dedent2.default`
926
- declare module "virtual:react-router/server-build" {
927
- import { ServerBuild } from "react-router";
928
- export const assets: ServerBuild["assets"];
929
- export const assetsBuildDirectory: ServerBuild["assetsBuildDirectory"];
930
- export const basename: ServerBuild["basename"];
931
- export const entry: ServerBuild["entry"];
932
- export const future: ServerBuild["future"];
933
- export const isSpaMode: ServerBuild["isSpaMode"];
934
- export const prerender: ServerBuild["prerender"];
935
- export const publicPath: ServerBuild["publicPath"];
936
- export const routes: ServerBuild["routes"];
937
- export const ssr: ServerBuild["ssr"];
938
- export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
939
- }
940
- `;
941
1219
  }
942
1220
  });
943
1221
 
@@ -955,23 +1233,24 @@ var init_node_adapter = __esm({
955
1233
  });
956
1234
 
957
1235
  // vite/resolve-file-url.ts
958
- var path5;
1236
+ var path4;
959
1237
  var init_resolve_file_url = __esm({
960
1238
  "vite/resolve-file-url.ts"() {
961
1239
  "use strict";
962
- path5 = __toESM(require("path"));
1240
+ path4 = __toESM(require("path"));
963
1241
  init_vite();
964
1242
  }
965
1243
  });
966
1244
 
967
1245
  // vite/styles.ts
968
- var path6, import_react_router, cssFileRegExp, cssModulesRegExp;
1246
+ var path5, import_react_router, cssFileRegExp, cssModulesRegExp;
969
1247
  var init_styles = __esm({
970
1248
  "vite/styles.ts"() {
971
1249
  "use strict";
972
- path6 = __toESM(require("path"));
1250
+ path5 = __toESM(require("path"));
973
1251
  import_react_router = require("react-router");
974
1252
  init_resolve_file_url();
1253
+ init_babel();
975
1254
  cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
976
1255
  cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
977
1256
  }
@@ -1065,11 +1344,11 @@ var init_route_chunks = __esm({
1065
1344
  });
1066
1345
 
1067
1346
  // vite/with-props.ts
1068
- var import_dedent3, vmod;
1347
+ var import_dedent2, vmod;
1069
1348
  var init_with_props = __esm({
1070
1349
  "vite/with-props.ts"() {
1071
1350
  "use strict";
1072
- import_dedent3 = __toESM(require("dedent"));
1351
+ import_dedent2 = __toESM(require("dedent"));
1073
1352
  init_babel();
1074
1353
  init_virtual_module();
1075
1354
  vmod = create("with-props");
@@ -1118,8 +1397,8 @@ function getServerBundleIds(ctx) {
1118
1397
  async function cleanBuildDirectory(viteConfig, ctx) {
1119
1398
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
1120
1399
  let isWithinRoot = () => {
1121
- let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
1122
- return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
1400
+ let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
1401
+ return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1123
1402
  };
1124
1403
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1125
1404
  await fse.remove(buildDirectory);
@@ -1130,7 +1409,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1130
1409
  ([environmentName, options]) => {
1131
1410
  let outDir = options.build?.outDir;
1132
1411
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
1133
- return path7.join(outDir, ".vite/manifest.json");
1412
+ return path6.join(outDir, ".vite/manifest.json");
1134
1413
  }
1135
1414
  );
1136
1415
  await Promise.all(
@@ -1140,7 +1419,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1140
1419
  if (!ctx.viteManifestEnabled) {
1141
1420
  await fse.remove(viteManifestPath);
1142
1421
  }
1143
- let viteDir = path7.dirname(viteManifestPath);
1422
+ let viteDir = path6.dirname(viteManifestPath);
1144
1423
  let viteDirFiles = await fse.readdir(viteDir);
1145
1424
  if (viteDirFiles.length === 0) {
1146
1425
  await fse.remove(viteDir);
@@ -1157,10 +1436,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
1157
1436
  }
1158
1437
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1159
1438
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1160
- let packageRoot = path7.dirname(
1439
+ let packageRoot = path6.dirname(
1161
1440
  require.resolve("@react-router/dev/package.json")
1162
1441
  );
1163
- let { moduleSyncEnabled } = await import(`file:///${path7.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1442
+ let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1164
1443
  let vite2 = getVite();
1165
1444
  let viteServerConditions = [
1166
1445
  ...vite2.defaultServerConditions ?? [],
@@ -1217,7 +1496,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1217
1496
  copyPublicDir: false,
1218
1497
  // Assets in the public directory are only used by the client
1219
1498
  rollupOptions: {
1220
- input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual2.serverBuild.id,
1499
+ input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
1221
1500
  output: {
1222
1501
  entryFileNames: serverBuildFile,
1223
1502
  format: serverModuleFormat
@@ -1234,7 +1513,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1234
1513
  ctx.entryClientFilePath,
1235
1514
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
1236
1515
  (route) => {
1237
- let routeFilePath = path7.resolve(
1516
+ let routeFilePath = path6.resolve(
1238
1517
  ctx.reactRouterConfig.appDirectory,
1239
1518
  route.file
1240
1519
  );
@@ -1257,8 +1536,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1257
1536
  ""
1258
1537
  ) : null;
1259
1538
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1260
- return path7.posix.join(
1261
- (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
1539
+ let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1540
+ return path6.posix.join(
1541
+ assetsDir,
1262
1542
  `[name]${routeChunkSuffix}-[hash].js`
1263
1543
  );
1264
1544
  }
@@ -1293,9 +1573,6 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1293
1573
  }
1294
1574
  });
1295
1575
  }
1296
- if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
1297
- environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
1298
- }
1299
1576
  return environmentOptionsResolvers;
1300
1577
  }
1301
1578
  function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
@@ -1310,13 +1587,13 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1310
1587
  function isNonNullable(x) {
1311
1588
  return x != null;
1312
1589
  }
1313
- var import_node_crypto, fs4, path7, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, CLIENT_NON_COMPONENT_EXPORTS, CLIENT_ROUTE_EXPORTS, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, CSS_DEV_HELPER_ENVIRONMENT_NAME, virtualHmrRuntime, virtualInjectHmrRuntime, virtual2, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1590
+ var import_node_crypto, fs4, path6, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, CLIENT_NON_COMPONENT_EXPORTS, CLIENT_ROUTE_EXPORTS, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, virtualHmrRuntime, virtualInjectHmrRuntime, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1314
1591
  var init_plugin = __esm({
1315
1592
  "vite/plugin.ts"() {
1316
1593
  "use strict";
1317
1594
  import_node_crypto = require("crypto");
1318
1595
  fs4 = __toESM(require("fs"));
1319
- path7 = __toESM(require("path"));
1596
+ path6 = __toESM(require("path"));
1320
1597
  url = __toESM(require("url"));
1321
1598
  fse = __toESM(require("fs-extra"));
1322
1599
  babel2 = __toESM(require("@babel/core"));
@@ -1358,27 +1635,26 @@ var init_plugin = __esm({
1358
1635
  ];
1359
1636
  BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1360
1637
  SSR_BUNDLE_PREFIX = "ssrBundle_";
1361
- CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
1362
1638
  virtualHmrRuntime = create("hmr-runtime");
1363
1639
  virtualInjectHmrRuntime = create("inject-hmr-runtime");
1364
- virtual2 = {
1640
+ virtual = {
1365
1641
  serverBuild: create("server-build"),
1366
1642
  serverManifest: create("server-manifest"),
1367
1643
  browserManifest: create("browser-manifest")
1368
1644
  };
1369
- getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1645
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
1370
1646
  reactRouterConfig.buildDirectory,
1371
1647
  "server",
1372
1648
  ...serverBundleId ? [serverBundleId] : []
1373
1649
  );
1374
- getClientBuildDirectory = (reactRouterConfig) => path7.join(reactRouterConfig.buildDirectory, "client");
1375
- defaultEntriesDir = path7.resolve(
1376
- path7.dirname(require.resolve("@react-router/dev/package.json")),
1650
+ getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
1651
+ defaultEntriesDir = path6.resolve(
1652
+ path6.dirname(require.resolve("@react-router/dev/package.json")),
1377
1653
  "dist",
1378
1654
  "config",
1379
1655
  "defaults"
1380
1656
  );
1381
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path7.join(defaultEntriesDir, filename3));
1657
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename2) => path6.join(defaultEntriesDir, filename2));
1382
1658
  invariant(defaultEntries.length > 0, "No default entries found");
1383
1659
  REACT_REFRESH_HEADER = `
1384
1660
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1412,7 +1688,13 @@ __export(build_exports, {
1412
1688
  async function build(root, viteBuildOptions) {
1413
1689
  await preloadVite();
1414
1690
  let vite2 = getVite();
1415
- let configResult = await loadConfig({ rootDirectory: root });
1691
+ let configResult = await loadConfig({
1692
+ rootDirectory: root,
1693
+ mode: viteBuildOptions.mode ?? "production",
1694
+ // In this scope we only need future flags, so we can skip evaluating
1695
+ // routes.ts until we're within the Vite build context
1696
+ skipRoutes: true
1697
+ });
1416
1698
  if (!configResult.ok) {
1417
1699
  throw new Error(configResult.error);
1418
1700
  }
@@ -1652,7 +1934,7 @@ var import_semver = __toESM(require("semver"));
1652
1934
  var import_picocolors8 = __toESM(require("picocolors"));
1653
1935
 
1654
1936
  // cli/commands.ts
1655
- var path8 = __toESM(require("path"));
1937
+ var path7 = __toESM(require("path"));
1656
1938
  var import_fs_extra = __toESM(require("fs-extra"));
1657
1939
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
1658
1940
  var import_exit_hook = __toESM(require("exit-hook"));
@@ -1738,9 +2020,12 @@ function transpile(tsx, options = {}) {
1738
2020
  init_profiler();
1739
2021
  init_typegen();
1740
2022
  init_vite();
1741
- async function routes(reactRouterRoot, flags = {}) {
1742
- let rootDirectory = reactRouterRoot ?? process.cwd();
1743
- let configResult = await loadConfig({ rootDirectory });
2023
+ async function routes(rootDirectory, flags = {}) {
2024
+ rootDirectory = resolveRootDirectory(rootDirectory, flags);
2025
+ let configResult = await loadConfig({
2026
+ rootDirectory,
2027
+ mode: flags.mode ?? "production"
2028
+ });
1744
2029
  if (!configResult.ok) {
1745
2030
  console.error(import_picocolors7.default.red(configResult.error));
1746
2031
  process.exit(1);
@@ -1749,9 +2034,7 @@ async function routes(reactRouterRoot, flags = {}) {
1749
2034
  console.log(formatRoutes(configResult.value.routes, format));
1750
2035
  }
1751
2036
  async function build2(root, options = {}) {
1752
- if (!root) {
1753
- root = process.env.REACT_ROUTER_ROOT || process.cwd();
1754
- }
2037
+ root = resolveRootDirectory(root, options);
1755
2038
  let { build: build3 } = await Promise.resolve().then(() => (init_build(), build_exports));
1756
2039
  if (options.profile) {
1757
2040
  await start();
@@ -1768,6 +2051,7 @@ async function dev2(root, options = {}) {
1768
2051
  await start();
1769
2052
  }
1770
2053
  (0, import_exit_hook.default)(() => stop(console.info));
2054
+ root = resolveRootDirectory(root, options);
1771
2055
  await dev3(root, options);
1772
2056
  await new Promise(() => {
1773
2057
  });
@@ -1779,14 +2063,17 @@ var conjunctionListFormat = new Intl.ListFormat("en", {
1779
2063
  style: "long",
1780
2064
  type: "conjunction"
1781
2065
  });
1782
- async function generateEntry(entry, reactRouterRoot, flags = {}) {
2066
+ async function generateEntry(entry, rootDirectory, flags = {}) {
1783
2067
  if (!entry) {
1784
- await generateEntry("entry.client", reactRouterRoot, flags);
1785
- await generateEntry("entry.server", reactRouterRoot, flags);
2068
+ await generateEntry("entry.client", rootDirectory, flags);
2069
+ await generateEntry("entry.server", rootDirectory, flags);
1786
2070
  return;
1787
2071
  }
1788
- let rootDirectory = reactRouterRoot ?? process.cwd();
1789
- let configResult = await loadConfig({ rootDirectory });
2072
+ rootDirectory = resolveRootDirectory(rootDirectory, flags);
2073
+ let configResult = await loadConfig({
2074
+ rootDirectory,
2075
+ mode: flags.mode ?? "production"
2076
+ });
1790
2077
  if (!configResult.ok) {
1791
2078
  console.error(import_picocolors7.default.red(configResult.error));
1792
2079
  return;
@@ -1806,14 +2093,14 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1806
2093
  console.error(import_picocolors7.default.red(`No default server entry detected.`));
1807
2094
  return;
1808
2095
  }
1809
- let defaultsDirectory = path8.resolve(
1810
- path8.dirname(require.resolve("@react-router/dev/package.json")),
2096
+ let defaultsDirectory = path7.resolve(
2097
+ path7.dirname(require.resolve("@react-router/dev/package.json")),
1811
2098
  "dist",
1812
2099
  "config",
1813
2100
  "defaults"
1814
2101
  );
1815
- let defaultEntryClient = path8.resolve(defaultsDirectory, "entry.client.tsx");
1816
- let defaultEntryServer = path8.resolve(
2102
+ let defaultEntryClient = path7.resolve(defaultsDirectory, "entry.client.tsx");
2103
+ let defaultEntryServer = path7.resolve(
1817
2104
  defaultsDirectory,
1818
2105
  `entry.server.node.tsx`
1819
2106
  );
@@ -1822,7 +2109,7 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1822
2109
  let useTypeScript = flags.typescript ?? true;
1823
2110
  let outputExtension = useTypeScript ? "tsx" : "jsx";
1824
2111
  let outputEntry = `${entry}.${outputExtension}`;
1825
- let outputFile2 = path8.resolve(appDirectory, outputEntry);
2112
+ let outputFile2 = path7.resolve(appDirectory, outputEntry);
1826
2113
  if (!useTypeScript) {
1827
2114
  let javascript = transpile(contents, {
1828
2115
  cwd: rootDirectory,
@@ -1834,20 +2121,26 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1834
2121
  }
1835
2122
  console.log(
1836
2123
  import_picocolors7.default.blue(
1837
- `Entry file ${entry} created at ${path8.relative(
2124
+ `Entry file ${entry} created at ${path7.relative(
1838
2125
  rootDirectory,
1839
2126
  outputFile2
1840
2127
  )}.`
1841
2128
  )
1842
2129
  );
1843
2130
  }
2131
+ function resolveRootDirectory(root, flags) {
2132
+ if (root) {
2133
+ return path7.resolve(root);
2134
+ }
2135
+ return process.env.REACT_ROUTER_ROOT || (flags?.config ? path7.dirname(path7.resolve(flags.config)) : process.cwd());
2136
+ }
1844
2137
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
1845
2138
  for (let entry of entries2) {
1846
- let entryPath = path8.resolve(appDirectory, entry);
2139
+ let entryPath = path7.resolve(appDirectory, entry);
1847
2140
  let exists = await import_fs_extra.default.pathExists(entryPath);
1848
2141
  if (exists) {
1849
- let relative8 = path8.relative(rootDirectory, entryPath);
1850
- console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
2142
+ let relative7 = path7.relative(rootDirectory, entryPath);
2143
+ console.error(import_picocolors7.default.red(`Entry file ${relative7} already exists.`));
1851
2144
  return process.exit(1);
1852
2145
  }
1853
2146
  }
@@ -1863,17 +2156,22 @@ async function createClientEntry(rootDirectory, appDirectory, inputFile) {
1863
2156
  return contents;
1864
2157
  }
1865
2158
  async function typegen(root, flags) {
1866
- root ??= process.cwd();
2159
+ root = resolveRootDirectory(root, flags);
1867
2160
  if (flags.watch) {
1868
2161
  await preloadVite();
1869
2162
  const vite2 = getVite();
1870
2163
  const logger = vite2.createLogger("info", { prefix: "[react-router]" });
1871
- await watch(root, { logger });
2164
+ await watch(root, {
2165
+ mode: flags.mode ?? "development",
2166
+ logger
2167
+ });
1872
2168
  await new Promise(() => {
1873
2169
  });
1874
2170
  return;
1875
2171
  }
1876
- await run(root);
2172
+ await run(root, {
2173
+ mode: flags.mode ?? "production"
2174
+ });
1877
2175
  }
1878
2176
 
1879
2177
  // cli/run.ts