@react-router/dev 0.0.0-experimental-5bbc45fb6 → 0.0.0-experimental-2d7ec82d5

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-5bbc45fb6
3
+ * @react-router/dev v0.0.0-experimental-2d7ec82d5
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,354 +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).map((route) => {
1011
- const filename2 = getRouteModuleAnnotationsFilepath(ctx, route);
1012
- const parents = getParents(ctx, route);
1013
- const content = import_dedent.default`
1014
- // Generated by React Router
1015
-
1016
- import type {
1017
- Params,
1018
- RouteModuleAnnotations,
1019
- CreateLoaderData,
1020
- CreateActionData,
1021
- } from "react-router/internal";
1022
-
1023
- ${parents.map((parent) => parent.import).join("\n" + " ".repeat(3))}
1024
- type Parents = [${parents.map((parent) => parent.name).join(", ")}]
1025
-
1026
- type Id = "${route.id}"
1027
- type Module = typeof import("../${Pathe.filename(route.file)}.js")
1028
-
1029
- export type unstable_Props = {
1030
- params: Params[Id]
1031
- loaderData: CreateLoaderData<Module>
1032
- actionData: CreateActionData<Module>
1033
- }
1034
-
1035
- type Annotations = RouteModuleAnnotations<unstable_Props & {
1036
- parents: Parents,
1037
- module: Module,
1038
- }>;
1039
-
1040
- export namespace Route {
1041
- // links
1042
- export type LinkDescriptors = Annotations["LinkDescriptors"];
1043
- export type LinksFunction = Annotations["LinksFunction"];
1044
-
1045
- // meta
1046
- export type MetaArgs = Annotations["MetaArgs"];
1047
- export type MetaDescriptors = Annotations["MetaDescriptors"];
1048
- export type MetaFunction = Annotations["MetaFunction"];
1049
-
1050
- // headers
1051
- export type HeadersArgs = Annotations["HeadersArgs"];
1052
- export type HeadersFunction = Annotations["HeadersFunction"];
1053
-
1054
- // unstable_middleware
1055
- export type unstable_MiddlewareFunction = Annotations["unstable_MiddlewareFunction"];
1056
-
1057
- // unstable_clientMiddleware
1058
- export type unstable_ClientMiddlewareFunction = Annotations["unstable_ClientMiddlewareFunction"];
1059
-
1060
- // loader
1061
- export type LoaderArgs = Annotations["LoaderArgs"];
1062
-
1063
- // clientLoader
1064
- export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
1065
-
1066
- // action
1067
- export type ActionArgs = Annotations["ActionArgs"];
1068
-
1069
- // clientAction
1070
- export type ClientActionArgs = Annotations["ClientActionArgs"];
1071
-
1072
- // HydrateFallback
1073
- export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
1074
-
1075
- // Component
1076
- export type ComponentProps = Annotations["ComponentProps"];
1077
-
1078
- // ErrorBoundary
1079
- export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
1080
- }
1081
- `;
1082
- return { filename: filename2, content };
1083
- });
1084
- }
1085
- function getRouteModuleAnnotationsFilepath(ctx, route) {
1086
- return Path3.join(
1087
- typesDirectory(ctx),
1088
- Path3.relative(ctx.rootDirectory, ctx.config.appDirectory),
1089
- Path3.dirname(route.file),
1090
- "+types/" + Pathe.filename(route.file) + ".ts"
1091
- );
1092
- }
1093
- function getParents(ctx, route) {
1094
- const typesPath = getRouteModuleAnnotationsFilepath(ctx, route);
727
+ function generate2(ctx, route) {
1095
728
  const lineage2 = lineage(ctx.config.routes, route);
729
+ const fullpath2 = fullpath(lineage2);
730
+ const typesPath = getTypesPath(ctx, route);
1096
731
  const parents = lineage2.slice(0, -1);
1097
- return parents.map((parent, i) => {
732
+ const parentTypeImports = parents.map((parent, i) => {
1098
733
  const rel = Path3.relative(
1099
734
  Path3.dirname(typesPath),
1100
- getRouteModuleAnnotationsFilepath(ctx, parent)
735
+ getTypesPath(ctx, parent)
1101
736
  );
737
+ const indent = i === 0 ? "" : " ".repeat(2);
1102
738
  let source = noExtension(rel);
1103
739
  if (!source.startsWith("../")) source = "./" + source;
1104
- const name = `Parent${i}`;
1105
- return {
1106
- name,
1107
- import: `import type { unstable_Props as ${name} } from "${source}.js"`
1108
- };
1109
- });
1110
- }
1111
- function noExtension(path8) {
1112
- return Path3.join(Path3.dirname(path8), Pathe.filename(path8));
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
+ `;
1113
788
  }
1114
- function paramsType(path8) {
1115
- const params = parse2(path8);
1116
- return t2.tsTypeLiteral(
1117
- Object.entries(params).map(([param, isRequired]) => {
1118
- const property = t2.tsPropertySignature(
1119
- t2.stringLiteral(param),
1120
- t2.tsTypeAnnotation(t2.tsStringKeyword())
1121
- );
1122
- property.optional = !isRequired;
1123
- return property;
1124
- })
789
+ function formatParamProperties(fullpath2) {
790
+ const params = parse2(fullpath2);
791
+ const properties = Object.entries(params).map(
792
+ ([name, isRequired]) => isRequired ? `"${name}": string` : `"${name}"?: string`
1125
793
  );
794
+ return properties.join("; ");
1126
795
  }
1127
- var import_dedent, Path3, Pathe, t2;
796
+ var import_dedent, Path3, Pathe2, noExtension;
1128
797
  var init_generate = __esm({
1129
798
  "typegen/generate.ts"() {
1130
799
  "use strict";
1131
800
  import_dedent = __toESM(require("dedent"));
1132
801
  Path3 = __toESM(require("pathe"));
1133
- Pathe = __toESM(require("pathe/utils"));
1134
- init_babel();
802
+ Pathe2 = __toESM(require("pathe/utils"));
803
+ init_paths();
1135
804
  init_params();
1136
805
  init_route();
1137
- ({ t: t2 } = babel_exports);
806
+ noExtension = (path9) => Path3.join(Path3.dirname(path9), Pathe2.filename(path9));
1138
807
  }
1139
808
  });
1140
809
 
1141
810
  // typegen/index.ts
1142
- async function clearRouteModuleAnnotations(ctx) {
1143
- await import_promises.default.rm(
1144
- Path4.join(typesDirectory(ctx), Path4.basename(ctx.config.appDirectory)),
1145
- { recursive: true, force: true }
1146
- );
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
+ };
1147
836
  }
1148
- async function write(...files) {
1149
- return Promise.all(
1150
- files.map(async ({ filename: filename2, content }) => {
1151
- await import_promises.default.mkdir(Path4.dirname(filename2), { recursive: true });
1152
- await import_promises.default.writeFile(filename2, content);
1153
- })
1154
- );
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
+ };
1155
852
  }
1156
- async function run(rootDirectory, { mode }) {
1157
- const ctx = await createContext2({ rootDirectory, mode, watch: false });
1158
- await clearRouteModuleAnnotations(ctx);
1159
- await write(
1160
- generateFuture(ctx),
1161
- generatePages(ctx),
1162
- generateRoutes(ctx),
1163
- generateServerBuild(ctx),
1164
- ...generateRouteModuleAnnotations(ctx)
1165
- );
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);
1166
866
  }
1167
- async function watch(rootDirectory, { mode, logger }) {
1168
- const ctx = await createContext2({ rootDirectory, mode, watch: true });
1169
- await clearRouteModuleAnnotations(ctx);
1170
- await write(
1171
- generateFuture(ctx),
1172
- generatePages(ctx),
1173
- generateRoutes(ctx),
1174
- generateServerBuild(ctx),
1175
- ...generateRouteModuleAnnotations(ctx)
1176
- );
1177
- logger?.info((0, import_picocolors3.green)("generated types"), { timestamp: true, clear: true });
1178
- ctx.configLoader.onChange(
1179
- async ({ result, configChanged, routeConfigChanged }) => {
1180
- if (!result.ok) {
1181
- logger?.error((0, import_picocolors3.red)(result.error), { timestamp: true, clear: true });
1182
- return;
1183
- }
1184
- ctx.config = result.value;
1185
- if (configChanged) {
1186
- await write(generateFuture(ctx));
1187
- logger?.info((0, import_picocolors3.green)("regenerated types"), {
1188
- timestamp: true,
1189
- clear: true
1190
- });
1191
- }
1192
- if (routeConfigChanged) {
1193
- await clearRouteModuleAnnotations(ctx);
1194
- await write(
1195
- generatePages(ctx),
1196
- generateRoutes(ctx),
1197
- ...generateRouteModuleAnnotations(ctx)
1198
- );
1199
- logger?.info((0, import_picocolors3.green)("regenerated types"), {
1200
- timestamp: true,
1201
- clear: true
1202
- });
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;
1203
874
  }
1204
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)
1205
880
  );
1206
- return {
1207
- close: async () => await ctx.configLoader.close()
1208
- };
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");
1209
910
  }
1210
- var import_promises, Path4, import_picocolors3;
911
+ var import_node_fs3, import_dedent2, Path4, import_picocolors3, virtual;
1211
912
  var init_typegen = __esm({
1212
913
  "typegen/index.ts"() {
1213
914
  "use strict";
1214
- import_promises = __toESM(require("fs/promises"));
915
+ import_node_fs3 = __toESM(require("fs"));
916
+ import_dedent2 = __toESM(require("dedent"));
1215
917
  Path4 = __toESM(require("pathe"));
1216
- import_picocolors3 = require("picocolors");
1217
- init_context();
918
+ import_picocolors3 = __toESM(require("picocolors"));
919
+ init_config();
920
+ init_babel();
1218
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
+ `;
1219
941
  }
1220
942
  });
1221
943
 
@@ -1233,24 +955,23 @@ var init_node_adapter = __esm({
1233
955
  });
1234
956
 
1235
957
  // vite/resolve-file-url.ts
1236
- var path4;
958
+ var path5;
1237
959
  var init_resolve_file_url = __esm({
1238
960
  "vite/resolve-file-url.ts"() {
1239
961
  "use strict";
1240
- path4 = __toESM(require("path"));
962
+ path5 = __toESM(require("path"));
1241
963
  init_vite();
1242
964
  }
1243
965
  });
1244
966
 
1245
967
  // vite/styles.ts
1246
- var path5, import_react_router, cssFileRegExp, cssModulesRegExp;
968
+ var path6, import_react_router, cssFileRegExp, cssModulesRegExp;
1247
969
  var init_styles = __esm({
1248
970
  "vite/styles.ts"() {
1249
971
  "use strict";
1250
- path5 = __toESM(require("path"));
972
+ path6 = __toESM(require("path"));
1251
973
  import_react_router = require("react-router");
1252
974
  init_resolve_file_url();
1253
- init_babel();
1254
975
  cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
1255
976
  cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
1256
977
  }
@@ -1344,11 +1065,11 @@ var init_route_chunks = __esm({
1344
1065
  });
1345
1066
 
1346
1067
  // vite/with-props.ts
1347
- var import_dedent2, vmod;
1068
+ var import_dedent3, vmod;
1348
1069
  var init_with_props = __esm({
1349
1070
  "vite/with-props.ts"() {
1350
1071
  "use strict";
1351
- import_dedent2 = __toESM(require("dedent"));
1072
+ import_dedent3 = __toESM(require("dedent"));
1352
1073
  init_babel();
1353
1074
  init_virtual_module();
1354
1075
  vmod = create("with-props");
@@ -1397,8 +1118,8 @@ function getServerBundleIds(ctx) {
1397
1118
  async function cleanBuildDirectory(viteConfig, ctx) {
1398
1119
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
1399
1120
  let isWithinRoot = () => {
1400
- let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
1401
- return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1121
+ let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
1122
+ return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
1402
1123
  };
1403
1124
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1404
1125
  await fse.remove(buildDirectory);
@@ -1409,7 +1130,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1409
1130
  ([environmentName, options]) => {
1410
1131
  let outDir = options.build?.outDir;
1411
1132
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
1412
- return path6.join(outDir, ".vite/manifest.json");
1133
+ return path7.join(outDir, ".vite/manifest.json");
1413
1134
  }
1414
1135
  );
1415
1136
  await Promise.all(
@@ -1419,7 +1140,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1419
1140
  if (!ctx.viteManifestEnabled) {
1420
1141
  await fse.remove(viteManifestPath);
1421
1142
  }
1422
- let viteDir = path6.dirname(viteManifestPath);
1143
+ let viteDir = path7.dirname(viteManifestPath);
1423
1144
  let viteDirFiles = await fse.readdir(viteDir);
1424
1145
  if (viteDirFiles.length === 0) {
1425
1146
  await fse.remove(viteDir);
@@ -1436,10 +1157,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
1436
1157
  }
1437
1158
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1438
1159
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1439
- let packageRoot = path6.dirname(
1160
+ let packageRoot = path7.dirname(
1440
1161
  require.resolve("@react-router/dev/package.json")
1441
1162
  );
1442
- 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")}`);
1443
1164
  let vite2 = getVite();
1444
1165
  let viteServerConditions = [
1445
1166
  ...vite2.defaultServerConditions ?? [],
@@ -1496,7 +1217,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1496
1217
  copyPublicDir: false,
1497
1218
  // Assets in the public directory are only used by the client
1498
1219
  rollupOptions: {
1499
- 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,
1500
1221
  output: {
1501
1222
  entryFileNames: serverBuildFile,
1502
1223
  format: serverModuleFormat
@@ -1513,7 +1234,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1513
1234
  ctx.entryClientFilePath,
1514
1235
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
1515
1236
  (route) => {
1516
- let routeFilePath = path6.resolve(
1237
+ let routeFilePath = path7.resolve(
1517
1238
  ctx.reactRouterConfig.appDirectory,
1518
1239
  route.file
1519
1240
  );
@@ -1536,9 +1257,8 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1536
1257
  ""
1537
1258
  ) : null;
1538
1259
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1539
- let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1540
- return path6.posix.join(
1541
- assetsDir,
1260
+ return path7.posix.join(
1261
+ (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
1542
1262
  `[name]${routeChunkSuffix}-[hash].js`
1543
1263
  );
1544
1264
  }
@@ -1573,6 +1293,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1573
1293
  }
1574
1294
  });
1575
1295
  }
1296
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
1297
+ environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
1298
+ }
1576
1299
  return environmentOptionsResolvers;
1577
1300
  }
1578
1301
  function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
@@ -1587,13 +1310,13 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1587
1310
  function isNonNullable(x) {
1588
1311
  return x != null;
1589
1312
  }
1590
- var import_node_crypto, fs4, path6, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, CLIENT_NON_COMPONENT_EXPORTS, CLIENT_ROUTE_EXPORTS, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, virtualHmrRuntime, virtualInjectHmrRuntime, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
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;
1591
1314
  var init_plugin = __esm({
1592
1315
  "vite/plugin.ts"() {
1593
1316
  "use strict";
1594
1317
  import_node_crypto = require("crypto");
1595
1318
  fs4 = __toESM(require("fs"));
1596
- path6 = __toESM(require("path"));
1319
+ path7 = __toESM(require("path"));
1597
1320
  url = __toESM(require("url"));
1598
1321
  fse = __toESM(require("fs-extra"));
1599
1322
  babel2 = __toESM(require("@babel/core"));
@@ -1635,26 +1358,27 @@ var init_plugin = __esm({
1635
1358
  ];
1636
1359
  BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1637
1360
  SSR_BUNDLE_PREFIX = "ssrBundle_";
1361
+ CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
1638
1362
  virtualHmrRuntime = create("hmr-runtime");
1639
1363
  virtualInjectHmrRuntime = create("inject-hmr-runtime");
1640
- virtual = {
1364
+ virtual2 = {
1641
1365
  serverBuild: create("server-build"),
1642
1366
  serverManifest: create("server-manifest"),
1643
1367
  browserManifest: create("browser-manifest")
1644
1368
  };
1645
- getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
1369
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1646
1370
  reactRouterConfig.buildDirectory,
1647
1371
  "server",
1648
1372
  ...serverBundleId ? [serverBundleId] : []
1649
1373
  );
1650
- getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
1651
- defaultEntriesDir = path6.resolve(
1652
- 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")),
1653
1377
  "dist",
1654
1378
  "config",
1655
1379
  "defaults"
1656
1380
  );
1657
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename2) => path6.join(defaultEntriesDir, filename2));
1381
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path7.join(defaultEntriesDir, filename3));
1658
1382
  invariant(defaultEntries.length > 0, "No default entries found");
1659
1383
  REACT_REFRESH_HEADER = `
1660
1384
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1688,13 +1412,7 @@ __export(build_exports, {
1688
1412
  async function build(root, viteBuildOptions) {
1689
1413
  await preloadVite();
1690
1414
  let vite2 = getVite();
1691
- let configResult = await loadConfig({
1692
- rootDirectory: root,
1693
- mode: viteBuildOptions.mode ?? "production",
1694
- // In this scope we only need future flags, so we can skip evaluating
1695
- // routes.ts until we're within the Vite build context
1696
- skipRoutes: true
1697
- });
1415
+ let configResult = await loadConfig({ rootDirectory: root });
1698
1416
  if (!configResult.ok) {
1699
1417
  throw new Error(configResult.error);
1700
1418
  }
@@ -1934,7 +1652,7 @@ var import_semver = __toESM(require("semver"));
1934
1652
  var import_picocolors8 = __toESM(require("picocolors"));
1935
1653
 
1936
1654
  // cli/commands.ts
1937
- var path7 = __toESM(require("path"));
1655
+ var path8 = __toESM(require("path"));
1938
1656
  var import_fs_extra = __toESM(require("fs-extra"));
1939
1657
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
1940
1658
  var import_exit_hook = __toESM(require("exit-hook"));
@@ -2020,12 +1738,9 @@ function transpile(tsx, options = {}) {
2020
1738
  init_profiler();
2021
1739
  init_typegen();
2022
1740
  init_vite();
2023
- async function routes(rootDirectory, flags = {}) {
2024
- rootDirectory = resolveRootDirectory(rootDirectory, flags);
2025
- let configResult = await loadConfig({
2026
- rootDirectory,
2027
- mode: flags.mode ?? "production"
2028
- });
1741
+ async function routes(reactRouterRoot, flags = {}) {
1742
+ let rootDirectory = reactRouterRoot ?? process.cwd();
1743
+ let configResult = await loadConfig({ rootDirectory });
2029
1744
  if (!configResult.ok) {
2030
1745
  console.error(import_picocolors7.default.red(configResult.error));
2031
1746
  process.exit(1);
@@ -2034,7 +1749,9 @@ async function routes(rootDirectory, flags = {}) {
2034
1749
  console.log(formatRoutes(configResult.value.routes, format));
2035
1750
  }
2036
1751
  async function build2(root, options = {}) {
2037
- root = resolveRootDirectory(root, options);
1752
+ if (!root) {
1753
+ root = process.env.REACT_ROUTER_ROOT || process.cwd();
1754
+ }
2038
1755
  let { build: build3 } = await Promise.resolve().then(() => (init_build(), build_exports));
2039
1756
  if (options.profile) {
2040
1757
  await start();
@@ -2051,7 +1768,6 @@ async function dev2(root, options = {}) {
2051
1768
  await start();
2052
1769
  }
2053
1770
  (0, import_exit_hook.default)(() => stop(console.info));
2054
- root = resolveRootDirectory(root, options);
2055
1771
  await dev3(root, options);
2056
1772
  await new Promise(() => {
2057
1773
  });
@@ -2063,17 +1779,14 @@ var conjunctionListFormat = new Intl.ListFormat("en", {
2063
1779
  style: "long",
2064
1780
  type: "conjunction"
2065
1781
  });
2066
- async function generateEntry(entry, rootDirectory, flags = {}) {
1782
+ async function generateEntry(entry, reactRouterRoot, flags = {}) {
2067
1783
  if (!entry) {
2068
- await generateEntry("entry.client", rootDirectory, flags);
2069
- await generateEntry("entry.server", rootDirectory, flags);
1784
+ await generateEntry("entry.client", reactRouterRoot, flags);
1785
+ await generateEntry("entry.server", reactRouterRoot, flags);
2070
1786
  return;
2071
1787
  }
2072
- rootDirectory = resolveRootDirectory(rootDirectory, flags);
2073
- let configResult = await loadConfig({
2074
- rootDirectory,
2075
- mode: flags.mode ?? "production"
2076
- });
1788
+ let rootDirectory = reactRouterRoot ?? process.cwd();
1789
+ let configResult = await loadConfig({ rootDirectory });
2077
1790
  if (!configResult.ok) {
2078
1791
  console.error(import_picocolors7.default.red(configResult.error));
2079
1792
  return;
@@ -2093,14 +1806,14 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2093
1806
  console.error(import_picocolors7.default.red(`No default server entry detected.`));
2094
1807
  return;
2095
1808
  }
2096
- let defaultsDirectory = path7.resolve(
2097
- path7.dirname(require.resolve("@react-router/dev/package.json")),
1809
+ let defaultsDirectory = path8.resolve(
1810
+ path8.dirname(require.resolve("@react-router/dev/package.json")),
2098
1811
  "dist",
2099
1812
  "config",
2100
1813
  "defaults"
2101
1814
  );
2102
- let defaultEntryClient = path7.resolve(defaultsDirectory, "entry.client.tsx");
2103
- let defaultEntryServer = path7.resolve(
1815
+ let defaultEntryClient = path8.resolve(defaultsDirectory, "entry.client.tsx");
1816
+ let defaultEntryServer = path8.resolve(
2104
1817
  defaultsDirectory,
2105
1818
  `entry.server.node.tsx`
2106
1819
  );
@@ -2109,7 +1822,7 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2109
1822
  let useTypeScript = flags.typescript ?? true;
2110
1823
  let outputExtension = useTypeScript ? "tsx" : "jsx";
2111
1824
  let outputEntry = `${entry}.${outputExtension}`;
2112
- let outputFile2 = path7.resolve(appDirectory, outputEntry);
1825
+ let outputFile2 = path8.resolve(appDirectory, outputEntry);
2113
1826
  if (!useTypeScript) {
2114
1827
  let javascript = transpile(contents, {
2115
1828
  cwd: rootDirectory,
@@ -2121,26 +1834,20 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2121
1834
  }
2122
1835
  console.log(
2123
1836
  import_picocolors7.default.blue(
2124
- `Entry file ${entry} created at ${path7.relative(
1837
+ `Entry file ${entry} created at ${path8.relative(
2125
1838
  rootDirectory,
2126
1839
  outputFile2
2127
1840
  )}.`
2128
1841
  )
2129
1842
  );
2130
1843
  }
2131
- function resolveRootDirectory(root, flags) {
2132
- if (root) {
2133
- return path7.resolve(root);
2134
- }
2135
- return process.env.REACT_ROUTER_ROOT || (flags?.config ? path7.dirname(path7.resolve(flags.config)) : process.cwd());
2136
- }
2137
1844
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
2138
1845
  for (let entry of entries2) {
2139
- let entryPath = path7.resolve(appDirectory, entry);
1846
+ let entryPath = path8.resolve(appDirectory, entry);
2140
1847
  let exists = await import_fs_extra.default.pathExists(entryPath);
2141
1848
  if (exists) {
2142
- let relative7 = path7.relative(rootDirectory, entryPath);
2143
- 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.`));
2144
1851
  return process.exit(1);
2145
1852
  }
2146
1853
  }
@@ -2156,22 +1863,17 @@ async function createClientEntry(rootDirectory, appDirectory, inputFile) {
2156
1863
  return contents;
2157
1864
  }
2158
1865
  async function typegen(root, flags) {
2159
- root = resolveRootDirectory(root, flags);
1866
+ root ??= process.cwd();
2160
1867
  if (flags.watch) {
2161
1868
  await preloadVite();
2162
1869
  const vite2 = getVite();
2163
1870
  const logger = vite2.createLogger("info", { prefix: "[react-router]" });
2164
- await watch(root, {
2165
- mode: flags.mode ?? "development",
2166
- logger
2167
- });
1871
+ await watch(root, { logger });
2168
1872
  await new Promise(() => {
2169
1873
  });
2170
1874
  return;
2171
1875
  }
2172
- await run(root, {
2173
- mode: flags.mode ?? "production"
2174
- });
1876
+ await run(root);
2175
1877
  }
2176
1878
 
2177
1879
  // cli/run.ts