@c0va23/react-router-dev 7.13.0 → 7.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.13.0
2
+ * @react-router/dev v7.13.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -48,8 +48,8 @@ module.exports = __toCommonJS(vite_exports);
48
48
  // vite/plugin.ts
49
49
  var import_node_crypto = require("crypto");
50
50
  var import_node_fs2 = require("fs");
51
- var import_promises2 = require("fs/promises");
52
- var path6 = __toESM(require("path"));
51
+ var import_promises3 = require("fs/promises");
52
+ var path7 = __toESM(require("path"));
53
53
  var url = __toESM(require("url"));
54
54
  var babel = __toESM(require("@babel/core"));
55
55
  var import_react_router2 = require("react-router");
@@ -246,7 +246,7 @@ function validateRouteConfig({
246
246
  `Route config in "${routeConfigFile}" is invalid.`,
247
247
  root ? `${root}` : [],
248
248
  nested ? Object.entries(nested).map(
249
- ([path9, message]) => `Path: routes.${path9}
249
+ ([path10, message]) => `Path: routes.${path10}
250
250
  ${message}`
251
251
  ) : []
252
252
  ].flat().join("\n\n")
@@ -431,7 +431,7 @@ async function resolveConfig({
431
431
  basename: basename3,
432
432
  buildDirectory: userBuildDirectory,
433
433
  buildEnd,
434
- prerender,
434
+ prerender: prerender2,
435
435
  routeDiscovery: userRouteDiscovery,
436
436
  serverBuildFile,
437
437
  serverBundles,
@@ -445,15 +445,15 @@ async function resolveConfig({
445
445
  if (!ssr && serverBundles) {
446
446
  serverBundles = void 0;
447
447
  }
448
- if (prerender) {
448
+ if (prerender2) {
449
449
  let isValidPrerenderPathsConfig = (p) => typeof p === "boolean" || typeof p === "function" || Array.isArray(p);
450
- let isValidPrerenderConfig = isValidPrerenderPathsConfig(prerender) || typeof prerender === "object" && "paths" in prerender && isValidPrerenderPathsConfig(prerender.paths);
450
+ let isValidPrerenderConfig = isValidPrerenderPathsConfig(prerender2) || typeof prerender2 === "object" && "paths" in prerender2 && isValidPrerenderPathsConfig(prerender2.paths);
451
451
  if (!isValidPrerenderConfig) {
452
452
  return err(
453
453
  "The `prerender`/`prerender.paths` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths."
454
454
  );
455
455
  }
456
- let isValidConcurrencyConfig = typeof prerender != "object" || !("unstable_concurrency" in prerender) || typeof prerender.unstable_concurrency === "number" && Number.isInteger(prerender.unstable_concurrency) && prerender.unstable_concurrency > 0;
456
+ let isValidConcurrencyConfig = typeof prerender2 != "object" || !("unstable_concurrency" in prerender2) || typeof prerender2.unstable_concurrency === "number" && Number.isInteger(prerender2.unstable_concurrency) && prerender2.unstable_concurrency > 0;
457
457
  if (!isValidConcurrencyConfig) {
458
458
  return err(
459
459
  "The `prerender.unstable_concurrency` config must be a positive integer if specified."
@@ -560,8 +560,10 @@ async function resolveConfig({
560
560
  }
561
561
  let future = {
562
562
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
563
+ unstable_passThroughRequests: userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
563
564
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
564
565
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
566
+ unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
565
567
  v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
566
568
  v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
567
569
  v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
@@ -573,7 +575,7 @@ async function resolveConfig({
573
575
  buildDirectory,
574
576
  buildEnd,
575
577
  future,
576
- prerender,
578
+ prerender: prerender2,
577
579
  routes,
578
580
  routeDiscovery,
579
581
  serverBuildFile,
@@ -640,13 +642,11 @@ async function createConfigLoader({
640
642
  if (!fsWatcher) {
641
643
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
642
644
  ignoreInitial: true,
643
- ignored: (path9) => {
644
- let dirname4 = import_pathe3.default.dirname(path9);
645
- return !dirname4.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
646
- // that are at the root level, not nested in subdirectories
647
- path9 !== root && // Watch the root directory itself
648
- dirname4 !== root;
649
- }
645
+ ignored: (path10) => isIgnoredByWatcher(path10, { root, appDirectory })
646
+ });
647
+ fsWatcher.on("error", (error) => {
648
+ let message = error instanceof Error ? error.message : String(error);
649
+ console.warn(import_picocolors.default.yellow(`File watcher error: ${message}`));
650
650
  });
651
651
  fsWatcher.on("all", async (...args) => {
652
652
  let [event, rawFilepath] = args;
@@ -855,6 +855,25 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
855
855
  }
856
856
  return false;
857
857
  }
858
+ function isIgnoredByWatcher(path10, { root, appDirectory }) {
859
+ let dirname4 = import_pathe3.default.dirname(path10);
860
+ let ignoredByPath = !dirname4.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
861
+ // that are at the root level, not nested in subdirectories
862
+ path10 !== root && // Watch the root directory itself
863
+ dirname4 !== root;
864
+ if (ignoredByPath) {
865
+ return true;
866
+ }
867
+ try {
868
+ let stat = import_node_fs.default.statSync(path10, { throwIfNoEntry: false });
869
+ if (stat && !stat.isFile() && !stat.isDirectory()) {
870
+ return true;
871
+ }
872
+ } catch {
873
+ return true;
874
+ }
875
+ return false;
876
+ }
858
877
 
859
878
  // typegen/context.ts
860
879
  async function createContext2({
@@ -928,7 +947,7 @@ function fullpath(lineage2) {
928
947
  if (lineage2.length === 1 && route?.id === "root") return "/";
929
948
  const isLayout = route && route.index !== true && route.path === void 0;
930
949
  if (isLayout) return void 0;
931
- return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path9) => path9 !== void 0 && path9 !== "").join("/");
950
+ return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path10) => path10 !== void 0 && path10 !== "").join("/");
932
951
  }
933
952
 
934
953
  // typegen/generate.ts
@@ -1108,8 +1127,8 @@ function routeModulesType(ctx) {
1108
1127
  );
1109
1128
  }
1110
1129
  function isInAppDirectory(ctx, routeFile) {
1111
- const path9 = Path3.resolve(ctx.config.appDirectory, routeFile);
1112
- return path9.startsWith(ctx.config.appDirectory);
1130
+ const path10 = Path3.resolve(ctx.config.appDirectory, routeFile);
1131
+ return path10.startsWith(ctx.config.appDirectory);
1113
1132
  }
1114
1133
  function getRouteAnnotations({
1115
1134
  ctx,
@@ -1221,21 +1240,21 @@ function getRouteAnnotations({
1221
1240
  return { filename: filename2, content };
1222
1241
  }
1223
1242
  function relativeImportSource(from, to) {
1224
- let path9 = Path3.relative(Path3.dirname(from), to);
1225
- let extension = Path3.extname(path9);
1226
- path9 = Path3.join(Path3.dirname(path9), Pathe.filename(path9));
1227
- if (!path9.startsWith("../")) path9 = "./" + path9;
1243
+ let path10 = Path3.relative(Path3.dirname(from), to);
1244
+ let extension = Path3.extname(path10);
1245
+ path10 = Path3.join(Path3.dirname(path10), Pathe.filename(path10));
1246
+ if (!path10.startsWith("../")) path10 = "./" + path10;
1228
1247
  if (!extension || /\.(js|ts)x?$/.test(extension)) {
1229
1248
  extension = ".js";
1230
1249
  }
1231
- return path9 + extension;
1250
+ return path10 + extension;
1232
1251
  }
1233
1252
  function rootDirsPath(ctx, typesPath) {
1234
1253
  const rel = Path3.relative(typesDirectory(ctx), typesPath);
1235
1254
  return Path3.join(ctx.rootDirectory, rel);
1236
1255
  }
1237
- function paramsType(path9) {
1238
- const params = parse2(path9);
1256
+ function paramsType(path10) {
1257
+ const params = parse2(path10);
1239
1258
  return t2.tsTypeLiteral(
1240
1259
  Object.entries(params).map(([param, isRequired]) => {
1241
1260
  const property = t2.tsPropertySignature(
@@ -1504,11 +1523,11 @@ var getCssStringFromViteDevModuleCode = (code) => {
1504
1523
  let cssContent = void 0;
1505
1524
  const ast = import_parser.parse(code, { sourceType: "module" });
1506
1525
  traverse(ast, {
1507
- VariableDeclaration(path9) {
1508
- const declaration = path9.node.declarations[0];
1526
+ VariableDeclaration(path10) {
1527
+ const declaration = path10.node.declarations[0];
1509
1528
  if (declaration?.id?.type === "Identifier" && declaration.id.name === "__vite__css" && declaration.init?.type === "StringLiteral") {
1510
1529
  cssContent = declaration.init.value;
1511
- path9.stop();
1530
+ path10.stop();
1512
1531
  }
1513
1532
  }
1514
1533
  });
@@ -1547,10 +1566,10 @@ var removeExports = (ast, exportsToRemove) => {
1547
1566
  let markedForRemoval = /* @__PURE__ */ new Set();
1548
1567
  let removedExportLocalNames = /* @__PURE__ */ new Set();
1549
1568
  traverse(ast, {
1550
- ExportDeclaration(path9) {
1551
- if (path9.node.type === "ExportNamedDeclaration") {
1552
- if (path9.node.specifiers.length) {
1553
- path9.node.specifiers = path9.node.specifiers.filter((specifier) => {
1569
+ ExportDeclaration(path10) {
1570
+ if (path10.node.type === "ExportNamedDeclaration") {
1571
+ if (path10.node.specifiers.length) {
1572
+ path10.node.specifiers = path10.node.specifiers.filter((specifier) => {
1554
1573
  if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
1555
1574
  if (exportsToRemove.includes(specifier.exported.name)) {
1556
1575
  exportsFiltered = true;
@@ -1562,12 +1581,12 @@ var removeExports = (ast, exportsToRemove) => {
1562
1581
  }
1563
1582
  return true;
1564
1583
  });
1565
- if (path9.node.specifiers.length === 0) {
1566
- markedForRemoval.add(path9);
1584
+ if (path10.node.specifiers.length === 0) {
1585
+ markedForRemoval.add(path10);
1567
1586
  }
1568
1587
  }
1569
- if (path9.node.declaration?.type === "VariableDeclaration") {
1570
- let declaration = path9.node.declaration;
1588
+ if (path10.node.declaration?.type === "VariableDeclaration") {
1589
+ let declaration = path10.node.declaration;
1571
1590
  declaration.declarations = declaration.declarations.filter(
1572
1591
  (declaration2) => {
1573
1592
  if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
@@ -1581,30 +1600,30 @@ var removeExports = (ast, exportsToRemove) => {
1581
1600
  }
1582
1601
  );
1583
1602
  if (declaration.declarations.length === 0) {
1584
- markedForRemoval.add(path9);
1603
+ markedForRemoval.add(path10);
1585
1604
  }
1586
1605
  }
1587
- if (path9.node.declaration?.type === "FunctionDeclaration") {
1588
- let id = path9.node.declaration.id;
1606
+ if (path10.node.declaration?.type === "FunctionDeclaration") {
1607
+ let id = path10.node.declaration.id;
1589
1608
  if (id && exportsToRemove.includes(id.name)) {
1590
- markedForRemoval.add(path9);
1609
+ markedForRemoval.add(path10);
1591
1610
  }
1592
1611
  }
1593
- if (path9.node.declaration?.type === "ClassDeclaration") {
1594
- let id = path9.node.declaration.id;
1612
+ if (path10.node.declaration?.type === "ClassDeclaration") {
1613
+ let id = path10.node.declaration.id;
1595
1614
  if (id && exportsToRemove.includes(id.name)) {
1596
- markedForRemoval.add(path9);
1615
+ markedForRemoval.add(path10);
1597
1616
  }
1598
1617
  }
1599
1618
  }
1600
- if (path9.node.type === "ExportDefaultDeclaration") {
1619
+ if (path10.node.type === "ExportDefaultDeclaration") {
1601
1620
  if (exportsToRemove.includes("default")) {
1602
- markedForRemoval.add(path9);
1603
- if (path9.node.declaration) {
1604
- if (path9.node.declaration.type === "Identifier") {
1605
- removedExportLocalNames.add(path9.node.declaration.name);
1606
- } else if ((path9.node.declaration.type === "FunctionDeclaration" || path9.node.declaration.type === "ClassDeclaration") && path9.node.declaration.id) {
1607
- removedExportLocalNames.add(path9.node.declaration.id.name);
1621
+ markedForRemoval.add(path10);
1622
+ if (path10.node.declaration) {
1623
+ if (path10.node.declaration.type === "Identifier") {
1624
+ removedExportLocalNames.add(path10.node.declaration.name);
1625
+ } else if ((path10.node.declaration.type === "FunctionDeclaration" || path10.node.declaration.type === "ClassDeclaration") && path10.node.declaration.id) {
1626
+ removedExportLocalNames.add(path10.node.declaration.id.name);
1608
1627
  }
1609
1628
  }
1610
1629
  }
@@ -1612,21 +1631,21 @@ var removeExports = (ast, exportsToRemove) => {
1612
1631
  }
1613
1632
  });
1614
1633
  traverse(ast, {
1615
- ExpressionStatement(path9) {
1616
- if (!path9.parentPath.isProgram()) {
1634
+ ExpressionStatement(path10) {
1635
+ if (!path10.parentPath.isProgram()) {
1617
1636
  return;
1618
1637
  }
1619
- if (path9.node.expression.type === "AssignmentExpression") {
1620
- const left = path9.node.expression.left;
1638
+ if (path10.node.expression.type === "AssignmentExpression") {
1639
+ const left = path10.node.expression.left;
1621
1640
  if (left.type === "MemberExpression" && left.object.type === "Identifier" && (exportsToRemove.includes(left.object.name) || removedExportLocalNames.has(left.object.name))) {
1622
- markedForRemoval.add(path9);
1641
+ markedForRemoval.add(path10);
1623
1642
  }
1624
1643
  }
1625
1644
  }
1626
1645
  });
1627
1646
  if (markedForRemoval.size > 0 || exportsFiltered) {
1628
- for (let path9 of markedForRemoval) {
1629
- path9.remove();
1647
+ for (let path10 of markedForRemoval) {
1648
+ path10.remove();
1630
1649
  }
1631
1650
  (0, import_babel_dead_code_elimination.deadCodeElimination)(ast, previouslyReferencedIdentifiers);
1632
1651
  }
@@ -1709,28 +1728,28 @@ function codeToAst(code, cache, cacheKey) {
1709
1728
  )
1710
1729
  );
1711
1730
  }
1712
- function assertNodePath(path9) {
1731
+ function assertNodePath(path10) {
1713
1732
  invariant(
1714
- path9 && !Array.isArray(path9),
1715
- `Expected a Path, but got ${Array.isArray(path9) ? "an array" : path9}`
1733
+ path10 && !Array.isArray(path10),
1734
+ `Expected a Path, but got ${Array.isArray(path10) ? "an array" : path10}`
1716
1735
  );
1717
1736
  }
1718
- function assertNodePathIsStatement(path9) {
1737
+ function assertNodePathIsStatement(path10) {
1719
1738
  invariant(
1720
- path9 && !Array.isArray(path9) && t.isStatement(path9.node),
1721
- `Expected a Statement path, but got ${Array.isArray(path9) ? "an array" : path9?.node?.type}`
1739
+ path10 && !Array.isArray(path10) && t.isStatement(path10.node),
1740
+ `Expected a Statement path, but got ${Array.isArray(path10) ? "an array" : path10?.node?.type}`
1722
1741
  );
1723
1742
  }
1724
- function assertNodePathIsVariableDeclarator(path9) {
1743
+ function assertNodePathIsVariableDeclarator(path10) {
1725
1744
  invariant(
1726
- path9 && !Array.isArray(path9) && t.isVariableDeclarator(path9.node),
1727
- `Expected an Identifier path, but got ${Array.isArray(path9) ? "an array" : path9?.node?.type}`
1745
+ path10 && !Array.isArray(path10) && t.isVariableDeclarator(path10.node),
1746
+ `Expected an Identifier path, but got ${Array.isArray(path10) ? "an array" : path10?.node?.type}`
1728
1747
  );
1729
1748
  }
1730
- function assertNodePathIsPattern(path9) {
1749
+ function assertNodePathIsPattern(path10) {
1731
1750
  invariant(
1732
- path9 && !Array.isArray(path9) && t.isPattern(path9.node),
1733
- `Expected a Pattern path, but got ${Array.isArray(path9) ? "an array" : path9?.node?.type}`
1751
+ path10 && !Array.isArray(path10) && t.isPattern(path10.node),
1752
+ `Expected a Pattern path, but got ${Array.isArray(path10) ? "an array" : path10?.node?.type}`
1734
1753
  );
1735
1754
  }
1736
1755
  function getExportDependencies(code, cache, cacheKey) {
@@ -1766,8 +1785,8 @@ function getExportDependencies(code, cache, cacheKey) {
1766
1785
  }
1767
1786
  let isWithinExportDestructuring = Boolean(
1768
1787
  identifier.findParent(
1769
- (path9) => Boolean(
1770
- path9.isPattern() && path9.parentPath?.isVariableDeclarator() && path9.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
1788
+ (path10) => Boolean(
1789
+ path10.isPattern() && path10.parentPath?.isVariableDeclarator() && path10.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
1771
1790
  )
1772
1791
  )
1773
1792
  );
@@ -1845,7 +1864,7 @@ function getExportDependencies(code, cache, cacheKey) {
1845
1864
  for (let specifier of node.specifiers) {
1846
1865
  if (t.isIdentifier(specifier.exported)) {
1847
1866
  let name = specifier.exported.name;
1848
- let specifierPath = exportPath.get("specifiers").find((path9) => path9.node === specifier);
1867
+ let specifierPath = exportPath.get("specifiers").find((path10) => path10.node === specifier);
1849
1868
  invariant(
1850
1869
  specifierPath,
1851
1870
  `Expected to find specifier path for ${name}`
@@ -1862,22 +1881,22 @@ function getExportDependencies(code, cache, cacheKey) {
1862
1881
  }
1863
1882
  );
1864
1883
  }
1865
- function getDependentIdentifiersForPath(path9, state) {
1884
+ function getDependentIdentifiersForPath(path10, state) {
1866
1885
  let { visited, identifiers } = state ?? {
1867
1886
  visited: /* @__PURE__ */ new Set(),
1868
1887
  identifiers: /* @__PURE__ */ new Set()
1869
1888
  };
1870
- if (visited.has(path9)) {
1889
+ if (visited.has(path10)) {
1871
1890
  return identifiers;
1872
1891
  }
1873
- visited.add(path9);
1874
- path9.traverse({
1875
- Identifier(path10) {
1876
- if (identifiers.has(path10)) {
1892
+ visited.add(path10);
1893
+ path10.traverse({
1894
+ Identifier(path11) {
1895
+ if (identifiers.has(path11)) {
1877
1896
  return;
1878
1897
  }
1879
- identifiers.add(path10);
1880
- let binding = path10.scope.getBinding(path10.node.name);
1898
+ identifiers.add(path11);
1899
+ let binding = path11.scope.getBinding(path11.node.name);
1881
1900
  if (!binding) {
1882
1901
  return;
1883
1902
  }
@@ -1899,7 +1918,7 @@ function getDependentIdentifiersForPath(path9, state) {
1899
1918
  }
1900
1919
  }
1901
1920
  });
1902
- let topLevelStatement = getTopLevelStatementPathForPath(path9);
1921
+ let topLevelStatement = getTopLevelStatementPathForPath(path10);
1903
1922
  let withinImportStatement = topLevelStatement.isImportDeclaration();
1904
1923
  let withinExportStatement = topLevelStatement.isExportDeclaration();
1905
1924
  if (!withinImportStatement && !withinExportStatement) {
@@ -1908,9 +1927,9 @@ function getDependentIdentifiersForPath(path9, state) {
1908
1927
  identifiers
1909
1928
  });
1910
1929
  }
1911
- if (withinExportStatement && path9.isIdentifier() && (t.isPattern(path9.parentPath.node) || // [foo]
1912
- t.isPattern(path9.parentPath.parentPath?.node))) {
1913
- let variableDeclarator = path9.findParent((p) => p.isVariableDeclarator());
1930
+ if (withinExportStatement && path10.isIdentifier() && (t.isPattern(path10.parentPath.node) || // [foo]
1931
+ t.isPattern(path10.parentPath.parentPath?.node))) {
1932
+ let variableDeclarator = path10.findParent((p) => p.isVariableDeclarator());
1914
1933
  assertNodePath(variableDeclarator);
1915
1934
  getDependentIdentifiersForPath(variableDeclarator, {
1916
1935
  visited,
@@ -1919,16 +1938,16 @@ function getDependentIdentifiersForPath(path9, state) {
1919
1938
  }
1920
1939
  return identifiers;
1921
1940
  }
1922
- function getTopLevelStatementPathForPath(path9) {
1923
- let ancestry = path9.getAncestry();
1941
+ function getTopLevelStatementPathForPath(path10) {
1942
+ let ancestry = path10.getAncestry();
1924
1943
  let topLevelStatement = ancestry[ancestry.length - 2];
1925
1944
  assertNodePathIsStatement(topLevelStatement);
1926
1945
  return topLevelStatement;
1927
1946
  }
1928
1947
  function getTopLevelStatementsForPaths(paths) {
1929
1948
  let topLevelStatements = /* @__PURE__ */ new Set();
1930
- for (let path9 of paths) {
1931
- let topLevelStatement = getTopLevelStatementPathForPath(path9);
1949
+ for (let path10 of paths) {
1950
+ let topLevelStatement = getTopLevelStatementPathForPath(path10);
1932
1951
  topLevelStatements.add(topLevelStatement.node);
1933
1952
  }
1934
1953
  return topLevelStatements;
@@ -2322,24 +2341,24 @@ function isNamedComponentExport(name) {
2322
2341
  }
2323
2342
  var decorateComponentExportsWithProps = (ast) => {
2324
2343
  const hocs = [];
2325
- function getHocUid(path9, hocName) {
2326
- const uid = path9.scope.generateUidIdentifier(hocName);
2344
+ function getHocUid(path10, hocName) {
2345
+ const uid = path10.scope.generateUidIdentifier(hocName);
2327
2346
  hocs.push([hocName, uid]);
2328
2347
  return uid;
2329
2348
  }
2330
2349
  traverse(ast, {
2331
- ExportDeclaration(path9) {
2332
- if (path9.isExportDefaultDeclaration()) {
2333
- const declaration = path9.get("declaration");
2350
+ ExportDeclaration(path10) {
2351
+ if (path10.isExportDefaultDeclaration()) {
2352
+ const declaration = path10.get("declaration");
2334
2353
  const expr = declaration.isExpression() ? declaration.node : declaration.isFunctionDeclaration() ? toFunctionExpression(declaration.node) : void 0;
2335
2354
  if (expr) {
2336
- const uid = getHocUid(path9, "UNSAFE_withComponentProps");
2355
+ const uid = getHocUid(path10, "UNSAFE_withComponentProps");
2337
2356
  declaration.replaceWith(t.callExpression(uid, [expr]));
2338
2357
  }
2339
2358
  return;
2340
2359
  }
2341
- if (path9.isExportNamedDeclaration()) {
2342
- const decl = path9.get("declaration");
2360
+ if (path10.isExportNamedDeclaration()) {
2361
+ const decl = path10.get("declaration");
2343
2362
  if (decl.isVariableDeclaration()) {
2344
2363
  decl.get("declarations").forEach((varDeclarator) => {
2345
2364
  const id = varDeclarator.get("id");
@@ -2349,7 +2368,7 @@ var decorateComponentExportsWithProps = (ast) => {
2349
2368
  if (!id.isIdentifier()) return;
2350
2369
  const { name } = id.node;
2351
2370
  if (!isNamedComponentExport(name)) return;
2352
- const uid = getHocUid(path9, `UNSAFE_with${name}Props`);
2371
+ const uid = getHocUid(path10, `UNSAFE_with${name}Props`);
2353
2372
  init.replaceWith(t.callExpression(uid, [expr]));
2354
2373
  });
2355
2374
  return;
@@ -2359,7 +2378,7 @@ var decorateComponentExportsWithProps = (ast) => {
2359
2378
  if (!id) return;
2360
2379
  const { name } = id;
2361
2380
  if (!isNamedComponentExport(name)) return;
2362
- const uid = getHocUid(path9, `UNSAFE_with${name}Props`);
2381
+ const uid = getHocUid(path10, `UNSAFE_with${name}Props`);
2363
2382
  decl.replaceWith(
2364
2383
  t.variableDeclaration("const", [
2365
2384
  t.variableDeclarator(
@@ -2480,6 +2499,222 @@ function warnOnClientSourceMaps() {
2480
2499
  };
2481
2500
  }
2482
2501
 
2502
+ // vite/plugins/prerender.ts
2503
+ var import_promises2 = require("fs/promises");
2504
+ var import_node_path = __toESM(require("path"));
2505
+ function normalizePrerenderRequest(input) {
2506
+ if (typeof input === "string" || input instanceof Request) {
2507
+ return { request: input, metadata: void 0 };
2508
+ }
2509
+ return { request: input.request, metadata: input.metadata };
2510
+ }
2511
+ function normalizePostProcessResult(result) {
2512
+ if (Array.isArray(result)) {
2513
+ return { files: result, requests: [] };
2514
+ }
2515
+ return { files: result.files, requests: result.requests ?? [] };
2516
+ }
2517
+ function prerender(options) {
2518
+ const {
2519
+ config,
2520
+ requests,
2521
+ postProcess = defaultPostProcess,
2522
+ handleError = defaultHandleError,
2523
+ logFile,
2524
+ finalize
2525
+ } = options;
2526
+ let viteConfig;
2527
+ return {
2528
+ name: "prerender",
2529
+ configResolved(resolvedConfig) {
2530
+ viteConfig = resolvedConfig;
2531
+ },
2532
+ writeBundle: {
2533
+ async handler() {
2534
+ const pluginContext = this;
2535
+ const rawRequests = typeof requests === "function" ? await requests.call(pluginContext) : requests;
2536
+ const prerenderRequests = rawRequests.map(normalizePrerenderRequest);
2537
+ if (prerenderRequests.length === 0) {
2538
+ return;
2539
+ }
2540
+ const prerenderConfig = typeof config === "function" ? await config.call(pluginContext) : config;
2541
+ const {
2542
+ buildDirectory = viteConfig.environments.client.build.outDir,
2543
+ concurrency = 1,
2544
+ retryCount = 0,
2545
+ retryDelay = 500,
2546
+ maxRedirects = 0,
2547
+ timeout = 1e4
2548
+ } = prerenderConfig ?? {};
2549
+ const previewServer = await startPreviewServer(viteConfig);
2550
+ try {
2551
+ const baseUrl = getResolvedUrl(previewServer);
2552
+ async function prerenderRequest(input, metadata) {
2553
+ let attemptCount = 0;
2554
+ let redirectCount = 0;
2555
+ const request = new Request(input);
2556
+ const url2 = new URL(request.url);
2557
+ if (url2.origin !== baseUrl.origin) {
2558
+ url2.hostname = baseUrl.hostname;
2559
+ url2.protocol = baseUrl.protocol;
2560
+ url2.port = baseUrl.port;
2561
+ }
2562
+ async function attempt(url3) {
2563
+ try {
2564
+ const signal = AbortSignal.timeout(timeout);
2565
+ const prerenderReq = new Request(url3, request);
2566
+ const response = await fetch(prerenderReq, {
2567
+ redirect: "manual",
2568
+ signal
2569
+ });
2570
+ if (response.status >= 300 && response.status < 400 && response.headers.has("location") && ++redirectCount <= maxRedirects) {
2571
+ const location = response.headers.get("location");
2572
+ const responseURL = new URL(response.url);
2573
+ const locationUrl = new URL(location, response.url);
2574
+ if (responseURL.origin !== locationUrl.origin) {
2575
+ return await postProcess.call(
2576
+ pluginContext,
2577
+ request,
2578
+ response,
2579
+ metadata
2580
+ );
2581
+ }
2582
+ const redirectUrl = new URL(location, url3);
2583
+ return await attempt(redirectUrl);
2584
+ }
2585
+ if (response.status >= 500 && ++attemptCount <= retryCount) {
2586
+ await new Promise(
2587
+ (resolve6) => setTimeout(resolve6, retryDelay)
2588
+ );
2589
+ return attempt(url3);
2590
+ }
2591
+ return await postProcess.call(
2592
+ pluginContext,
2593
+ request,
2594
+ response,
2595
+ metadata
2596
+ );
2597
+ } catch (error) {
2598
+ if (++attemptCount <= retryCount) {
2599
+ await new Promise(
2600
+ (resolve6) => setTimeout(resolve6, retryDelay)
2601
+ );
2602
+ return attempt(url3);
2603
+ }
2604
+ handleError.call(
2605
+ pluginContext,
2606
+ request,
2607
+ error instanceof Error ? error : new Error(error?.toString() ?? "Unknown error"),
2608
+ metadata
2609
+ );
2610
+ return [];
2611
+ }
2612
+ }
2613
+ return attempt(url2);
2614
+ }
2615
+ async function prerender2(input, metadata) {
2616
+ const result = await prerenderRequest(input, metadata);
2617
+ const { files, requests: requests2 } = normalizePostProcessResult(result);
2618
+ for (const file of files) {
2619
+ await writePrerenderFile(file, metadata);
2620
+ }
2621
+ for (const followUp of requests2) {
2622
+ const normalized = normalizePrerenderRequest(followUp);
2623
+ await prerender2(normalized.request, normalized.metadata);
2624
+ }
2625
+ }
2626
+ async function writePrerenderFile(file, metadata) {
2627
+ const normalizedPath = file.path.startsWith("/") ? file.path.slice(1) : file.path;
2628
+ const outputPath = import_node_path.default.join(
2629
+ buildDirectory,
2630
+ ...normalizedPath.split("/")
2631
+ );
2632
+ await (0, import_promises2.mkdir)(import_node_path.default.dirname(outputPath), { recursive: true });
2633
+ await (0, import_promises2.writeFile)(outputPath, file.contents);
2634
+ const relativePath = import_node_path.default.relative(viteConfig.root, outputPath);
2635
+ if (logFile) {
2636
+ logFile.call(pluginContext, relativePath, metadata);
2637
+ }
2638
+ return relativePath;
2639
+ }
2640
+ const pMap = await import("p-map");
2641
+ await pMap.default(
2642
+ prerenderRequests,
2643
+ async ({ request, metadata }) => {
2644
+ await prerender2(request, metadata);
2645
+ },
2646
+ { concurrency }
2647
+ );
2648
+ if (finalize) {
2649
+ await finalize.call(pluginContext, buildDirectory);
2650
+ }
2651
+ } finally {
2652
+ await new Promise((resolve6, reject) => {
2653
+ previewServer.httpServer.close((err2) => {
2654
+ if (err2) {
2655
+ reject(err2);
2656
+ } else {
2657
+ resolve6();
2658
+ }
2659
+ });
2660
+ });
2661
+ }
2662
+ }
2663
+ }
2664
+ };
2665
+ }
2666
+ async function defaultPostProcess(request, response) {
2667
+ const prerenderPath = new URL(request.url).pathname;
2668
+ if (!response.ok) {
2669
+ throw new Error(
2670
+ `Prerender: Request failed for ${prerenderPath}: ${response.status} ${response.statusText}`
2671
+ );
2672
+ }
2673
+ return [
2674
+ {
2675
+ path: `${prerenderPath}/index.html`,
2676
+ contents: await response.text()
2677
+ }
2678
+ ];
2679
+ }
2680
+ function defaultHandleError(request, error) {
2681
+ const prerenderPath = new URL(request.url).pathname;
2682
+ if (request.signal?.aborted) {
2683
+ throw new Error(
2684
+ `Prerender: Request timed out for ${prerenderPath}: ${error.message}`
2685
+ );
2686
+ }
2687
+ throw new Error(
2688
+ `Prerender: Request failed for ${prerenderPath}: ${error.message}`
2689
+ );
2690
+ }
2691
+ async function startPreviewServer(viteConfig) {
2692
+ const vite2 = await import("vite");
2693
+ try {
2694
+ return await vite2.preview({
2695
+ configFile: viteConfig.configFile,
2696
+ logLevel: "silent",
2697
+ preview: {
2698
+ port: 0,
2699
+ open: false
2700
+ }
2701
+ });
2702
+ } catch (error) {
2703
+ throw new Error("Prerender: Failed to start Vite preview server", {
2704
+ cause: error
2705
+ });
2706
+ }
2707
+ }
2708
+ function getResolvedUrl(previewServer) {
2709
+ const baseUrl = previewServer.resolvedUrls?.local[0];
2710
+ if (!baseUrl) {
2711
+ throw new Error(
2712
+ "Prerender: No resolved URL is available from the Vite preview server"
2713
+ );
2714
+ }
2715
+ return new URL(baseUrl);
2716
+ }
2717
+
2483
2718
  // vite/plugin.ts
2484
2719
  function extractPluginContext(viteConfig) {
2485
2720
  return viteConfig["__reactRouterPluginContext"];
@@ -2541,8 +2776,8 @@ var virtualHmrRuntime = create("hmr-runtime");
2541
2776
  var virtualInjectHmrRuntime = create("inject-hmr-runtime");
2542
2777
  var normalizeRelativeFilePath = (file, reactRouterConfig) => {
2543
2778
  let vite2 = getVite();
2544
- let fullPath = path6.resolve(reactRouterConfig.appDirectory, file);
2545
- let relativePath = path6.relative(reactRouterConfig.appDirectory, fullPath);
2779
+ let fullPath = path7.resolve(reactRouterConfig.appDirectory, file);
2780
+ let relativePath = path7.relative(reactRouterConfig.appDirectory, fullPath);
2546
2781
  return vite2.normalizePath(relativePath).split("?")[0];
2547
2782
  };
2548
2783
  var virtual = {
@@ -2565,7 +2800,7 @@ var getHash = (source, maxLength) => {
2565
2800
  var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
2566
2801
  let vite2 = getVite();
2567
2802
  let rootRelativeFilePath = vite2.normalizePath(
2568
- path6.relative(ctx.rootDirectory, absoluteFilePath)
2803
+ path7.relative(ctx.rootDirectory, absoluteFilePath)
2569
2804
  );
2570
2805
  let entryChunk = viteManifest[rootRelativeFilePath];
2571
2806
  if (!entryChunk) {
@@ -2656,7 +2891,7 @@ function resolveDependantChunks(viteManifest, entryChunks) {
2656
2891
  function getAllDynamicCssFiles(ctx, viteManifest) {
2657
2892
  let allDynamicCssFiles = /* @__PURE__ */ new Set();
2658
2893
  for (let route of Object.values(ctx.reactRouterConfig.routes)) {
2659
- let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
2894
+ let routeFile = path7.join(ctx.reactRouterConfig.appDirectory, route.file);
2660
2895
  let entryChunk = resolveChunk(
2661
2896
  ctx,
2662
2897
  viteManifest,
@@ -2695,8 +2930,8 @@ function dedupe(array2) {
2695
2930
  return [...new Set(array2)];
2696
2931
  }
2697
2932
  var writeFileSafe = async (file, contents) => {
2698
- await (0, import_promises2.mkdir)(path6.dirname(file), { recursive: true });
2699
- await (0, import_promises2.writeFile)(file, contents);
2933
+ await (0, import_promises3.mkdir)(path7.dirname(file), { recursive: true });
2934
+ await (0, import_promises3.writeFile)(file, contents);
2700
2935
  };
2701
2936
  var getExportNames = (code) => {
2702
2937
  let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
@@ -2721,7 +2956,7 @@ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile)
2721
2956
  }
2722
2957
  let ssr = true;
2723
2958
  let { pluginContainer, moduleGraph } = viteChildCompiler;
2724
- let routePath = path6.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
2959
+ let routePath = path7.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
2725
2960
  let url2 = resolveFileUrl(ctx, routePath);
2726
2961
  let resolveId = async () => {
2727
2962
  let result = await pluginContainer.resolveId(url2, void 0, { ssr });
@@ -2730,7 +2965,7 @@ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile)
2730
2965
  };
2731
2966
  let [id, code] = await Promise.all([
2732
2967
  resolveId(),
2733
- readRouteFile?.() ?? (0, import_promises2.readFile)(routePath, "utf-8"),
2968
+ readRouteFile?.() ?? (0, import_promises3.readFile)(routePath, "utf-8"),
2734
2969
  // pluginContainer.transform(...) fails if we don't do this first:
2735
2970
  moduleGraph.ensureEntryFromUrl(url2, ssr)
2736
2971
  ]);
@@ -2763,12 +2998,12 @@ var resolveEnvironmentBuildContext = ({
2763
2998
  };
2764
2999
  return resolvedBuildContext;
2765
3000
  };
2766
- var getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
3001
+ var getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
2767
3002
  reactRouterConfig.buildDirectory,
2768
3003
  "server",
2769
3004
  ...serverBundleId ? [serverBundleId] : []
2770
3005
  );
2771
- var getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
3006
+ var getClientBuildDirectory = (reactRouterConfig) => path7.join(reactRouterConfig.buildDirectory, "client");
2772
3007
  var getServerBundleRouteIds = (vitePluginContext, ctx) => {
2773
3008
  if (!ctx.buildManifest) {
2774
3009
  return void 0;
@@ -2786,14 +3021,14 @@ var getServerBundleRouteIds = (vitePluginContext, ctx) => {
2786
3021
  );
2787
3022
  return Object.keys(serverBundleRoutes);
2788
3023
  };
2789
- var defaultEntriesDir = path6.resolve(
2790
- path6.dirname(require.resolve("@react-router/dev/package.json")),
3024
+ var defaultEntriesDir = path7.resolve(
3025
+ path7.dirname(require.resolve("@react-router/dev/package.json")),
2791
3026
  "dist",
2792
3027
  "config",
2793
3028
  "defaults"
2794
3029
  );
2795
3030
  var defaultEntries = (0, import_node_fs2.readdirSync)(defaultEntriesDir).map(
2796
- (filename2) => path6.join(defaultEntriesDir, filename2)
3031
+ (filename2) => path7.join(defaultEntriesDir, filename2)
2797
3032
  );
2798
3033
  invariant(defaultEntries.length > 0, "No default entries found");
2799
3034
  var reactRouterDevLoadContext = () => void 0;
@@ -2843,6 +3078,8 @@ var reactRouterVitePlugin = () => {
2843
3078
  firstLoad = false;
2844
3079
  ctx = {
2845
3080
  environmentBuildContext,
3081
+ reactRouterManifest: null,
3082
+ prerenderPaths: null,
2846
3083
  reactRouterConfig,
2847
3084
  rootDirectory,
2848
3085
  entryClientFilePath,
@@ -2867,6 +3104,12 @@ var reactRouterVitePlugin = () => {
2867
3104
  ctx.reactRouterConfig.ssr,
2868
3105
  routes
2869
3106
  );
3107
+ if (!ctx.prerenderPaths) {
3108
+ ctx.prerenderPaths = /* @__PURE__ */ new Set();
3109
+ }
3110
+ for (let path10 of prerenderPaths) {
3111
+ ctx.prerenderPaths.add(path10);
3112
+ }
2870
3113
  let isSpaMode = isSpaModeEnabled(ctx.reactRouterConfig);
2871
3114
  return `
2872
3115
  import * as entryServer from ${JSON.stringify(
@@ -2889,7 +3132,7 @@ var reactRouterVitePlugin = () => {
2889
3132
  virtual.serverManifest.id
2890
3133
  )};
2891
3134
  export const assetsBuildDirectory = ${JSON.stringify(
2892
- path6.relative(
3135
+ path7.relative(
2893
3136
  ctx.rootDirectory,
2894
3137
  getClientBuildDirectory(ctx.reactRouterConfig)
2895
3138
  )
@@ -2929,8 +3172,8 @@ var reactRouterVitePlugin = () => {
2929
3172
  `;
2930
3173
  };
2931
3174
  let loadViteManifest = async (directory) => {
2932
- let manifestContents = await (0, import_promises2.readFile)(
2933
- path6.resolve(directory, ".vite", "manifest.json"),
3175
+ let manifestContents = await (0, import_promises3.readFile)(
3176
+ path7.resolve(directory, ".vite", "manifest.json"),
2934
3177
  "utf-8"
2935
3178
  );
2936
3179
  return JSON.parse(manifestContents);
@@ -2954,8 +3197,8 @@ var reactRouterVitePlugin = () => {
2954
3197
  const entryNormalizedPath = "parentPath" in entry && typeof entry.parentPath === "string" ? entry.parentPath : entry.path;
2955
3198
  let contents;
2956
3199
  try {
2957
- contents = await (0, import_promises2.readFile)(
2958
- path6.join(entryNormalizedPath, entry.name),
3200
+ contents = await (0, import_promises3.readFile)(
3201
+ path7.join(entryNormalizedPath, entry.name),
2959
3202
  "utf-8"
2960
3203
  );
2961
3204
  } catch (e) {
@@ -2964,9 +3207,9 @@ var reactRouterVitePlugin = () => {
2964
3207
  }
2965
3208
  let hash = (0, import_node_crypto.createHash)("sha384").update(contents).digest().toString("base64");
2966
3209
  let filepath = getVite().normalizePath(
2967
- path6.relative(
3210
+ path7.relative(
2968
3211
  clientBuildDirectory,
2969
- path6.join(entryNormalizedPath, entry.name)
3212
+ path7.join(entryNormalizedPath, entry.name)
2970
3213
  )
2971
3214
  );
2972
3215
  sriManifest[`${ctx2.publicPath}${filepath}`] = `sha384-${hash}`;
@@ -2999,7 +3242,7 @@ var reactRouterVitePlugin = () => {
2999
3242
  );
3000
3243
  let enforceSplitRouteModules = ctx.reactRouterConfig.future.v8_splitRouteModules === "enforce";
3001
3244
  for (let route of Object.values(ctx.reactRouterConfig.routes)) {
3002
- let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
3245
+ let routeFile = path7.join(ctx.reactRouterConfig.appDirectory, route.file);
3003
3246
  let sourceExports = routeManifestExports[route.id];
3004
3247
  let hasClientAction = sourceExports.includes("clientAction");
3005
3248
  let hasClientLoader = sourceExports.includes("clientLoader");
@@ -3034,6 +3277,7 @@ var reactRouterVitePlugin = () => {
3034
3277
  hasClientAction,
3035
3278
  hasClientLoader,
3036
3279
  hasClientMiddleware,
3280
+ hasDefaultExport: sourceExports.includes("default"),
3037
3281
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
3038
3282
  ...getReactRouterManifestBuildAssets(
3039
3283
  ctx,
@@ -3071,7 +3315,7 @@ var reactRouterVitePlugin = () => {
3071
3315
  }
3072
3316
  let fingerprintedValues = { entry, routes: browserRoutes };
3073
3317
  let version = getHash(JSON.stringify(fingerprintedValues), 8);
3074
- let manifestPath = path6.posix.join(
3318
+ let manifestPath = path7.posix.join(
3075
3319
  viteConfig2.build.assetsDir,
3076
3320
  `manifest-${version}.js`
3077
3321
  );
@@ -3083,7 +3327,7 @@ var reactRouterVitePlugin = () => {
3083
3327
  sri: void 0
3084
3328
  };
3085
3329
  await writeFileSafe(
3086
- path6.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
3330
+ path7.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
3087
3331
  `window.__reactRouterManifest=${JSON.stringify(
3088
3332
  reactRouterBrowserManifest
3089
3333
  )};`
@@ -3159,6 +3403,7 @@ var reactRouterVitePlugin = () => {
3159
3403
  hasClientAction,
3160
3404
  hasClientLoader,
3161
3405
  hasClientMiddleware,
3406
+ hasDefaultExport: sourceExports.includes("default"),
3162
3407
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
3163
3408
  imports: []
3164
3409
  };
@@ -3541,31 +3786,61 @@ var reactRouterVitePlugin = () => {
3541
3786
  };
3542
3787
  },
3543
3788
  configurePreviewServer(previewServer) {
3789
+ let cachedHandler = null;
3790
+ async function getHandler() {
3791
+ if (cachedHandler) return cachedHandler;
3792
+ let serverBuildFiles = [];
3793
+ let buildManifest = ctx.buildManifest ?? (ctx.reactRouterConfig.serverBundles ? await getBuildManifest({
3794
+ reactRouterConfig: ctx.reactRouterConfig,
3795
+ rootDirectory: ctx.rootDirectory
3796
+ }) : null);
3797
+ if (buildManifest?.serverBundles) {
3798
+ for (let bundle of Object.values(buildManifest.serverBundles)) {
3799
+ serverBuildFiles.push(
3800
+ path7.resolve(ctx.rootDirectory, bundle.file)
3801
+ );
3802
+ }
3803
+ } else {
3804
+ let serverEntryPath = path7.resolve(
3805
+ getServerBuildDirectory(ctx.reactRouterConfig),
3806
+ "index.js"
3807
+ );
3808
+ serverBuildFiles.push(serverEntryPath);
3809
+ }
3810
+ let handlers = [];
3811
+ for (let file of serverBuildFiles) {
3812
+ let build = await import(url.pathToFileURL(file).href);
3813
+ handlers.push((0, import_react_router2.createRequestHandler)(build, "production"));
3814
+ }
3815
+ cachedHandler = async (request, loadContext) => {
3816
+ let response;
3817
+ for (let handler of handlers) {
3818
+ response = await handler(request, loadContext);
3819
+ if (response.status !== 404) {
3820
+ return response;
3821
+ }
3822
+ }
3823
+ if (response) {
3824
+ return response;
3825
+ }
3826
+ throw new Error("No handlers were found for the request.");
3827
+ };
3828
+ return cachedHandler;
3829
+ }
3544
3830
  return () => {
3545
3831
  if (!ctx.reactRouterConfig.ssr) {
3546
3832
  return;
3547
3833
  }
3548
3834
  previewServer.middlewares.use(async (req, res, next) => {
3549
3835
  try {
3550
- let serverBuildDirectory = getServerBuildDirectory(
3551
- ctx.reactRouterConfig
3552
- );
3553
- let serverBuildFile = path6.resolve(
3554
- serverBuildDirectory,
3555
- "index.js"
3836
+ let handler = await getHandler();
3837
+ let request = await fromNodeRequest(req, res);
3838
+ let response = await handler(
3839
+ request,
3840
+ await reactRouterDevLoadContext(request)
3556
3841
  );
3557
- let build = await import(url.pathToFileURL(serverBuildFile).href);
3558
- let handler = (0, import_react_router2.createRequestHandler)(build, "production");
3559
- let nodeHandler = async (nodeReq, nodeRes) => {
3560
- let req2 = await fromNodeRequest(nodeReq, nodeRes);
3561
- let res2 = await handler(
3562
- req2,
3563
- await reactRouterDevLoadContext(req2)
3564
- );
3565
- const { sendResponse } = await import("@remix-run/node-fetch-server");
3566
- await sendResponse(nodeRes, res2);
3567
- };
3568
- await nodeHandler(req, res);
3842
+ const { sendResponse } = await import("@remix-run/node-fetch-server");
3843
+ await sendResponse(res, response);
3569
3844
  } catch (error) {
3570
3845
  next(error);
3571
3846
  }
@@ -3592,19 +3867,19 @@ var reactRouterVitePlugin = () => {
3592
3867
  let removedAssetPaths = [];
3593
3868
  let copiedAssetPaths = [];
3594
3869
  for (let ssrAssetPath of ssrAssetPaths) {
3595
- let src = path6.join(serverBuildDirectory, ssrAssetPath);
3596
- let dest = path6.join(clientBuildDirectory, ssrAssetPath);
3870
+ let src = path7.join(serverBuildDirectory, ssrAssetPath);
3871
+ let dest = path7.join(clientBuildDirectory, ssrAssetPath);
3597
3872
  if (!userSsrEmitAssets) {
3598
3873
  if (!(0, import_node_fs2.existsSync)(dest)) {
3599
- await (0, import_promises2.mkdir)(path6.dirname(dest), { recursive: true });
3600
- await (0, import_promises2.rename)(src, dest);
3874
+ await (0, import_promises3.mkdir)(path7.dirname(dest), { recursive: true });
3875
+ await (0, import_promises3.rename)(src, dest);
3601
3876
  movedAssetPaths.push(dest);
3602
3877
  } else {
3603
- await (0, import_promises2.rm)(src, { force: true, recursive: true });
3878
+ await (0, import_promises3.rm)(src, { force: true, recursive: true });
3604
3879
  removedAssetPaths.push(dest);
3605
3880
  }
3606
3881
  } else if (!(0, import_node_fs2.existsSync)(dest)) {
3607
- await (0, import_promises2.cp)(src, dest, { recursive: true });
3882
+ await (0, import_promises3.cp)(src, dest, { recursive: true });
3608
3883
  copiedAssetPaths.push(dest);
3609
3884
  }
3610
3885
  }
@@ -3614,21 +3889,21 @@ var reactRouterVitePlugin = () => {
3614
3889
  );
3615
3890
  await Promise.all(
3616
3891
  ssrCssPaths.map(async (cssPath) => {
3617
- let src = path6.join(serverBuildDirectory, cssPath);
3618
- await (0, import_promises2.rm)(src, { force: true, recursive: true });
3892
+ let src = path7.join(serverBuildDirectory, cssPath);
3893
+ await (0, import_promises3.rm)(src, { force: true, recursive: true });
3619
3894
  removedAssetPaths.push(src);
3620
3895
  })
3621
3896
  );
3622
3897
  }
3623
3898
  let cleanedAssetPaths = [...removedAssetPaths, ...movedAssetPaths];
3624
3899
  let handledAssetPaths = [...cleanedAssetPaths, ...copiedAssetPaths];
3625
- let cleanedAssetDirs = new Set(cleanedAssetPaths.map(path6.dirname));
3900
+ let cleanedAssetDirs = new Set(cleanedAssetPaths.map(path7.dirname));
3626
3901
  await Promise.all(
3627
3902
  Array.from(cleanedAssetDirs).map(async (dir) => {
3628
3903
  try {
3629
- const files = await (0, import_promises2.readdir)(dir, { recursive: true });
3904
+ const files = await (0, import_promises3.readdir)(dir, { recursive: true });
3630
3905
  if (files.length === 0) {
3631
- await (0, import_promises2.rm)(dir, { force: true, recursive: true });
3906
+ await (0, import_promises3.rm)(dir, { force: true, recursive: true });
3632
3907
  }
3633
3908
  } catch {
3634
3909
  }
@@ -3644,7 +3919,7 @@ var reactRouterVitePlugin = () => {
3644
3919
  [
3645
3920
  `${import_picocolors4.default.green("\u2713")} ${message}`,
3646
3921
  ...paths.map(
3647
- (assetPath) => import_picocolors4.default.dim(path6.relative(ctx.rootDirectory, assetPath))
3922
+ (assetPath) => import_picocolors4.default.dim(path7.relative(ctx.rootDirectory, assetPath))
3648
3923
  )
3649
3924
  ].join("\n")
3650
3925
  );
@@ -3665,6 +3940,9 @@ var reactRouterVitePlugin = () => {
3665
3940
  if (handledAssetPaths.length) {
3666
3941
  viteConfig.logger.info("");
3667
3942
  }
3943
+ if (future.unstable_previewServerPrerendering) {
3944
+ return;
3945
+ }
3668
3946
  process.env.IS_RR_BUILD_REQUEST = "yes";
3669
3947
  if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
3670
3948
  await handlePrerender(
@@ -3738,7 +4016,7 @@ var reactRouterVitePlugin = () => {
3738
4016
  );
3739
4017
  let isMainChunkExport = (name) => !chunkedExports.includes(name);
3740
4018
  let mainChunkReexports = sourceExports.filter(isMainChunkExport).join(", ");
3741
- let chunkBasePath = `./${path6.basename(id)}`;
4019
+ let chunkBasePath = `./${path7.basename(id)}`;
3742
4020
  return [
3743
4021
  `export { ${mainChunkReexports} } from "${getRouteChunkModuleId(
3744
4022
  chunkBasePath,
@@ -3758,7 +4036,7 @@ var reactRouterVitePlugin = () => {
3758
4036
  async transform(code, id, options) {
3759
4037
  if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
3760
4038
  let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
3761
- let routeFileName = path6.basename(routeModuleId);
4039
+ let routeFileName = path7.basename(routeModuleId);
3762
4040
  let sourceExports = await getRouteModuleExports(
3763
4041
  viteChildCompiler,
3764
4042
  ctx,
@@ -3838,6 +4116,7 @@ var reactRouterVitePlugin = () => {
3838
4116
  viteConfig,
3839
4117
  routeIds
3840
4118
  })).reactRouterServerManifest : await getReactRouterManifestForDev();
4119
+ ctx.reactRouterManifest = reactRouterManifest;
3841
4120
  if (!ctx.reactRouterConfig.ssr) {
3842
4121
  invariant(viteConfig);
3843
4122
  validateSsrFalsePrerenderExports(
@@ -3885,7 +4164,7 @@ var reactRouterVitePlugin = () => {
3885
4164
  }
3886
4165
  let vite2 = getVite();
3887
4166
  let importerShort = vite2.normalizePath(
3888
- path6.relative(ctx.rootDirectory, importer)
4167
+ path7.relative(ctx.rootDirectory, importer)
3889
4168
  );
3890
4169
  if (isRoute(ctx.reactRouterConfig, importer)) {
3891
4170
  let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
@@ -4007,17 +4286,17 @@ var reactRouterVitePlugin = () => {
4007
4286
  },
4008
4287
  async load(id) {
4009
4288
  if (id !== virtualHmrRuntime.resolvedId) return;
4010
- let reactRefreshDir = path6.dirname(
4289
+ let reactRefreshDir = path7.dirname(
4011
4290
  require.resolve("react-refresh/package.json")
4012
4291
  );
4013
- let reactRefreshRuntimePath = path6.join(
4292
+ let reactRefreshRuntimePath = path7.join(
4014
4293
  reactRefreshDir,
4015
4294
  "cjs/react-refresh-runtime.development.js"
4016
4295
  );
4017
4296
  return [
4018
4297
  "const exports = {}",
4019
- await (0, import_promises2.readFile)(reactRefreshRuntimePath, "utf8"),
4020
- await (0, import_promises2.readFile)(require.resolve("./static/refresh-utils.mjs"), "utf8"),
4298
+ await (0, import_promises3.readFile)(reactRefreshRuntimePath, "utf8"),
4299
+ await (0, import_promises3.readFile)(require.resolve("./static/refresh-utils.mjs"), "utf8"),
4021
4300
  "export default exports"
4022
4301
  ].join("\n");
4023
4302
  }
@@ -4117,6 +4396,225 @@ var reactRouterVitePlugin = () => {
4117
4396
  }
4118
4397
  }
4119
4398
  },
4399
+ prerender({
4400
+ config() {
4401
+ process.env.IS_RR_BUILD_REQUEST = "yes";
4402
+ return {
4403
+ // Required as viteConfig.environments.client.build.outDir is only available in Vite v6+
4404
+ buildDirectory: getClientBuildDirectory(ctx.reactRouterConfig),
4405
+ concurrency: getPrerenderConcurrencyConfig(ctx.reactRouterConfig)
4406
+ };
4407
+ },
4408
+ async requests() {
4409
+ invariant(viteConfig);
4410
+ let { future } = ctx.reactRouterConfig;
4411
+ if (future.v8_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
4412
+ return [];
4413
+ }
4414
+ if (!future.unstable_previewServerPrerendering) {
4415
+ return [];
4416
+ }
4417
+ let requests = [];
4418
+ if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
4419
+ invariant(ctx.prerenderPaths !== null, "Prerender paths missing");
4420
+ invariant(
4421
+ ctx.reactRouterManifest !== null,
4422
+ "Prerender manifest missing"
4423
+ );
4424
+ let { reactRouterConfig, reactRouterManifest, prerenderPaths } = ctx;
4425
+ assertPrerenderPathsMatchRoutes(
4426
+ reactRouterConfig,
4427
+ Array.from(prerenderPaths)
4428
+ );
4429
+ let buildRoutes = createPrerenderRoutes(reactRouterManifest.routes);
4430
+ for (let prerenderPath of prerenderPaths) {
4431
+ let matches = (0, import_react_router2.matchRoutes)(
4432
+ buildRoutes,
4433
+ `/${prerenderPath}/`.replace(/^\/\/+/, "/")
4434
+ );
4435
+ if (!matches) {
4436
+ continue;
4437
+ }
4438
+ let leafRoute = matches[matches.length - 1].route;
4439
+ let manifestRoute = reactRouterManifest.routes[leafRoute.id];
4440
+ let isResourceRoute = manifestRoute && !manifestRoute.hasDefaultExport && !manifestRoute.hasErrorBoundary;
4441
+ if (isResourceRoute) {
4442
+ if (manifestRoute?.hasLoader) {
4443
+ requests.push(
4444
+ // Prerender a .data file for turbo-stream consumption
4445
+ createDataRequest(
4446
+ prerenderPath,
4447
+ reactRouterConfig,
4448
+ [leafRoute.id],
4449
+ true
4450
+ ),
4451
+ // Prerender a raw file for external consumption
4452
+ createResourceRouteRequest(prerenderPath, reactRouterConfig)
4453
+ );
4454
+ } else {
4455
+ viteConfig.logger.warn(
4456
+ `\u26A0\uFE0F Skipping prerendering for resource route without a loader: ${leafRoute.id}`
4457
+ );
4458
+ }
4459
+ } else {
4460
+ let hasLoaders = matches.some(
4461
+ (m) => reactRouterManifest.routes[m.route.id]?.hasLoader
4462
+ );
4463
+ if (hasLoaders) {
4464
+ requests.push(
4465
+ createDataRequest(prerenderPath, reactRouterConfig, null)
4466
+ );
4467
+ } else {
4468
+ requests.push(
4469
+ createRouteRequest(prerenderPath, reactRouterConfig)
4470
+ );
4471
+ }
4472
+ }
4473
+ }
4474
+ }
4475
+ if (!ctx.reactRouterConfig.ssr) {
4476
+ requests.push(createSpaModeRequest(ctx.reactRouterConfig));
4477
+ }
4478
+ return requests;
4479
+ },
4480
+ async postProcess(request, response, metadata) {
4481
+ invariant(metadata);
4482
+ if (metadata.type === "data") {
4483
+ let pathname2 = new URL(request.url).pathname;
4484
+ if (response.status !== 200 && response.status !== 202) {
4485
+ throw new Error(
4486
+ `Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${metadata.path}\` path.
4487
+ ${pathname2}`,
4488
+ { cause: response }
4489
+ );
4490
+ }
4491
+ let data = await response.text();
4492
+ return {
4493
+ files: [
4494
+ {
4495
+ path: pathname2,
4496
+ contents: data
4497
+ }
4498
+ ],
4499
+ // After saving the .data file, request the HTML page.
4500
+ // The data is passed along to be embedded in the response header.
4501
+ requests: !metadata.isResourceRoute ? [createRouteRequest(metadata.path, ctx.reactRouterConfig, data)] : []
4502
+ };
4503
+ }
4504
+ if (metadata.type === "resource") {
4505
+ let pathname2 = new URL(request.url).pathname;
4506
+ let contents = new Uint8Array(await response.arrayBuffer());
4507
+ if (response.status !== 200) {
4508
+ throw new Error(
4509
+ `Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${pathname2}\` path.
4510
+ ${new TextDecoder().decode(contents)}`
4511
+ );
4512
+ }
4513
+ return [
4514
+ {
4515
+ path: pathname2,
4516
+ contents
4517
+ }
4518
+ ];
4519
+ }
4520
+ let html = await response.text();
4521
+ if (metadata.type === "spa") {
4522
+ if (response.status !== 200) {
4523
+ throw new Error(
4524
+ `SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your SPA Fallback HTML file.
4525
+ ` + html
4526
+ );
4527
+ }
4528
+ if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
4529
+ throw new Error(
4530
+ "SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
4531
+ );
4532
+ }
4533
+ return [
4534
+ {
4535
+ path: "/__spa-fallback.html",
4536
+ contents: html
4537
+ }
4538
+ ];
4539
+ }
4540
+ let pathname = new URL(request.url).pathname;
4541
+ if (redirectStatusCodes.has(response.status)) {
4542
+ let location = response.headers.get("Location");
4543
+ let delay = response.status === 302 ? 2 : 0;
4544
+ let escapedLocation = escapeHtml(location ?? "");
4545
+ let escapedPathname = escapeHtml(pathname);
4546
+ html = `<!doctype html>
4547
+ <head>
4548
+ <title>Redirecting to: ${escapedLocation}</title>
4549
+ <meta http-equiv="refresh" content="${delay};url=${escapedLocation}">
4550
+ <meta name="robots" content="noindex">
4551
+ </head>
4552
+ <body>
4553
+ <a href="${escapedLocation}">
4554
+ Redirecting from <code>${escapedPathname}</code> to <code>${escapedLocation}</code>
4555
+ </a>
4556
+ </body>
4557
+ </html>`;
4558
+ } else if (response.status !== 200) {
4559
+ throw new Error(
4560
+ `Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${pathname}\` path.
4561
+ ${html}`
4562
+ );
4563
+ }
4564
+ return [
4565
+ {
4566
+ path: `${pathname}/index.html`,
4567
+ contents: html
4568
+ }
4569
+ ];
4570
+ },
4571
+ logFile(outputPath, metadata) {
4572
+ invariant(viteConfig);
4573
+ invariant(metadata);
4574
+ if (metadata.type === "spa") {
4575
+ return;
4576
+ }
4577
+ viteConfig.logger.info(
4578
+ `Prerender (${metadata.type}): ${metadata.path} -> ${import_picocolors4.default.bold(outputPath)}`
4579
+ );
4580
+ },
4581
+ async finalize(buildDirectory) {
4582
+ invariant(viteConfig);
4583
+ let { ssr, future } = ctx.reactRouterConfig;
4584
+ if (!ssr) {
4585
+ let spaFallback = path7.join(buildDirectory, "__spa-fallback.html");
4586
+ let index = path7.join(buildDirectory, "index.html");
4587
+ let finalSpaPath;
4588
+ if ((0, import_node_fs2.existsSync)(spaFallback) && !(0, import_node_fs2.existsSync)(index)) {
4589
+ await (0, import_promises3.rename)(spaFallback, index);
4590
+ finalSpaPath = index;
4591
+ } else if ((0, import_node_fs2.existsSync)(spaFallback)) {
4592
+ finalSpaPath = spaFallback;
4593
+ }
4594
+ if (finalSpaPath) {
4595
+ let prettyPath = path7.relative(viteConfig.root, finalSpaPath);
4596
+ if (ctx.prerenderPaths && ctx.prerenderPaths.size > 0) {
4597
+ viteConfig.logger.info(
4598
+ `Prerender (html): SPA Fallback -> ${import_picocolors4.default.bold(prettyPath)}`
4599
+ );
4600
+ } else {
4601
+ viteConfig.logger.info(
4602
+ `SPA Mode: Generated ${import_picocolors4.default.bold(prettyPath)}`
4603
+ );
4604
+ }
4605
+ }
4606
+ let serverBuildDirectory = future.v8_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx.reactRouterConfig);
4607
+ viteConfig.logger.info(
4608
+ [
4609
+ "Removing the server build in",
4610
+ import_picocolors4.default.green(serverBuildDirectory),
4611
+ "due to ssr:false"
4612
+ ].join(" ")
4613
+ );
4614
+ (0, import_node_fs2.rmSync)(serverBuildDirectory, { force: true, recursive: true });
4615
+ }
4616
+ }
4617
+ }),
4120
4618
  validatePluginOrder(),
4121
4619
  warnOnClientSourceMaps()
4122
4620
  ];
@@ -4180,7 +4678,7 @@ if (import.meta.hot && !inWebWorker) {
4180
4678
  function getRoute(pluginConfig, file) {
4181
4679
  let vite2 = getVite();
4182
4680
  let routePath = vite2.normalizePath(
4183
- path6.relative(pluginConfig.appDirectory, file)
4681
+ path7.relative(pluginConfig.appDirectory, file)
4184
4682
  );
4185
4683
  let route = Object.values(pluginConfig.routes).find(
4186
4684
  (r) => vite2.normalizePath(r.file) === routePath
@@ -4219,7 +4717,7 @@ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteF
4219
4717
  caseSensitive: route.caseSensitive,
4220
4718
  url: combineURLs(
4221
4719
  ctx.publicPath,
4222
- "/" + path6.relative(
4720
+ "/" + path7.relative(
4223
4721
  ctx.rootDirectory,
4224
4722
  resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
4225
4723
  )
@@ -4235,6 +4733,7 @@ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteF
4235
4733
  hasLoader: sourceExports.includes("loader"),
4236
4734
  hasClientLoader: sourceExports.includes("clientLoader"),
4237
4735
  hasClientMiddleware: sourceExports.includes("clientMiddleware"),
4736
+ hasDefaultExport: sourceExports.includes("default"),
4238
4737
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
4239
4738
  imports: []
4240
4739
  };
@@ -4247,7 +4746,7 @@ function isSpaModeEnabled(reactRouterConfig) {
4247
4746
  return reactRouterConfig.ssr === false && !isPrerenderingEnabled(reactRouterConfig);
4248
4747
  }
4249
4748
  async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
4250
- let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
4749
+ let serverBuildPath = path7.join(serverBuildDirectory, serverBuildFile);
4251
4750
  let build = await import(url.pathToFileURL(serverBuildPath).toString());
4252
4751
  let { createRequestHandler: createHandler } = await import("react-router");
4253
4752
  return {
@@ -4289,9 +4788,9 @@ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory
4289
4788
  "SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
4290
4789
  );
4291
4790
  }
4292
- await (0, import_promises2.writeFile)(path6.join(clientBuildDirectory, filename2), html);
4293
- let prettyDir = path6.relative(viteConfig.root, clientBuildDirectory);
4294
- let prettyPath = path6.join(prettyDir, filename2);
4791
+ await (0, import_promises3.writeFile)(path7.join(clientBuildDirectory, filename2), html);
4792
+ let prettyDir = path7.relative(viteConfig.root, clientBuildDirectory);
4793
+ let prettyPath = path7.join(prettyDir, filename2);
4295
4794
  if (build.prerender.length > 0) {
4296
4795
  viteConfig.logger.info(
4297
4796
  `Prerender (html): SPA Fallback -> ${import_picocolors4.default.bold(prettyPath)}`
@@ -4307,17 +4806,17 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4307
4806
  serverBuildPath
4308
4807
  );
4309
4808
  let routes = createPrerenderRoutes(reactRouterConfig.routes);
4310
- for (let path9 of build.prerender) {
4311
- let matches = (0, import_react_router2.matchRoutes)(routes, `/${path9}/`.replace(/^\/\/+/, "/"));
4809
+ for (let path10 of build.prerender) {
4810
+ let matches = (0, import_react_router2.matchRoutes)(routes, `/${path10}/`.replace(/^\/\/+/, "/"));
4312
4811
  if (!matches) {
4313
4812
  throw new Error(
4314
- `Unable to prerender path because it does not match any routes: ${path9}`
4813
+ `Unable to prerender path because it does not match any routes: ${path10}`
4315
4814
  );
4316
4815
  }
4317
4816
  }
4318
4817
  let buildRoutes = createPrerenderRoutes(build.routes);
4319
- let prerenderSinglePath = async (path9) => {
4320
- let matches = (0, import_react_router2.matchRoutes)(buildRoutes, `/${path9}/`.replace(/^\/\/+/, "/"));
4818
+ let prerenderSinglePath = async (path10) => {
4819
+ let matches = (0, import_react_router2.matchRoutes)(buildRoutes, `/${path10}/`.replace(/^\/\/+/, "/"));
4321
4820
  if (!matches) {
4322
4821
  return;
4323
4822
  }
@@ -4330,7 +4829,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4330
4829
  if (manifestRoute.loader) {
4331
4830
  await prerenderData(
4332
4831
  handler,
4333
- path9,
4832
+ path10,
4334
4833
  [leafRoute.id],
4335
4834
  clientBuildDirectory,
4336
4835
  reactRouterConfig,
@@ -4338,7 +4837,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4338
4837
  );
4339
4838
  await prerenderResourceRoute(
4340
4839
  handler,
4341
- path9,
4840
+ path10,
4342
4841
  clientBuildDirectory,
4343
4842
  reactRouterConfig,
4344
4843
  viteConfig
@@ -4356,7 +4855,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4356
4855
  if (!isResourceRoute && hasLoaders) {
4357
4856
  data = await prerenderData(
4358
4857
  handler,
4359
- path9,
4858
+ path10,
4360
4859
  null,
4361
4860
  clientBuildDirectory,
4362
4861
  reactRouterConfig,
@@ -4365,7 +4864,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4365
4864
  }
4366
4865
  await prerenderRoute(
4367
4866
  handler,
4368
- path9,
4867
+ path10,
4369
4868
  clientBuildDirectory,
4370
4869
  reactRouterConfig,
4371
4870
  viteConfig,
@@ -4378,9 +4877,9 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4378
4877
  }
4379
4878
  };
4380
4879
  let concurrency = 1;
4381
- let { prerender } = reactRouterConfig;
4382
- if (typeof prerender === "object" && "unstable_concurrency" in prerender) {
4383
- concurrency = prerender.unstable_concurrency ?? 1;
4880
+ let { prerender: prerender2 } = reactRouterConfig;
4881
+ if (typeof prerender2 === "object" && "unstable_concurrency" in prerender2) {
4882
+ concurrency = prerender2.unstable_concurrency ?? 1;
4384
4883
  }
4385
4884
  const pMap = await import("p-map");
4386
4885
  await pMap.default(build.prerender, prerenderSinglePath, { concurrency });
@@ -4439,12 +4938,12 @@ async function prerenderData(handler, prerenderPath, onlyRoutes, clientBuildDire
4439
4938
  ${normalizedPath}`
4440
4939
  );
4441
4940
  }
4442
- let outfile = path6.join(clientBuildDirectory, ...normalizedPath.split("/"));
4443
- await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4444
- await (0, import_promises2.writeFile)(outfile, data);
4941
+ let outfile = path7.join(clientBuildDirectory, ...normalizedPath.split("/"));
4942
+ await (0, import_promises3.mkdir)(path7.dirname(outfile), { recursive: true });
4943
+ await (0, import_promises3.writeFile)(outfile, data);
4445
4944
  viteConfig.logger.info(
4446
4945
  `Prerender (data): ${prerenderPath} -> ${import_picocolors4.default.bold(
4447
- path6.relative(viteConfig.root, outfile)
4946
+ path7.relative(viteConfig.root, outfile)
4448
4947
  )}`
4449
4948
  );
4450
4949
  return data;
@@ -4461,15 +4960,17 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
4461
4960
  if (redirectStatusCodes.has(response.status)) {
4462
4961
  let location = response.headers.get("Location");
4463
4962
  let delay = response.status === 302 ? 2 : 0;
4963
+ let escapedLocation = escapeHtml(location ?? "");
4964
+ let escapedNormalizedPath = escapeHtml(normalizedPath);
4464
4965
  html = `<!doctype html>
4465
4966
  <head>
4466
- <title>Redirecting to: ${location}</title>
4467
- <meta http-equiv="refresh" content="${delay};url=${location}">
4967
+ <title>Redirecting to: ${escapedLocation}</title>
4968
+ <meta http-equiv="refresh" content="${delay};url=${escapedLocation}">
4468
4969
  <meta name="robots" content="noindex">
4469
4970
  </head>
4470
4971
  <body>
4471
- <a href="${location}">
4472
- Redirecting from <code>${normalizedPath}</code> to <code>${location}</code>
4972
+ <a href="${escapedLocation}">
4973
+ Redirecting from <code>${escapedNormalizedPath}</code> to <code>${escapedLocation}</code>
4473
4974
  </a>
4474
4975
  </body>
4475
4976
  </html>`;
@@ -4479,16 +4980,16 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
4479
4980
  ${html}`
4480
4981
  );
4481
4982
  }
4482
- let outfile = path6.join(
4983
+ let outfile = path7.join(
4483
4984
  clientBuildDirectory,
4484
4985
  ...normalizedPath.split("/"),
4485
4986
  "index.html"
4486
4987
  );
4487
- await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4488
- await (0, import_promises2.writeFile)(outfile, html);
4988
+ await (0, import_promises3.mkdir)(path7.dirname(outfile), { recursive: true });
4989
+ await (0, import_promises3.writeFile)(outfile, html);
4489
4990
  viteConfig.logger.info(
4490
4991
  `Prerender (html): ${prerenderPath} -> ${import_picocolors4.default.bold(
4491
- path6.relative(viteConfig.root, outfile)
4992
+ path7.relative(viteConfig.root, outfile)
4492
4993
  )}`
4493
4994
  );
4494
4995
  }
@@ -4503,24 +5004,24 @@ async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirecto
4503
5004
  ${content.toString("utf8")}`
4504
5005
  );
4505
5006
  }
4506
- let outfile = path6.join(clientBuildDirectory, ...normalizedPath.split("/"));
4507
- await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4508
- await (0, import_promises2.writeFile)(outfile, content);
5007
+ let outfile = path7.join(clientBuildDirectory, ...normalizedPath.split("/"));
5008
+ await (0, import_promises3.mkdir)(path7.dirname(outfile), { recursive: true });
5009
+ await (0, import_promises3.writeFile)(outfile, content);
4509
5010
  viteConfig.logger.info(
4510
5011
  `Prerender (resource): ${prerenderPath} -> ${import_picocolors4.default.bold(
4511
- path6.relative(viteConfig.root, outfile)
5012
+ path7.relative(viteConfig.root, outfile)
4512
5013
  )}`
4513
5014
  );
4514
5015
  }
4515
- async function getPrerenderPaths(prerender, ssr, routes, logWarning = false) {
4516
- if (prerender == null || prerender === false) {
5016
+ async function getPrerenderPaths(prerender2, ssr, routes, logWarning = false) {
5017
+ if (prerender2 == null || prerender2 === false) {
4517
5018
  return [];
4518
5019
  }
4519
5020
  let pathsConfig;
4520
- if (typeof prerender === "object" && "paths" in prerender) {
4521
- pathsConfig = prerender.paths;
5021
+ if (typeof prerender2 === "object" && "paths" in prerender2) {
5022
+ pathsConfig = prerender2.paths;
4522
5023
  } else {
4523
- pathsConfig = prerender;
5024
+ pathsConfig = prerender2;
4524
5025
  }
4525
5026
  if (pathsConfig === false) {
4526
5027
  return [];
@@ -4591,14 +5092,14 @@ async function validateSsrFalsePrerenderExports(viteConfig, ctx, manifest, viteC
4591
5092
  }
4592
5093
  let prerenderRoutes = createPrerenderRoutes(manifest.routes);
4593
5094
  let prerenderedRoutes = /* @__PURE__ */ new Set();
4594
- for (let path9 of prerenderPaths) {
5095
+ for (let path10 of prerenderPaths) {
4595
5096
  let matches = (0, import_react_router2.matchRoutes)(
4596
5097
  prerenderRoutes,
4597
- `/${path9}/`.replace(/^\/\/+/, "/")
5098
+ `/${path10}/`.replace(/^\/\/+/, "/")
4598
5099
  );
4599
5100
  invariant(
4600
5101
  matches,
4601
- `Unable to prerender path because it does not match any routes: ${path9}`
5102
+ `Unable to prerender path because it does not match any routes: ${path10}`
4602
5103
  );
4603
5104
  matches.forEach((m) => prerenderedRoutes.add(m.route.id));
4604
5105
  }
@@ -4765,11 +5266,11 @@ function validateRouteChunks({
4765
5266
  async function cleanBuildDirectory(viteConfig, ctx) {
4766
5267
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
4767
5268
  let isWithinRoot = () => {
4768
- let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
4769
- return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
5269
+ let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
5270
+ return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
4770
5271
  };
4771
5272
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
4772
- await (0, import_promises2.rm)(buildDirectory, { force: true, recursive: true });
5273
+ await (0, import_promises3.rm)(buildDirectory, { force: true, recursive: true });
4773
5274
  }
4774
5275
  }
4775
5276
  async function cleanViteManifests(environmentsOptions, ctx) {
@@ -4777,7 +5278,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
4777
5278
  ([environmentName, options]) => {
4778
5279
  let outDir = options.build?.outDir;
4779
5280
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
4780
- return path6.join(outDir, ".vite/manifest.json");
5281
+ return path7.join(outDir, ".vite/manifest.json");
4781
5282
  }
4782
5283
  );
4783
5284
  await Promise.all(
@@ -4785,12 +5286,12 @@ async function cleanViteManifests(environmentsOptions, ctx) {
4785
5286
  let manifestExists = (0, import_node_fs2.existsSync)(viteManifestPath);
4786
5287
  if (!manifestExists) return;
4787
5288
  if (!ctx.viteManifestEnabled) {
4788
- await (0, import_promises2.rm)(viteManifestPath, { force: true, recursive: true });
5289
+ await (0, import_promises3.rm)(viteManifestPath, { force: true, recursive: true });
4789
5290
  }
4790
- let viteDir = path6.dirname(viteManifestPath);
4791
- let viteDirFiles = await (0, import_promises2.readdir)(viteDir, { recursive: true });
5291
+ let viteDir = path7.dirname(viteManifestPath);
5292
+ let viteDirFiles = await (0, import_promises3.readdir)(viteDir, { recursive: true });
4792
5293
  if (viteDirFiles.length === 0) {
4793
- await (0, import_promises2.rm)(viteDir, { force: true, recursive: true });
5294
+ await (0, import_promises3.rm)(viteDir, { force: true, recursive: true });
4794
5295
  }
4795
5296
  })
4796
5297
  );
@@ -4805,12 +5306,12 @@ async function getBuildManifest({
4805
5306
  }
4806
5307
  let { normalizePath } = await import("vite");
4807
5308
  let serverBuildDirectory = getServerBuildDirectory(reactRouterConfig);
4808
- let resolvedAppDirectory = path6.resolve(rootDirectory, appDirectory);
5309
+ let resolvedAppDirectory = path7.resolve(rootDirectory, appDirectory);
4809
5310
  let rootRelativeRoutes = Object.fromEntries(
4810
5311
  Object.entries(routes).map(([id, route]) => {
4811
- let filePath = path6.join(resolvedAppDirectory, route.file);
5312
+ let filePath = path7.join(resolvedAppDirectory, route.file);
4812
5313
  let rootRelativeFilePath = normalizePath(
4813
- path6.relative(rootDirectory, filePath)
5314
+ path7.relative(rootDirectory, filePath)
4814
5315
  );
4815
5316
  return [id, { ...route, file: rootRelativeFilePath }];
4816
5317
  })
@@ -4828,7 +5329,7 @@ async function getBuildManifest({
4828
5329
  (route2) => configRouteToBranchRoute({
4829
5330
  ...route2,
4830
5331
  // Ensure absolute paths are passed to the serverBundles function
4831
- file: path6.join(resolvedAppDirectory, route2.file)
5332
+ file: path7.join(resolvedAppDirectory, route2.file)
4832
5333
  })
4833
5334
  )
4834
5335
  });
@@ -4852,10 +5353,10 @@ async function getBuildManifest({
4852
5353
  buildManifest.serverBundles[serverBundleId] ??= {
4853
5354
  id: serverBundleId,
4854
5355
  file: normalizePath(
4855
- path6.join(
4856
- path6.relative(
5356
+ path7.join(
5357
+ path7.relative(
4857
5358
  rootDirectory,
4858
- path6.join(serverBuildDirectory, serverBundleId)
5359
+ path7.join(serverBuildDirectory, serverBundleId)
4859
5360
  ),
4860
5361
  reactRouterConfig.serverBuildFile
4861
5362
  )
@@ -4874,10 +5375,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
4874
5375
  }
4875
5376
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4876
5377
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
4877
- let packageRoot = path6.dirname(
5378
+ let packageRoot = path7.dirname(
4878
5379
  require.resolve("@react-router/dev/package.json")
4879
5380
  );
4880
- let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
5381
+ let { moduleSyncEnabled } = await import(`file:///${path7.join(packageRoot, "module-sync-enabled/index.mjs")}`);
4881
5382
  let vite2 = getVite();
4882
5383
  function getBaseOptions({
4883
5384
  viteUserConfig
@@ -4956,7 +5457,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4956
5457
  ctx.entryClientFilePath,
4957
5458
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
4958
5459
  (route) => {
4959
- let routeFilePath = path6.resolve(
5460
+ let routeFilePath = path7.resolve(
4960
5461
  ctx.reactRouterConfig.appDirectory,
4961
5462
  route.file
4962
5463
  );
@@ -4980,7 +5481,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4980
5481
  ) : null;
4981
5482
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
4982
5483
  let assetsDir = (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
4983
- return path6.posix.join(
5484
+ return path7.posix.join(
4984
5485
  assetsDir,
4985
5486
  `[name]${routeChunkSuffix}-[hash].js`
4986
5487
  );
@@ -5046,13 +5547,89 @@ async function asyncFlatten(arr) {
5046
5547
  } while (arr.some((v2) => v2?.then));
5047
5548
  return arr;
5048
5549
  }
5550
+ function assertPrerenderPathsMatchRoutes(config, prerenderPaths) {
5551
+ let routes = createPrerenderRoutes(config.routes);
5552
+ for (let path10 of prerenderPaths) {
5553
+ let matches = (0, import_react_router2.matchRoutes)(routes, `/${path10}/`.replace(/^\/\/+/, "/"));
5554
+ if (!matches) {
5555
+ throw new Error(
5556
+ `Unable to prerender path because it does not match any routes: ${path10}`
5557
+ );
5558
+ }
5559
+ }
5560
+ }
5561
+ function getPrerenderConcurrencyConfig(reactRouterConfig) {
5562
+ let concurrency = 1;
5563
+ let { prerender: prerender2 } = reactRouterConfig;
5564
+ if (typeof prerender2 === "object" && "unstable_concurrency" in prerender2) {
5565
+ concurrency = prerender2.unstable_concurrency ?? 1;
5566
+ }
5567
+ return concurrency;
5568
+ }
5569
+ function createDataRequest(prerenderPath, reactRouterConfig, onlyRoutes, isResourceRoute) {
5570
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
5571
+ let url2 = new URL(`http://localhost${normalizedPath}`);
5572
+ if (onlyRoutes?.length) {
5573
+ url2.searchParams.set("_routes", onlyRoutes.join(","));
5574
+ }
5575
+ return {
5576
+ request: new Request(url2),
5577
+ metadata: { type: "data", path: prerenderPath, isResourceRoute }
5578
+ };
5579
+ }
5580
+ function createRouteRequest(prerenderPath, reactRouterConfig, data) {
5581
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(
5582
+ /\/\/+/g,
5583
+ "/"
5584
+ );
5585
+ let headers = new Headers();
5586
+ if (data) {
5587
+ let encodedData = encodeURI(data);
5588
+ if (encodedData.length < 8 * 1024) {
5589
+ headers.set("X-React-Router-Prerender-Data", encodedData);
5590
+ }
5591
+ }
5592
+ return {
5593
+ request: new Request(`http://localhost${normalizedPath}`, { headers }),
5594
+ metadata: { type: "html", path: prerenderPath }
5595
+ };
5596
+ }
5597
+ function createResourceRouteRequest(prerenderPath, reactRouterConfig, requestInit) {
5598
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
5599
+ return {
5600
+ request: new Request(`http://localhost${normalizedPath}`, requestInit),
5601
+ metadata: { type: "resource", path: prerenderPath }
5602
+ };
5603
+ }
5604
+ function createSpaModeRequest(reactRouterConfig) {
5605
+ return {
5606
+ request: new Request(`http://localhost${reactRouterConfig.basename}`, {
5607
+ headers: {
5608
+ // Enable SPA mode in the server runtime and only render down to the root
5609
+ "X-React-Router-SPA-Mode": "yes"
5610
+ }
5611
+ }),
5612
+ metadata: { type: "spa", path: "/" }
5613
+ };
5614
+ }
5615
+ var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
5616
+ var ESCAPE_LOOKUP = {
5617
+ "&": "\\u0026",
5618
+ ">": "\\u003e",
5619
+ "<": "\\u003c",
5620
+ "\u2028": "\\u2028",
5621
+ "\u2029": "\\u2029"
5622
+ };
5623
+ function escapeHtml(html) {
5624
+ return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
5625
+ }
5049
5626
 
5050
5627
  // vite/rsc/plugin.ts
5051
5628
  var import_es_module_lexer3 = require("es-module-lexer");
5052
5629
  var Path5 = __toESM(require("pathe"));
5053
5630
  var babel2 = __toESM(require("@babel/core"));
5054
5631
  var import_picocolors5 = __toESM(require("picocolors"));
5055
- var import_promises3 = require("fs/promises");
5632
+ var import_promises4 = require("fs/promises");
5056
5633
  var import_pathe6 = __toESM(require("pathe"));
5057
5634
 
5058
5635
  // vite/rsc/virtual-route-config.ts
@@ -5763,8 +6340,8 @@ ${errors.map((x) => ` - ${x}`).join("\n")}
5763
6340
  );
5764
6341
  return [
5765
6342
  "const exports = {}",
5766
- await (0, import_promises3.readFile)(reactRefreshRuntimePath, "utf8"),
5767
- await (0, import_promises3.readFile)(
6343
+ await (0, import_promises4.readFile)(reactRefreshRuntimePath, "utf8"),
6344
+ await (0, import_promises4.readFile)(
5768
6345
  require.resolve("./static/rsc-refresh-utils.mjs"),
5769
6346
  "utf8"
5770
6347
  ),
@@ -5826,7 +6403,7 @@ ${errors.map((x) => ` - ${x}`).join("\n")}
5826
6403
  const normalizedPath = import_pathe6.default.normalize(mod.file);
5827
6404
  const routeId = routeIdByFile?.get(normalizedPath);
5828
6405
  if (routeId !== void 0) {
5829
- const routeSource = await (0, import_promises3.readFile)(normalizedPath, "utf8");
6406
+ const routeSource = await (0, import_promises4.readFile)(normalizedPath, "utf8");
5830
6407
  const virtualRouteModuleCode = (await server.environments.rsc.pluginContainer.transform(
5831
6408
  routeSource,
5832
6409
  `${normalizedPath}?route-module`