@react-router/dev 0.0.0-experimental-ab0e85b04 → 0.0.0-experimental-e56aa53bc

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-ab0e85b04
3
+ * @react-router/dev v0.0.0-experimental-e56aa53bc
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -125,15 +125,13 @@ var init_ssr_externals = __esm({
125
125
  // vite/vite-node.ts
126
126
  async function createContext({
127
127
  root,
128
- mode,
129
- customLogger
128
+ mode
130
129
  }) {
131
130
  await preloadVite();
132
131
  const vite2 = getVite();
133
132
  const devServer = await vite2.createServer({
134
133
  root,
135
134
  mode,
136
- customLogger,
137
135
  server: {
138
136
  preTransformRequests: false,
139
137
  hmr: false,
@@ -145,15 +143,6 @@ async function createContext({
145
143
  optimizeDeps: {
146
144
  noDiscovery: true
147
145
  },
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
- },
157
146
  configFile: false,
158
147
  envFile: false,
159
148
  plugins: []
@@ -216,7 +205,7 @@ function validateRouteConfig({
216
205
  `Route config in "${routeConfigFile}" is invalid.`,
217
206
  root ? `${root}` : [],
218
207
  nested ? Object.entries(nested).map(
219
- ([path8, message]) => `Path: routes.${path8}
208
+ ([path9, message]) => `Path: routes.${path9}
220
209
  ${message}`
221
210
  ) : []
222
211
  ].flat().join("\n\n")
@@ -301,8 +290,7 @@ function err(error) {
301
290
  async function resolveConfig({
302
291
  root,
303
292
  viteNodeContext,
304
- reactRouterConfigFile,
305
- skipRoutes
293
+ reactRouterConfigFile
306
294
  }) {
307
295
  let reactRouterUserConfig = {};
308
296
  if (reactRouterConfigFile) {
@@ -351,17 +339,12 @@ async function resolveConfig({
351
339
  serverModuleFormat: "esm",
352
340
  ssr: true
353
341
  };
354
- let userAndPresetConfigs = mergeReactRouterConfig(
355
- ...presets,
356
- reactRouterUserConfig
357
- );
358
342
  let {
359
343
  appDirectory: userAppDirectory,
360
344
  basename: basename2,
361
345
  buildDirectory: userBuildDirectory,
362
346
  buildEnd,
363
347
  prerender,
364
- routeDiscovery: userRouteDiscovery,
365
348
  serverBuildFile,
366
349
  serverBundles,
367
350
  serverModuleFormat,
@@ -369,7 +352,7 @@ async function resolveConfig({
369
352
  } = {
370
353
  ...defaults,
371
354
  // Default values should be completely overridden by user/preset config, not merged
372
- ...userAndPresetConfigs
355
+ ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
373
356
  };
374
357
  if (!ssr && serverBundles) {
375
358
  serverBundles = void 0;
@@ -380,32 +363,6 @@ async function resolveConfig({
380
363
  "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
381
364
  );
382
365
  }
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
- }
409
366
  let appDirectory = import_pathe3.default.resolve(root, userAppDirectory || "app");
410
367
  let buildDirectory = import_pathe3.default.resolve(root, userBuildDirectory);
411
368
  let rootRouteFile = findEntry(appDirectory, "root");
@@ -418,50 +375,45 @@ async function resolveConfig({
418
375
  `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
419
376
  );
420
377
  }
421
- let routes2 = {};
422
- if (!skipRoutes) {
423
- routes2 = {
424
- root: { path: "", id: "root", file: rootRouteFile }
425
- };
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")
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")
463
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);
464
401
  }
402
+ routes2 = {
403
+ ...routes2,
404
+ ...configRoutesToRouteManifest(appDirectory, routeConfig)
405
+ };
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
+ );
465
417
  }
466
418
  let future = {
467
419
  unstable_middleware: reactRouterUserConfig.future?.unstable_middleware ?? false,
@@ -478,7 +430,6 @@ async function resolveConfig({
478
430
  future,
479
431
  prerender,
480
432
  routes: routes2,
481
- routeDiscovery,
482
433
  serverBuildFile,
483
434
  serverBundles,
484
435
  serverModuleFormat,
@@ -491,35 +442,24 @@ async function resolveConfig({
491
442
  }
492
443
  async function createConfigLoader({
493
444
  rootDirectory: root,
494
- watch: watch2,
495
- mode,
496
- skipRoutes
445
+ watch: watch2
497
446
  }) {
498
- root = import_pathe3.default.normalize(root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd());
499
- let vite2 = await import("vite");
447
+ root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
500
448
  let viteNodeContext = await createContext({
501
449
  root,
502
- mode,
503
- // Filter out any info level logs from vite-node
504
- customLogger: vite2.createLogger("warn", {
505
- prefix: "[react-router]"
506
- })
450
+ mode: watch2 ? "development" : "production"
507
451
  });
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 });
452
+ let reactRouterConfigFile = findEntry(root, "react-router.config", {
453
+ absolute: true
454
+ });
455
+ let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
516
456
  let appDirectory;
517
457
  let initialConfigResult = await getConfig();
518
458
  if (!initialConfigResult.ok) {
519
459
  throw new Error(initialConfigResult.error);
520
460
  }
521
- appDirectory = import_pathe3.default.normalize(initialConfigResult.value.appDirectory);
522
- let currentConfig = initialConfigResult.value;
461
+ appDirectory = initialConfigResult.value.appDirectory;
462
+ let lastConfig = initialConfigResult.value;
523
463
  let fsWatcher;
524
464
  let changeHandlers = [];
525
465
  return {
@@ -532,71 +472,41 @@ async function createConfigLoader({
532
472
  }
533
473
  changeHandlers.push(handler);
534
474
  if (!fsWatcher) {
535
- fsWatcher = import_chokidar.default.watch([root, appDirectory], {
536
- ignoreInitial: true,
537
- ignored: (path8) => {
538
- let dirname6 = import_pathe3.default.dirname(path8);
539
- return !dirname6.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
- dirname6 !== root;
543
- }
544
- });
475
+ fsWatcher = import_chokidar.default.watch(
476
+ [
477
+ ...reactRouterConfigFile ? [reactRouterConfigFile] : [],
478
+ appDirectory
479
+ ],
480
+ { ignoreInitial: true }
481
+ );
545
482
  fsWatcher.on("all", async (...args) => {
546
483
  let [event, rawFilepath] = args;
547
484
  let filepath = import_pathe3.default.normalize(rawFilepath);
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(
485
+ let appFileAddedOrRemoved = appDirectory && (event === "add" || event === "unlink") && filepath.startsWith(import_pathe3.default.normalize(appDirectory));
486
+ let configCodeUpdated = Boolean(
556
487
  viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
557
488
  );
558
- if (!moduleGraphChanged && !appFileAddedOrRemoved) {
559
- return;
560
- }
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);
489
+ if (configCodeUpdated || appFileAddedOrRemoved) {
490
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
491
+ viteNodeContext.runner?.moduleCache.clear();
571
492
  }
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;
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
+ }
600
510
  }
601
511
  });
602
512
  }
@@ -613,73 +523,23 @@ async function createConfigLoader({
613
523
  }
614
524
  };
615
525
  }
616
- async function loadConfig({
617
- rootDirectory,
618
- mode,
619
- skipRoutes
620
- }) {
526
+ async function loadConfig({ rootDirectory }) {
621
527
  let configLoader = await createConfigLoader({
622
528
  rootDirectory,
623
- mode,
624
- skipRoutes,
625
529
  watch: false
626
530
  });
627
531
  let config = await configLoader.getConfig();
628
532
  await configLoader.close();
629
533
  return config;
630
534
  }
631
- function omitRoutes(config) {
632
- return {
633
- ...config,
634
- routes: {}
635
- };
636
- }
637
- function isEntryFile(entryBasename, filename3) {
638
- return entryExts.some((ext) => filename3 === `${entryBasename}${ext}`);
639
- }
640
535
  function findEntry(dir, basename2, 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, basename2 + ext);
646
- if (import_node_fs.default.existsSync(file)) {
647
- return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
648
- }
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;
658
- }
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;
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);
680
540
  }
681
541
  }
682
- return false;
542
+ return void 0;
683
543
  }
684
544
  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;
685
545
  var init_config = __esm({
@@ -801,21 +661,21 @@ var init_babel = __esm({
801
661
 
802
662
  // typegen/paths.ts
803
663
  function getTypesDir(ctx) {
804
- return Path3.join(ctx.rootDirectory, ".react-router/types");
664
+ return Path2.join(ctx.rootDirectory, ".react-router/types");
805
665
  }
806
666
  function getTypesPath(ctx, route) {
807
- return Path3.join(
667
+ return Path2.join(
808
668
  getTypesDir(ctx),
809
- Path3.relative(ctx.rootDirectory, ctx.config.appDirectory),
810
- Path3.dirname(route.file),
669
+ Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
670
+ Path2.dirname(route.file),
811
671
  "+types/" + Pathe.filename(route.file) + ".ts"
812
672
  );
813
673
  }
814
- var Path3, Pathe;
674
+ var Path2, Pathe;
815
675
  var init_paths = __esm({
816
676
  "typegen/paths.ts"() {
817
677
  "use strict";
818
- Path3 = __toESM(require("pathe"));
678
+ Path2 = __toESM(require("pathe"));
819
679
  Pathe = __toESM(require("pathe/utils"));
820
680
  }
821
681
  });
@@ -855,7 +715,7 @@ function lineage(routes2, route) {
855
715
  }
856
716
  function fullpath(lineage2) {
857
717
  if (lineage2.length === 1 && lineage2[0].id === "root") return "/";
858
- return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path8) => path8 !== void 0 && path8 !== "").join("/");
718
+ return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path9) => path9 !== void 0 && path9 !== "").join("/");
859
719
  }
860
720
  var init_route = __esm({
861
721
  "typegen/route.ts"() {
@@ -870,8 +730,8 @@ function generate2(ctx, route) {
870
730
  const typesPath = getTypesPath(ctx, route);
871
731
  const parents = lineage2.slice(0, -1);
872
732
  const parentTypeImports = parents.map((parent, i) => {
873
- const rel = Path4.relative(
874
- Path4.dirname(typesPath),
733
+ const rel = Path3.relative(
734
+ Path3.dirname(typesPath),
875
735
  getTypesPath(ctx, parent)
876
736
  );
877
737
  const indent = i === 0 ? "" : " ".repeat(2);
@@ -933,55 +793,52 @@ function formatParamProperties(fullpath2) {
933
793
  );
934
794
  return properties.join("; ");
935
795
  }
936
- var import_dedent, Path4, Pathe2, noExtension;
796
+ var import_dedent, Path3, Pathe2, noExtension;
937
797
  var init_generate = __esm({
938
798
  "typegen/generate.ts"() {
939
799
  "use strict";
940
800
  import_dedent = __toESM(require("dedent"));
941
- Path4 = __toESM(require("pathe"));
801
+ Path3 = __toESM(require("pathe"));
942
802
  Pathe2 = __toESM(require("pathe/utils"));
943
803
  init_paths();
944
804
  init_params();
945
805
  init_route();
946
- noExtension = (path8) => Path4.join(Path4.dirname(path8), Pathe2.filename(path8));
806
+ noExtension = (path9) => Path3.join(Path3.dirname(path9), Pathe2.filename(path9));
947
807
  }
948
808
  });
949
809
 
950
810
  // typegen/index.ts
951
- async function run(rootDirectory, { mode }) {
952
- const ctx = await createContext2({ rootDirectory, mode, watch: false });
811
+ async function run(rootDirectory) {
812
+ const ctx = await createContext2({ rootDirectory, watch: false });
953
813
  await writeAll(ctx);
954
814
  }
955
- async function watch(rootDirectory, { mode, logger }) {
956
- const ctx = await createContext2({ rootDirectory, mode, watch: true });
815
+ async function watch(rootDirectory, { logger } = {}) {
816
+ const ctx = await createContext2({ rootDirectory, watch: true });
957
817
  await writeAll(ctx);
958
818
  logger?.info(import_picocolors3.default.green("generated types"), { timestamp: true, clear: true });
959
- ctx.configLoader.onChange(
960
- async ({ result, configChanged, routeConfigChanged }) => {
961
- if (!result.ok) {
962
- logger?.error(import_picocolors3.default.red(result.error), { timestamp: true, clear: true });
963
- return;
964
- }
965
- ctx.config = result.value;
966
- if (configChanged || routeConfigChanged) {
967
- await writeAll(ctx);
968
- logger?.info(import_picocolors3.default.green("regenerated types"), {
969
- timestamp: true,
970
- clear: true
971
- });
972
- }
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;
973
823
  }
974
- );
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
+ });
975
833
  return {
976
834
  close: async () => await ctx.configLoader.close()
977
835
  };
978
836
  }
979
837
  async function createContext2({
980
838
  rootDirectory,
981
- watch: watch2,
982
- mode
839
+ watch: watch2
983
840
  }) {
984
- const configLoader = await createConfigLoader({ rootDirectory, mode, watch: watch2 });
841
+ const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
985
842
  const configResult = await configLoader.getConfig();
986
843
  if (!configResult.ok) {
987
844
  throw new Error(configResult.error);
@@ -999,12 +856,12 @@ async function writeAll(ctx) {
999
856
  Object.values(ctx.config.routes).forEach((route) => {
1000
857
  const typesPath = getTypesPath(ctx, route);
1001
858
  const content = generate2(ctx, route);
1002
- import_node_fs3.default.mkdirSync(Path5.dirname(typesPath), { recursive: true });
859
+ import_node_fs3.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
1003
860
  import_node_fs3.default.writeFileSync(typesPath, content);
1004
861
  });
1005
- const registerPath = Path5.join(typegenDir, "+register.ts");
862
+ const registerPath = Path4.join(typegenDir, "+register.ts");
1006
863
  import_node_fs3.default.writeFileSync(registerPath, register(ctx));
1007
- const virtualPath = Path5.join(typegenDir, "+virtual.d.ts");
864
+ const virtualPath = Path4.join(typegenDir, "+virtual.d.ts");
1008
865
  import_node_fs3.default.writeFileSync(virtualPath, virtual);
1009
866
  }
1010
867
  function register(ctx) {
@@ -1015,25 +872,21 @@ function register(ctx) {
1015
872
  interface Register {
1016
873
  params: Params;
1017
874
  }
1018
-
1019
- interface Future {
1020
- unstable_middleware: ${ctx.config.future.unstable_middleware}
1021
- }
1022
875
  }
1023
876
  `;
1024
877
  const { t: t2 } = babel_exports;
1025
- const fullpaths = /* @__PURE__ */ new Set();
1026
- Object.values(ctx.config.routes).forEach((route) => {
1027
- if (route.id !== "root" && !route.path) return;
1028
- const lineage2 = lineage(ctx.config.routes, route);
1029
- const fullpath2 = fullpath(lineage2);
1030
- fullpaths.add(fullpath2);
1031
- });
878
+ const indexPaths = new Set(
879
+ Object.values(ctx.config.routes).filter((route) => route.index).map((route) => route.path)
880
+ );
1032
881
  const typeParams = t2.tsTypeAliasDeclaration(
1033
882
  t2.identifier("Params"),
1034
883
  null,
1035
884
  t2.tsTypeLiteral(
1036
- Array.from(fullpaths).map((fullpath2) => {
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);
1037
890
  const params = parse2(fullpath2);
1038
891
  return t2.tsPropertySignature(
1039
892
  t2.stringLiteral(fullpath2),
@@ -1050,18 +903,18 @@ function register(ctx) {
1050
903
  )
1051
904
  )
1052
905
  );
1053
- })
906
+ }).filter((x) => x !== void 0)
1054
907
  )
1055
908
  );
1056
909
  return [register2, generate(typeParams).code].join("\n\n");
1057
910
  }
1058
- var import_node_fs3, import_dedent2, Path5, import_picocolors3, virtual;
911
+ var import_node_fs3, import_dedent2, Path4, import_picocolors3, virtual;
1059
912
  var init_typegen = __esm({
1060
913
  "typegen/index.ts"() {
1061
914
  "use strict";
1062
915
  import_node_fs3 = __toESM(require("fs"));
1063
916
  import_dedent2 = __toESM(require("dedent"));
1064
- Path5 = __toESM(require("pathe"));
917
+ Path4 = __toESM(require("pathe"));
1065
918
  import_picocolors3 = __toESM(require("picocolors"));
1066
919
  init_config();
1067
920
  init_babel();
@@ -1080,7 +933,6 @@ var init_typegen = __esm({
1080
933
  export const isSpaMode: ServerBuild["isSpaMode"];
1081
934
  export const prerender: ServerBuild["prerender"];
1082
935
  export const publicPath: ServerBuild["publicPath"];
1083
- export const routeDiscovery: ServerBuild["routeDiscovery"];
1084
936
  export const routes: ServerBuild["routes"];
1085
937
  export const ssr: ServerBuild["ssr"];
1086
938
  export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
@@ -1103,24 +955,23 @@ var init_node_adapter = __esm({
1103
955
  });
1104
956
 
1105
957
  // vite/resolve-file-url.ts
1106
- var path4;
958
+ var path5;
1107
959
  var init_resolve_file_url = __esm({
1108
960
  "vite/resolve-file-url.ts"() {
1109
961
  "use strict";
1110
- path4 = __toESM(require("path"));
962
+ path5 = __toESM(require("path"));
1111
963
  init_vite();
1112
964
  }
1113
965
  });
1114
966
 
1115
967
  // vite/styles.ts
1116
- var path5, import_react_router, cssFileRegExp, cssModulesRegExp;
968
+ var path6, import_react_router, cssFileRegExp, cssModulesRegExp;
1117
969
  var init_styles = __esm({
1118
970
  "vite/styles.ts"() {
1119
971
  "use strict";
1120
- path5 = __toESM(require("path"));
972
+ path6 = __toESM(require("path"));
1121
973
  import_react_router = require("react-router");
1122
974
  init_resolve_file_url();
1123
- init_babel();
1124
975
  cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
1125
976
  cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
1126
977
  }
@@ -1267,8 +1118,8 @@ function getServerBundleIds(ctx) {
1267
1118
  async function cleanBuildDirectory(viteConfig, ctx) {
1268
1119
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
1269
1120
  let isWithinRoot = () => {
1270
- let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
1271
- return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1121
+ let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
1122
+ return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
1272
1123
  };
1273
1124
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1274
1125
  await fse.remove(buildDirectory);
@@ -1279,7 +1130,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1279
1130
  ([environmentName, options]) => {
1280
1131
  let outDir = options.build?.outDir;
1281
1132
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
1282
- return path6.join(outDir, ".vite/manifest.json");
1133
+ return path7.join(outDir, ".vite/manifest.json");
1283
1134
  }
1284
1135
  );
1285
1136
  await Promise.all(
@@ -1289,7 +1140,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1289
1140
  if (!ctx.viteManifestEnabled) {
1290
1141
  await fse.remove(viteManifestPath);
1291
1142
  }
1292
- let viteDir = path6.dirname(viteManifestPath);
1143
+ let viteDir = path7.dirname(viteManifestPath);
1293
1144
  let viteDirFiles = await fse.readdir(viteDir);
1294
1145
  if (viteDirFiles.length === 0) {
1295
1146
  await fse.remove(viteDir);
@@ -1306,10 +1157,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
1306
1157
  }
1307
1158
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1308
1159
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1309
- let packageRoot = path6.dirname(
1160
+ let packageRoot = path7.dirname(
1310
1161
  require.resolve("@react-router/dev/package.json")
1311
1162
  );
1312
- let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1163
+ let { moduleSyncEnabled } = await import(`file:///${path7.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1313
1164
  let vite2 = getVite();
1314
1165
  let viteServerConditions = [
1315
1166
  ...vite2.defaultServerConditions ?? [],
@@ -1383,7 +1234,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1383
1234
  ctx.entryClientFilePath,
1384
1235
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
1385
1236
  (route) => {
1386
- let routeFilePath = path6.resolve(
1237
+ let routeFilePath = path7.resolve(
1387
1238
  ctx.reactRouterConfig.appDirectory,
1388
1239
  route.file
1389
1240
  );
@@ -1406,9 +1257,8 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1406
1257
  ""
1407
1258
  ) : null;
1408
1259
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1409
- let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1410
- return path6.posix.join(
1411
- assetsDir,
1260
+ return path7.posix.join(
1261
+ (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
1412
1262
  `[name]${routeChunkSuffix}-[hash].js`
1413
1263
  );
1414
1264
  }
@@ -1443,6 +1293,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1443
1293
  }
1444
1294
  });
1445
1295
  }
1296
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
1297
+ environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
1298
+ }
1446
1299
  return environmentOptionsResolvers;
1447
1300
  }
1448
1301
  function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
@@ -1457,13 +1310,13 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1457
1310
  function isNonNullable(x) {
1458
1311
  return x != null;
1459
1312
  }
1460
- 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, virtual2, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
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;
1461
1314
  var init_plugin = __esm({
1462
1315
  "vite/plugin.ts"() {
1463
1316
  "use strict";
1464
1317
  import_node_crypto = require("crypto");
1465
1318
  fs4 = __toESM(require("fs"));
1466
- path6 = __toESM(require("path"));
1319
+ path7 = __toESM(require("path"));
1467
1320
  url = __toESM(require("url"));
1468
1321
  fse = __toESM(require("fs-extra"));
1469
1322
  babel2 = __toESM(require("@babel/core"));
@@ -1505,6 +1358,7 @@ var init_plugin = __esm({
1505
1358
  ];
1506
1359
  BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1507
1360
  SSR_BUNDLE_PREFIX = "ssrBundle_";
1361
+ CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
1508
1362
  virtualHmrRuntime = create("hmr-runtime");
1509
1363
  virtualInjectHmrRuntime = create("inject-hmr-runtime");
1510
1364
  virtual2 = {
@@ -1512,19 +1366,19 @@ var init_plugin = __esm({
1512
1366
  serverManifest: create("server-manifest"),
1513
1367
  browserManifest: create("browser-manifest")
1514
1368
  };
1515
- getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
1369
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1516
1370
  reactRouterConfig.buildDirectory,
1517
1371
  "server",
1518
1372
  ...serverBundleId ? [serverBundleId] : []
1519
1373
  );
1520
- getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
1521
- defaultEntriesDir = path6.resolve(
1522
- path6.dirname(require.resolve("@react-router/dev/package.json")),
1374
+ getClientBuildDirectory = (reactRouterConfig) => path7.join(reactRouterConfig.buildDirectory, "client");
1375
+ defaultEntriesDir = path7.resolve(
1376
+ path7.dirname(require.resolve("@react-router/dev/package.json")),
1523
1377
  "dist",
1524
1378
  "config",
1525
1379
  "defaults"
1526
1380
  );
1527
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path6.join(defaultEntriesDir, filename3));
1381
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path7.join(defaultEntriesDir, filename3));
1528
1382
  invariant(defaultEntries.length > 0, "No default entries found");
1529
1383
  REACT_REFRESH_HEADER = `
1530
1384
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1558,13 +1412,7 @@ __export(build_exports, {
1558
1412
  async function build(root, viteBuildOptions) {
1559
1413
  await preloadVite();
1560
1414
  let vite2 = getVite();
1561
- let configResult = await loadConfig({
1562
- rootDirectory: root,
1563
- mode: viteBuildOptions.mode ?? "production",
1564
- // In this scope we only need future flags, so we can skip evaluating
1565
- // routes.ts until we're within the Vite build context
1566
- skipRoutes: true
1567
- });
1415
+ let configResult = await loadConfig({ rootDirectory: root });
1568
1416
  if (!configResult.ok) {
1569
1417
  throw new Error(configResult.error);
1570
1418
  }
@@ -1804,7 +1652,7 @@ var import_semver = __toESM(require("semver"));
1804
1652
  var import_picocolors8 = __toESM(require("picocolors"));
1805
1653
 
1806
1654
  // cli/commands.ts
1807
- var path7 = __toESM(require("path"));
1655
+ var path8 = __toESM(require("path"));
1808
1656
  var import_fs_extra = __toESM(require("fs-extra"));
1809
1657
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
1810
1658
  var import_exit_hook = __toESM(require("exit-hook"));
@@ -1890,12 +1738,9 @@ function transpile(tsx, options = {}) {
1890
1738
  init_profiler();
1891
1739
  init_typegen();
1892
1740
  init_vite();
1893
- async function routes(rootDirectory, flags = {}) {
1894
- rootDirectory = resolveRootDirectory(rootDirectory, flags);
1895
- let configResult = await loadConfig({
1896
- rootDirectory,
1897
- mode: flags.mode ?? "production"
1898
- });
1741
+ async function routes(reactRouterRoot, flags = {}) {
1742
+ let rootDirectory = reactRouterRoot ?? process.cwd();
1743
+ let configResult = await loadConfig({ rootDirectory });
1899
1744
  if (!configResult.ok) {
1900
1745
  console.error(import_picocolors7.default.red(configResult.error));
1901
1746
  process.exit(1);
@@ -1904,7 +1749,9 @@ async function routes(rootDirectory, flags = {}) {
1904
1749
  console.log(formatRoutes(configResult.value.routes, format));
1905
1750
  }
1906
1751
  async function build2(root, options = {}) {
1907
- root = resolveRootDirectory(root, options);
1752
+ if (!root) {
1753
+ root = process.env.REACT_ROUTER_ROOT || process.cwd();
1754
+ }
1908
1755
  let { build: build3 } = await Promise.resolve().then(() => (init_build(), build_exports));
1909
1756
  if (options.profile) {
1910
1757
  await start();
@@ -1921,7 +1768,6 @@ async function dev2(root, options = {}) {
1921
1768
  await start();
1922
1769
  }
1923
1770
  (0, import_exit_hook.default)(() => stop(console.info));
1924
- root = resolveRootDirectory(root, options);
1925
1771
  await dev3(root, options);
1926
1772
  await new Promise(() => {
1927
1773
  });
@@ -1933,17 +1779,14 @@ var conjunctionListFormat = new Intl.ListFormat("en", {
1933
1779
  style: "long",
1934
1780
  type: "conjunction"
1935
1781
  });
1936
- async function generateEntry(entry, rootDirectory, flags = {}) {
1782
+ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1937
1783
  if (!entry) {
1938
- await generateEntry("entry.client", rootDirectory, flags);
1939
- await generateEntry("entry.server", rootDirectory, flags);
1784
+ await generateEntry("entry.client", reactRouterRoot, flags);
1785
+ await generateEntry("entry.server", reactRouterRoot, flags);
1940
1786
  return;
1941
1787
  }
1942
- rootDirectory = resolveRootDirectory(rootDirectory, flags);
1943
- let configResult = await loadConfig({
1944
- rootDirectory,
1945
- mode: flags.mode ?? "production"
1946
- });
1788
+ let rootDirectory = reactRouterRoot ?? process.cwd();
1789
+ let configResult = await loadConfig({ rootDirectory });
1947
1790
  if (!configResult.ok) {
1948
1791
  console.error(import_picocolors7.default.red(configResult.error));
1949
1792
  return;
@@ -1963,14 +1806,14 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
1963
1806
  console.error(import_picocolors7.default.red(`No default server entry detected.`));
1964
1807
  return;
1965
1808
  }
1966
- let defaultsDirectory = path7.resolve(
1967
- path7.dirname(require.resolve("@react-router/dev/package.json")),
1809
+ let defaultsDirectory = path8.resolve(
1810
+ path8.dirname(require.resolve("@react-router/dev/package.json")),
1968
1811
  "dist",
1969
1812
  "config",
1970
1813
  "defaults"
1971
1814
  );
1972
- let defaultEntryClient = path7.resolve(defaultsDirectory, "entry.client.tsx");
1973
- let defaultEntryServer = path7.resolve(
1815
+ let defaultEntryClient = path8.resolve(defaultsDirectory, "entry.client.tsx");
1816
+ let defaultEntryServer = path8.resolve(
1974
1817
  defaultsDirectory,
1975
1818
  `entry.server.node.tsx`
1976
1819
  );
@@ -1979,7 +1822,7 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
1979
1822
  let useTypeScript = flags.typescript ?? true;
1980
1823
  let outputExtension = useTypeScript ? "tsx" : "jsx";
1981
1824
  let outputEntry = `${entry}.${outputExtension}`;
1982
- let outputFile2 = path7.resolve(appDirectory, outputEntry);
1825
+ let outputFile2 = path8.resolve(appDirectory, outputEntry);
1983
1826
  if (!useTypeScript) {
1984
1827
  let javascript = transpile(contents, {
1985
1828
  cwd: rootDirectory,
@@ -1991,25 +1834,19 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
1991
1834
  }
1992
1835
  console.log(
1993
1836
  import_picocolors7.default.blue(
1994
- `Entry file ${entry} created at ${path7.relative(
1837
+ `Entry file ${entry} created at ${path8.relative(
1995
1838
  rootDirectory,
1996
1839
  outputFile2
1997
1840
  )}.`
1998
1841
  )
1999
1842
  );
2000
1843
  }
2001
- function resolveRootDirectory(root, flags) {
2002
- if (root) {
2003
- return path7.resolve(root);
2004
- }
2005
- return process.env.REACT_ROUTER_ROOT || (flags?.config ? path7.dirname(path7.resolve(flags.config)) : process.cwd());
2006
- }
2007
1844
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
2008
1845
  for (let entry of entries2) {
2009
- let entryPath = path7.resolve(appDirectory, entry);
1846
+ let entryPath = path8.resolve(appDirectory, entry);
2010
1847
  let exists = await import_fs_extra.default.pathExists(entryPath);
2011
1848
  if (exists) {
2012
- let relative8 = path7.relative(rootDirectory, entryPath);
1849
+ let relative8 = path8.relative(rootDirectory, entryPath);
2013
1850
  console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
2014
1851
  return process.exit(1);
2015
1852
  }
@@ -2026,22 +1863,17 @@ async function createClientEntry(rootDirectory, appDirectory, inputFile) {
2026
1863
  return contents;
2027
1864
  }
2028
1865
  async function typegen(root, flags) {
2029
- root = resolveRootDirectory(root, flags);
1866
+ root ??= process.cwd();
2030
1867
  if (flags.watch) {
2031
1868
  await preloadVite();
2032
1869
  const vite2 = getVite();
2033
1870
  const logger = vite2.createLogger("info", { prefix: "[react-router]" });
2034
- await watch(root, {
2035
- mode: flags.mode ?? "development",
2036
- logger
2037
- });
1871
+ await watch(root, { logger });
2038
1872
  await new Promise(() => {
2039
1873
  });
2040
1874
  return;
2041
1875
  }
2042
- await run(root, {
2043
- mode: flags.mode ?? "production"
2044
- });
1876
+ await run(root);
2045
1877
  }
2046
1878
 
2047
1879
  // cli/run.ts