@react-router/dev 0.0.0-experimental-b7b187661 → 0.0.0-experimental-e988dc602

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-b7b187661
3
+ * @react-router/dev v0.0.0-experimental-e988dc602
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
- basename: basename3,
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,
@@ -472,13 +424,12 @@ async function resolveConfig({
472
424
  };
473
425
  let reactRouterConfig = deepFreeze({
474
426
  appDirectory,
475
- basename: basename3,
427
+ basename: basename2,
476
428
  buildDirectory,
477
429
  buildEnd,
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 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
- });
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;
489
+ if (configCodeUpdated || appFileAddedOrRemoved) {
490
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
491
+ viteNodeContext.runner?.moduleCache.clear();
560
492
  }
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;
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, 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
- }
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);
649
540
  }
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
541
  }
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;
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({
@@ -780,31 +640,6 @@ var init_profiler = __esm({
780
640
  }
781
641
  });
782
642
 
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
-
808
643
  // vite/babel.ts
809
644
  var babel_exports = {};
810
645
  __export(babel_exports, {
@@ -824,6 +659,27 @@ var init_babel = __esm({
824
659
  }
825
660
  });
826
661
 
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
+
827
683
  // typegen/params.ts
828
684
  function parse2(fullpath2) {
829
685
  const result = {};
@@ -859,7 +715,7 @@ function lineage(routes2, route) {
859
715
  }
860
716
  function fullpath(lineage2) {
861
717
  if (lineage2.length === 1 && lineage2[0].id === "root") return "/";
862
- 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("/");
863
719
  }
864
720
  var init_route = __esm({
865
721
  "typegen/route.ts"() {
@@ -868,358 +724,220 @@ var init_route = __esm({
868
724
  });
869
725
 
870
726
  // typegen/generate.ts
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).filter((route) => isRouteInAppDirectory(ctx, route)).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 isRouteInAppDirectory(ctx, route) {
1086
- const absoluteRoutePath = Path3.resolve(ctx.config.appDirectory, route.file);
1087
- return absoluteRoutePath.startsWith(ctx.config.appDirectory);
1088
- }
1089
- function getRouteModuleAnnotationsFilepath(ctx, route) {
1090
- return Path3.join(
1091
- typesDirectory(ctx),
1092
- Path3.relative(ctx.rootDirectory, ctx.config.appDirectory),
1093
- Path3.dirname(route.file),
1094
- "+types/" + Pathe.filename(route.file) + ".ts"
1095
- );
1096
- }
1097
- function getParents(ctx, route) {
1098
- const typesPath = getRouteModuleAnnotationsFilepath(ctx, route);
727
+ function generate2(ctx, route) {
1099
728
  const lineage2 = lineage(ctx.config.routes, route);
729
+ const fullpath2 = fullpath(lineage2);
730
+ const typesPath = getTypesPath(ctx, route);
1100
731
  const parents = lineage2.slice(0, -1);
1101
- return parents.map((parent, i) => {
732
+ const parentTypeImports = parents.map((parent, i) => {
1102
733
  const rel = Path3.relative(
1103
734
  Path3.dirname(typesPath),
1104
- getRouteModuleAnnotationsFilepath(ctx, parent)
735
+ getTypesPath(ctx, parent)
1105
736
  );
737
+ const indent = i === 0 ? "" : " ".repeat(2);
1106
738
  let source = noExtension(rel);
1107
739
  if (!source.startsWith("../")) source = "./" + source;
1108
- const name = `Parent${i}`;
1109
- return {
1110
- name,
1111
- import: `import type { unstable_Props as ${name} } from "${source}.js"`
1112
- };
1113
- });
1114
- }
1115
- function noExtension(path8) {
1116
- return Path3.join(Path3.dirname(path8), Pathe.filename(path8));
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
+ `;
1117
788
  }
1118
- function paramsType(path8) {
1119
- const params = parse2(path8);
1120
- return t2.tsTypeLiteral(
1121
- Object.entries(params).map(([param, isRequired]) => {
1122
- const property = t2.tsPropertySignature(
1123
- t2.stringLiteral(param),
1124
- t2.tsTypeAnnotation(t2.tsStringKeyword())
1125
- );
1126
- property.optional = !isRequired;
1127
- return property;
1128
- })
789
+ function formatParamProperties(fullpath2) {
790
+ const params = parse2(fullpath2);
791
+ const properties = Object.entries(params).map(
792
+ ([name, isRequired]) => isRequired ? `"${name}": string` : `"${name}"?: string`
1129
793
  );
794
+ return properties.join("; ");
1130
795
  }
1131
- var import_dedent, Path3, Pathe, t2;
796
+ var import_dedent, Path3, Pathe2, noExtension;
1132
797
  var init_generate = __esm({
1133
798
  "typegen/generate.ts"() {
1134
799
  "use strict";
1135
800
  import_dedent = __toESM(require("dedent"));
1136
801
  Path3 = __toESM(require("pathe"));
1137
- Pathe = __toESM(require("pathe/utils"));
1138
- init_babel();
802
+ Pathe2 = __toESM(require("pathe/utils"));
803
+ init_paths();
1139
804
  init_params();
1140
805
  init_route();
1141
- ({ t: t2 } = babel_exports);
806
+ noExtension = (path9) => Path3.join(Path3.dirname(path9), Pathe2.filename(path9));
1142
807
  }
1143
808
  });
1144
809
 
1145
810
  // typegen/index.ts
1146
- async function clearRouteModuleAnnotations(ctx) {
1147
- await import_promises.default.rm(
1148
- Path4.join(typesDirectory(ctx), Path4.basename(ctx.config.appDirectory)),
1149
- { recursive: true, force: true }
1150
- );
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
+ };
1151
836
  }
1152
- async function write(...files) {
1153
- return Promise.all(
1154
- files.map(async ({ filename: filename2, content }) => {
1155
- await import_promises.default.mkdir(Path4.dirname(filename2), { recursive: true });
1156
- await import_promises.default.writeFile(filename2, content);
1157
- })
1158
- );
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
+ };
1159
852
  }
1160
- async function run(rootDirectory, { mode }) {
1161
- const ctx = await createContext2({ rootDirectory, mode, watch: false });
1162
- await import_promises.default.rm(typesDirectory(ctx), { recursive: true, force: true });
1163
- await write(
1164
- generateFuture(ctx),
1165
- generatePages(ctx),
1166
- generateRoutes(ctx),
1167
- generateServerBuild(ctx),
1168
- ...generateRouteModuleAnnotations(ctx)
1169
- );
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);
1170
866
  }
1171
- async function watch(rootDirectory, { mode, logger }) {
1172
- const ctx = await createContext2({ rootDirectory, mode, watch: true });
1173
- await import_promises.default.rm(typesDirectory(ctx), { recursive: true, force: true });
1174
- await write(
1175
- generateFuture(ctx),
1176
- generatePages(ctx),
1177
- generateRoutes(ctx),
1178
- generateServerBuild(ctx),
1179
- ...generateRouteModuleAnnotations(ctx)
1180
- );
1181
- logger?.info((0, import_picocolors3.green)("generated types"), { timestamp: true, clear: true });
1182
- ctx.configLoader.onChange(
1183
- async ({ result, configChanged, routeConfigChanged }) => {
1184
- if (!result.ok) {
1185
- logger?.error((0, import_picocolors3.red)(result.error), { timestamp: true, clear: true });
1186
- return;
1187
- }
1188
- ctx.config = result.value;
1189
- if (configChanged) {
1190
- await write(generateFuture(ctx));
1191
- logger?.info((0, import_picocolors3.green)("regenerated types"), {
1192
- timestamp: true,
1193
- clear: true
1194
- });
1195
- }
1196
- if (routeConfigChanged) {
1197
- await clearRouteModuleAnnotations(ctx);
1198
- await write(
1199
- generatePages(ctx),
1200
- generateRoutes(ctx),
1201
- ...generateRouteModuleAnnotations(ctx)
1202
- );
1203
- logger?.info((0, import_picocolors3.green)("regenerated types"), {
1204
- timestamp: true,
1205
- clear: true
1206
- });
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;
1207
874
  }
1208
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)
1209
880
  );
1210
- return {
1211
- close: async () => await ctx.configLoader.close()
1212
- };
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
+ )
905
+ );
906
+ }).filter((x) => x !== void 0)
907
+ )
908
+ );
909
+ return [register2, generate(typeParams).code].join("\n\n");
1213
910
  }
1214
- var import_promises, Path4, import_picocolors3;
911
+ var import_node_fs3, import_dedent2, Path4, import_picocolors3, virtual;
1215
912
  var init_typegen = __esm({
1216
913
  "typegen/index.ts"() {
1217
914
  "use strict";
1218
- import_promises = __toESM(require("fs/promises"));
915
+ import_node_fs3 = __toESM(require("fs"));
916
+ import_dedent2 = __toESM(require("dedent"));
1219
917
  Path4 = __toESM(require("pathe"));
1220
- import_picocolors3 = require("picocolors");
1221
- init_context();
918
+ import_picocolors3 = __toESM(require("picocolors"));
919
+ init_config();
920
+ init_babel();
1222
921
  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
+ `;
1223
941
  }
1224
942
  });
1225
943
 
@@ -1237,24 +955,23 @@ var init_node_adapter = __esm({
1237
955
  });
1238
956
 
1239
957
  // vite/resolve-file-url.ts
1240
- var path4;
958
+ var path5;
1241
959
  var init_resolve_file_url = __esm({
1242
960
  "vite/resolve-file-url.ts"() {
1243
961
  "use strict";
1244
- path4 = __toESM(require("path"));
962
+ path5 = __toESM(require("path"));
1245
963
  init_vite();
1246
964
  }
1247
965
  });
1248
966
 
1249
967
  // vite/styles.ts
1250
- var path5, import_react_router, cssFileRegExp, cssModulesRegExp;
968
+ var path6, import_react_router, cssFileRegExp, cssModulesRegExp;
1251
969
  var init_styles = __esm({
1252
970
  "vite/styles.ts"() {
1253
971
  "use strict";
1254
- path5 = __toESM(require("path"));
972
+ path6 = __toESM(require("path"));
1255
973
  import_react_router = require("react-router");
1256
974
  init_resolve_file_url();
1257
- init_babel();
1258
975
  cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
1259
976
  cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
1260
977
  }
@@ -1348,11 +1065,11 @@ var init_route_chunks = __esm({
1348
1065
  });
1349
1066
 
1350
1067
  // vite/with-props.ts
1351
- var import_dedent2, vmod;
1068
+ var import_dedent3, vmod;
1352
1069
  var init_with_props = __esm({
1353
1070
  "vite/with-props.ts"() {
1354
1071
  "use strict";
1355
- import_dedent2 = __toESM(require("dedent"));
1072
+ import_dedent3 = __toESM(require("dedent"));
1356
1073
  init_babel();
1357
1074
  init_virtual_module();
1358
1075
  vmod = create("with-props");
@@ -1401,8 +1118,8 @@ function getServerBundleIds(ctx) {
1401
1118
  async function cleanBuildDirectory(viteConfig, ctx) {
1402
1119
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
1403
1120
  let isWithinRoot = () => {
1404
- let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
1405
- return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1121
+ let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
1122
+ return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
1406
1123
  };
1407
1124
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1408
1125
  await fse.remove(buildDirectory);
@@ -1413,7 +1130,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1413
1130
  ([environmentName, options]) => {
1414
1131
  let outDir = options.build?.outDir;
1415
1132
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
1416
- return path6.join(outDir, ".vite/manifest.json");
1133
+ return path7.join(outDir, ".vite/manifest.json");
1417
1134
  }
1418
1135
  );
1419
1136
  await Promise.all(
@@ -1423,7 +1140,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1423
1140
  if (!ctx.viteManifestEnabled) {
1424
1141
  await fse.remove(viteManifestPath);
1425
1142
  }
1426
- let viteDir = path6.dirname(viteManifestPath);
1143
+ let viteDir = path7.dirname(viteManifestPath);
1427
1144
  let viteDirFiles = await fse.readdir(viteDir);
1428
1145
  if (viteDirFiles.length === 0) {
1429
1146
  await fse.remove(viteDir);
@@ -1440,10 +1157,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
1440
1157
  }
1441
1158
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1442
1159
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1443
- let packageRoot = path6.dirname(
1160
+ let packageRoot = path7.dirname(
1444
1161
  require.resolve("@react-router/dev/package.json")
1445
1162
  );
1446
- 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")}`);
1447
1164
  let vite2 = getVite();
1448
1165
  let viteServerConditions = [
1449
1166
  ...vite2.defaultServerConditions ?? [],
@@ -1500,7 +1217,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1500
1217
  copyPublicDir: false,
1501
1218
  // Assets in the public directory are only used by the client
1502
1219
  rollupOptions: {
1503
- input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
1220
+ input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual2.serverBuild.id,
1504
1221
  output: {
1505
1222
  entryFileNames: serverBuildFile,
1506
1223
  format: serverModuleFormat
@@ -1517,7 +1234,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1517
1234
  ctx.entryClientFilePath,
1518
1235
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
1519
1236
  (route) => {
1520
- let routeFilePath = path6.resolve(
1237
+ let routeFilePath = path7.resolve(
1521
1238
  ctx.reactRouterConfig.appDirectory,
1522
1239
  route.file
1523
1240
  );
@@ -1540,9 +1257,8 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1540
1257
  ""
1541
1258
  ) : null;
1542
1259
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1543
- let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1544
- return path6.posix.join(
1545
- assetsDir,
1260
+ return path7.posix.join(
1261
+ (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
1546
1262
  `[name]${routeChunkSuffix}-[hash].js`
1547
1263
  );
1548
1264
  }
@@ -1577,6 +1293,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1577
1293
  }
1578
1294
  });
1579
1295
  }
1296
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
1297
+ environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
1298
+ }
1580
1299
  return environmentOptionsResolvers;
1581
1300
  }
1582
1301
  function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
@@ -1591,13 +1310,13 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1591
1310
  function isNonNullable(x) {
1592
1311
  return x != null;
1593
1312
  }
1594
- 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;
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;
1595
1314
  var init_plugin = __esm({
1596
1315
  "vite/plugin.ts"() {
1597
1316
  "use strict";
1598
1317
  import_node_crypto = require("crypto");
1599
1318
  fs4 = __toESM(require("fs"));
1600
- path6 = __toESM(require("path"));
1319
+ path7 = __toESM(require("path"));
1601
1320
  url = __toESM(require("url"));
1602
1321
  fse = __toESM(require("fs-extra"));
1603
1322
  babel2 = __toESM(require("@babel/core"));
@@ -1639,26 +1358,27 @@ var init_plugin = __esm({
1639
1358
  ];
1640
1359
  BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1641
1360
  SSR_BUNDLE_PREFIX = "ssrBundle_";
1361
+ CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
1642
1362
  virtualHmrRuntime = create("hmr-runtime");
1643
1363
  virtualInjectHmrRuntime = create("inject-hmr-runtime");
1644
- virtual = {
1364
+ virtual2 = {
1645
1365
  serverBuild: create("server-build"),
1646
1366
  serverManifest: create("server-manifest"),
1647
1367
  browserManifest: create("browser-manifest")
1648
1368
  };
1649
- getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
1369
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1650
1370
  reactRouterConfig.buildDirectory,
1651
1371
  "server",
1652
1372
  ...serverBundleId ? [serverBundleId] : []
1653
1373
  );
1654
- getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
1655
- defaultEntriesDir = path6.resolve(
1656
- 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")),
1657
1377
  "dist",
1658
1378
  "config",
1659
1379
  "defaults"
1660
1380
  );
1661
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename2) => path6.join(defaultEntriesDir, filename2));
1381
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path7.join(defaultEntriesDir, filename3));
1662
1382
  invariant(defaultEntries.length > 0, "No default entries found");
1663
1383
  REACT_REFRESH_HEADER = `
1664
1384
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1692,13 +1412,7 @@ __export(build_exports, {
1692
1412
  async function build(root, viteBuildOptions) {
1693
1413
  await preloadVite();
1694
1414
  let vite2 = getVite();
1695
- let configResult = await loadConfig({
1696
- rootDirectory: root,
1697
- mode: viteBuildOptions.mode ?? "production",
1698
- // In this scope we only need future flags, so we can skip evaluating
1699
- // routes.ts until we're within the Vite build context
1700
- skipRoutes: true
1701
- });
1415
+ let configResult = await loadConfig({ rootDirectory: root });
1702
1416
  if (!configResult.ok) {
1703
1417
  throw new Error(configResult.error);
1704
1418
  }
@@ -1938,7 +1652,7 @@ var import_semver = __toESM(require("semver"));
1938
1652
  var import_picocolors8 = __toESM(require("picocolors"));
1939
1653
 
1940
1654
  // cli/commands.ts
1941
- var path7 = __toESM(require("path"));
1655
+ var path8 = __toESM(require("path"));
1942
1656
  var import_fs_extra = __toESM(require("fs-extra"));
1943
1657
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
1944
1658
  var import_exit_hook = __toESM(require("exit-hook"));
@@ -2024,12 +1738,9 @@ function transpile(tsx, options = {}) {
2024
1738
  init_profiler();
2025
1739
  init_typegen();
2026
1740
  init_vite();
2027
- async function routes(rootDirectory, flags = {}) {
2028
- rootDirectory = resolveRootDirectory(rootDirectory, flags);
2029
- let configResult = await loadConfig({
2030
- rootDirectory,
2031
- mode: flags.mode ?? "production"
2032
- });
1741
+ async function routes(reactRouterRoot, flags = {}) {
1742
+ let rootDirectory = reactRouterRoot ?? process.cwd();
1743
+ let configResult = await loadConfig({ rootDirectory });
2033
1744
  if (!configResult.ok) {
2034
1745
  console.error(import_picocolors7.default.red(configResult.error));
2035
1746
  process.exit(1);
@@ -2038,7 +1749,9 @@ async function routes(rootDirectory, flags = {}) {
2038
1749
  console.log(formatRoutes(configResult.value.routes, format));
2039
1750
  }
2040
1751
  async function build2(root, options = {}) {
2041
- root = resolveRootDirectory(root, options);
1752
+ if (!root) {
1753
+ root = process.env.REACT_ROUTER_ROOT || process.cwd();
1754
+ }
2042
1755
  let { build: build3 } = await Promise.resolve().then(() => (init_build(), build_exports));
2043
1756
  if (options.profile) {
2044
1757
  await start();
@@ -2055,7 +1768,6 @@ async function dev2(root, options = {}) {
2055
1768
  await start();
2056
1769
  }
2057
1770
  (0, import_exit_hook.default)(() => stop(console.info));
2058
- root = resolveRootDirectory(root, options);
2059
1771
  await dev3(root, options);
2060
1772
  await new Promise(() => {
2061
1773
  });
@@ -2067,17 +1779,14 @@ var conjunctionListFormat = new Intl.ListFormat("en", {
2067
1779
  style: "long",
2068
1780
  type: "conjunction"
2069
1781
  });
2070
- async function generateEntry(entry, rootDirectory, flags = {}) {
1782
+ async function generateEntry(entry, reactRouterRoot, flags = {}) {
2071
1783
  if (!entry) {
2072
- await generateEntry("entry.client", rootDirectory, flags);
2073
- await generateEntry("entry.server", rootDirectory, flags);
1784
+ await generateEntry("entry.client", reactRouterRoot, flags);
1785
+ await generateEntry("entry.server", reactRouterRoot, flags);
2074
1786
  return;
2075
1787
  }
2076
- rootDirectory = resolveRootDirectory(rootDirectory, flags);
2077
- let configResult = await loadConfig({
2078
- rootDirectory,
2079
- mode: flags.mode ?? "production"
2080
- });
1788
+ let rootDirectory = reactRouterRoot ?? process.cwd();
1789
+ let configResult = await loadConfig({ rootDirectory });
2081
1790
  if (!configResult.ok) {
2082
1791
  console.error(import_picocolors7.default.red(configResult.error));
2083
1792
  return;
@@ -2097,14 +1806,14 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2097
1806
  console.error(import_picocolors7.default.red(`No default server entry detected.`));
2098
1807
  return;
2099
1808
  }
2100
- let defaultsDirectory = path7.resolve(
2101
- path7.dirname(require.resolve("@react-router/dev/package.json")),
1809
+ let defaultsDirectory = path8.resolve(
1810
+ path8.dirname(require.resolve("@react-router/dev/package.json")),
2102
1811
  "dist",
2103
1812
  "config",
2104
1813
  "defaults"
2105
1814
  );
2106
- let defaultEntryClient = path7.resolve(defaultsDirectory, "entry.client.tsx");
2107
- let defaultEntryServer = path7.resolve(
1815
+ let defaultEntryClient = path8.resolve(defaultsDirectory, "entry.client.tsx");
1816
+ let defaultEntryServer = path8.resolve(
2108
1817
  defaultsDirectory,
2109
1818
  `entry.server.node.tsx`
2110
1819
  );
@@ -2113,7 +1822,7 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2113
1822
  let useTypeScript = flags.typescript ?? true;
2114
1823
  let outputExtension = useTypeScript ? "tsx" : "jsx";
2115
1824
  let outputEntry = `${entry}.${outputExtension}`;
2116
- let outputFile2 = path7.resolve(appDirectory, outputEntry);
1825
+ let outputFile2 = path8.resolve(appDirectory, outputEntry);
2117
1826
  if (!useTypeScript) {
2118
1827
  let javascript = transpile(contents, {
2119
1828
  cwd: rootDirectory,
@@ -2125,26 +1834,20 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2125
1834
  }
2126
1835
  console.log(
2127
1836
  import_picocolors7.default.blue(
2128
- `Entry file ${entry} created at ${path7.relative(
1837
+ `Entry file ${entry} created at ${path8.relative(
2129
1838
  rootDirectory,
2130
1839
  outputFile2
2131
1840
  )}.`
2132
1841
  )
2133
1842
  );
2134
1843
  }
2135
- function resolveRootDirectory(root, flags) {
2136
- if (root) {
2137
- return path7.resolve(root);
2138
- }
2139
- return process.env.REACT_ROUTER_ROOT || (flags?.config ? path7.dirname(path7.resolve(flags.config)) : process.cwd());
2140
- }
2141
1844
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
2142
1845
  for (let entry of entries2) {
2143
- let entryPath = path7.resolve(appDirectory, entry);
1846
+ let entryPath = path8.resolve(appDirectory, entry);
2144
1847
  let exists = await import_fs_extra.default.pathExists(entryPath);
2145
1848
  if (exists) {
2146
- let relative7 = path7.relative(rootDirectory, entryPath);
2147
- console.error(import_picocolors7.default.red(`Entry file ${relative7} already exists.`));
1849
+ let relative8 = path8.relative(rootDirectory, entryPath);
1850
+ console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
2148
1851
  return process.exit(1);
2149
1852
  }
2150
1853
  }
@@ -2160,22 +1863,17 @@ async function createClientEntry(rootDirectory, appDirectory, inputFile) {
2160
1863
  return contents;
2161
1864
  }
2162
1865
  async function typegen(root, flags) {
2163
- root = resolveRootDirectory(root, flags);
1866
+ root ??= process.cwd();
2164
1867
  if (flags.watch) {
2165
1868
  await preloadVite();
2166
1869
  const vite2 = getVite();
2167
1870
  const logger = vite2.createLogger("info", { prefix: "[react-router]" });
2168
- await watch(root, {
2169
- mode: flags.mode ?? "development",
2170
- logger
2171
- });
1871
+ await watch(root, { logger });
2172
1872
  await new Promise(() => {
2173
1873
  });
2174
1874
  return;
2175
1875
  }
2176
- await run(root, {
2177
- mode: flags.mode ?? "production"
2178
- });
1876
+ await run(root);
2179
1877
  }
2180
1878
 
2181
1879
  // cli/run.ts