@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/CHANGELOG.md CHANGED
@@ -1,5 +1,66 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## 7.13.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix `react-router dev` crash when Unix socket files exist in the project root ([#14854](https://github.com/remix-run/react-router/pull/14854))
8
+
9
+ - Escape redirect locations in prerendered redirect HTML ([#14880](https://github.com/remix-run/react-router/pull/14880))
10
+
11
+ - Add `future.unstable_passThroughRequests` flag ([#14775](https://github.com/remix-run/react-router/pull/14775))
12
+
13
+ By default, React Router normalizes the `request.url` passed to your `loader`, `action`, and `middleware` functions by removing React Router's internal implementation details (`.data` suffixes, `index` + `_routes` query params).
14
+
15
+ Enabling this flag removes that normalization and passes the raw HTTP `request` instance to your handlers. This provides a few benefits:
16
+
17
+ - Reduces server-side overhead by eliminating multiple `new Request()` calls on the critical path
18
+ - Allows you to distinguish document from data requests in your handlers base don the presence of a `.data` suffix (useful for observability purposes)
19
+
20
+ If you were previously relying on the normalization of `request.url`, you can switch to use the new sibling `unstable_url` parameter which contains a `URL` instance representing the normalized location:
21
+
22
+ ```tsx
23
+ // ❌ Before: you could assume there was no `.data` suffix in `request.url`
24
+ export async function loader({ request }: Route.LoaderArgs) {
25
+ let url = new URL(request.url);
26
+ if (url.pathname === "/path") {
27
+ // This check will fail with the flag enabled because the `.data` suffix will
28
+ // exist on data requests
29
+ }
30
+ }
31
+
32
+ // ✅ After: use `unstable_url` for normalized routing logic and `request.url`
33
+ // for raw routing logic
34
+ export async function loader({ request, unstable_url }: Route.LoaderArgs) {
35
+ if (unstable_url.pathname === "/path") {
36
+ // This will always have the `.data` suffix stripped
37
+ }
38
+
39
+ // And now you can distinguish between document versus data requests
40
+ let isDataRequest = new URL(request.url).pathname.endsWith(".data");
41
+ }
42
+ ```
43
+
44
+ - Add a new `unstable_url: URL` parameter to route handler methods (`loader`, `action`, `middleware`, etc.) representing the normalized URL the application is navigating to or fetching, with React Router implementation details removed (`.data`suffix, `index`/`_routes` query params) ([#14775](https://github.com/remix-run/react-router/pull/14775))
45
+
46
+ This is being added alongside the new `future.unstable_passthroughRequests` future flag so that users still have a way to access the normalized URL when that flag is enabled and non-normalized `request`'s are being passed to your handlers. When adopting this flag, you will only need to start leveraging this new parameter if you are relying on the normalization of `request.url` in your application code.
47
+
48
+ If you don't have the flag enabled, then `unstable_url` will match `request.url`.
49
+
50
+ - Updated dependencies:
51
+ - `react-router@7.13.2`
52
+ - `@react-router/node@7.13.2`
53
+ - `@react-router/serve@7.13.2`
54
+
55
+ ## 7.13.1
56
+
57
+ ### Patch Changes
58
+
59
+ - Updated dependencies:
60
+ - `react-router@7.13.1`
61
+ - `@react-router/node@7.13.1`
62
+ - `@react-router/serve@7.13.1`
63
+
3
64
  ## 7.13.0
4
65
 
5
66
  ### Patch Changes
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v7.13.0
3
+ * @react-router/dev v7.13.2
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -217,7 +217,7 @@ function validateRouteConfig({
217
217
  `Route config in "${routeConfigFile}" is invalid.`,
218
218
  root ? `${root}` : [],
219
219
  nested ? Object.entries(nested).map(
220
- ([path9, message]) => `Path: routes.${path9}
220
+ ([path10, message]) => `Path: routes.${path10}
221
221
  ${message}`
222
222
  ) : []
223
223
  ].flat().join("\n\n")
@@ -376,7 +376,7 @@ async function resolveConfig({
376
376
  basename: basename3,
377
377
  buildDirectory: userBuildDirectory,
378
378
  buildEnd,
379
- prerender,
379
+ prerender: prerender2,
380
380
  routeDiscovery: userRouteDiscovery,
381
381
  serverBuildFile,
382
382
  serverBundles,
@@ -390,15 +390,15 @@ async function resolveConfig({
390
390
  if (!ssr && serverBundles) {
391
391
  serverBundles = void 0;
392
392
  }
393
- if (prerender) {
393
+ if (prerender2) {
394
394
  let isValidPrerenderPathsConfig = (p) => typeof p === "boolean" || typeof p === "function" || Array.isArray(p);
395
- let isValidPrerenderConfig = isValidPrerenderPathsConfig(prerender) || typeof prerender === "object" && "paths" in prerender && isValidPrerenderPathsConfig(prerender.paths);
395
+ let isValidPrerenderConfig = isValidPrerenderPathsConfig(prerender2) || typeof prerender2 === "object" && "paths" in prerender2 && isValidPrerenderPathsConfig(prerender2.paths);
396
396
  if (!isValidPrerenderConfig) {
397
397
  return err(
398
398
  "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."
399
399
  );
400
400
  }
401
- let isValidConcurrencyConfig = typeof prerender != "object" || !("unstable_concurrency" in prerender) || typeof prerender.unstable_concurrency === "number" && Number.isInteger(prerender.unstable_concurrency) && prerender.unstable_concurrency > 0;
401
+ let isValidConcurrencyConfig = typeof prerender2 != "object" || !("unstable_concurrency" in prerender2) || typeof prerender2.unstable_concurrency === "number" && Number.isInteger(prerender2.unstable_concurrency) && prerender2.unstable_concurrency > 0;
402
402
  if (!isValidConcurrencyConfig) {
403
403
  return err(
404
404
  "The `prerender.unstable_concurrency` config must be a positive integer if specified."
@@ -505,8 +505,10 @@ async function resolveConfig({
505
505
  }
506
506
  let future = {
507
507
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
508
+ unstable_passThroughRequests: userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
508
509
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
509
510
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
511
+ unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
510
512
  v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
511
513
  v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
512
514
  v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
@@ -518,7 +520,7 @@ async function resolveConfig({
518
520
  buildDirectory,
519
521
  buildEnd,
520
522
  future,
521
- prerender,
523
+ prerender: prerender2,
522
524
  routes: routes2,
523
525
  routeDiscovery,
524
526
  serverBuildFile,
@@ -585,13 +587,11 @@ async function createConfigLoader({
585
587
  if (!fsWatcher) {
586
588
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
587
589
  ignoreInitial: true,
588
- ignored: (path9) => {
589
- let dirname5 = import_pathe3.default.dirname(path9);
590
- return !dirname5.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
591
- // that are at the root level, not nested in subdirectories
592
- path9 !== root && // Watch the root directory itself
593
- dirname5 !== root;
594
- }
590
+ ignored: (path10) => isIgnoredByWatcher(path10, { root, appDirectory })
591
+ });
592
+ fsWatcher.on("error", (error) => {
593
+ let message = error instanceof Error ? error.message : String(error);
594
+ console.warn(import_picocolors.default.yellow(`File watcher error: ${message}`));
595
595
  });
596
596
  fsWatcher.on("all", async (...args) => {
597
597
  let [event, rawFilepath] = args;
@@ -732,6 +732,25 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
732
732
  }
733
733
  return false;
734
734
  }
735
+ function isIgnoredByWatcher(path10, { root, appDirectory }) {
736
+ let dirname5 = import_pathe3.default.dirname(path10);
737
+ let ignoredByPath = !dirname5.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
738
+ // that are at the root level, not nested in subdirectories
739
+ path10 !== root && // Watch the root directory itself
740
+ dirname5 !== root;
741
+ if (ignoredByPath) {
742
+ return true;
743
+ }
744
+ try {
745
+ let stat = import_node_fs.default.statSync(path10, { throwIfNoEntry: false });
746
+ if (stat && !stat.isFile() && !stat.isDirectory()) {
747
+ return true;
748
+ }
749
+ } catch {
750
+ return true;
751
+ }
752
+ return false;
753
+ }
735
754
  var import_node_fs, import_node_child_process, import_pathe3, import_chokidar, import_picocolors, import_pick2, import_omit, import_cloneDeep, import_isEqual, excludedConfigPresetKeys, mergeReactRouterConfig, deepFreeze, entryExts;
736
755
  var init_config = __esm({
737
756
  "config/config.ts"() {
@@ -914,7 +933,7 @@ function fullpath(lineage2) {
914
933
  if (lineage2.length === 1 && route?.id === "root") return "/";
915
934
  const isLayout = route && route.index !== true && route.path === void 0;
916
935
  if (isLayout) return void 0;
917
- return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path9) => path9 !== void 0 && path9 !== "").join("/");
936
+ return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path10) => path10 !== void 0 && path10 !== "").join("/");
918
937
  }
919
938
  var init_route = __esm({
920
939
  "typegen/route.ts"() {
@@ -1098,8 +1117,8 @@ function routeModulesType(ctx) {
1098
1117
  );
1099
1118
  }
1100
1119
  function isInAppDirectory(ctx, routeFile) {
1101
- const path9 = Path3.resolve(ctx.config.appDirectory, routeFile);
1102
- return path9.startsWith(ctx.config.appDirectory);
1120
+ const path10 = Path3.resolve(ctx.config.appDirectory, routeFile);
1121
+ return path10.startsWith(ctx.config.appDirectory);
1103
1122
  }
1104
1123
  function getRouteAnnotations({
1105
1124
  ctx,
@@ -1211,21 +1230,21 @@ function getRouteAnnotations({
1211
1230
  return { filename: filename2, content };
1212
1231
  }
1213
1232
  function relativeImportSource(from, to) {
1214
- let path9 = Path3.relative(Path3.dirname(from), to);
1215
- let extension = Path3.extname(path9);
1216
- path9 = Path3.join(Path3.dirname(path9), Pathe.filename(path9));
1217
- if (!path9.startsWith("../")) path9 = "./" + path9;
1233
+ let path10 = Path3.relative(Path3.dirname(from), to);
1234
+ let extension = Path3.extname(path10);
1235
+ path10 = Path3.join(Path3.dirname(path10), Pathe.filename(path10));
1236
+ if (!path10.startsWith("../")) path10 = "./" + path10;
1218
1237
  if (!extension || /\.(js|ts)x?$/.test(extension)) {
1219
1238
  extension = ".js";
1220
1239
  }
1221
- return path9 + extension;
1240
+ return path10 + extension;
1222
1241
  }
1223
1242
  function rootDirsPath(ctx, typesPath) {
1224
1243
  const rel = Path3.relative(typesDirectory(ctx), typesPath);
1225
1244
  return Path3.join(ctx.rootDirectory, rel);
1226
1245
  }
1227
- function paramsType(path9) {
1228
- const params = parse2(path9);
1246
+ function paramsType(path10) {
1247
+ const params = parse2(path10);
1229
1248
  return t2.tsTypeLiteral(
1230
1249
  Object.entries(params).map(([param, isRequired]) => {
1231
1250
  const property = t2.tsPropertySignature(
@@ -1555,6 +1574,16 @@ var init_warn_on_client_source_maps = __esm({
1555
1574
  }
1556
1575
  });
1557
1576
 
1577
+ // vite/plugins/prerender.ts
1578
+ var import_promises2, import_node_path2;
1579
+ var init_prerender = __esm({
1580
+ "vite/plugins/prerender.ts"() {
1581
+ "use strict";
1582
+ import_promises2 = require("fs/promises");
1583
+ import_node_path2 = __toESM(require("path"));
1584
+ }
1585
+ });
1586
+
1558
1587
  // vite/plugin.ts
1559
1588
  async function resolveViteConfig({
1560
1589
  configFile,
@@ -1597,11 +1626,11 @@ function getServerBundleIds(ctx) {
1597
1626
  async function cleanBuildDirectory(viteConfig, ctx) {
1598
1627
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
1599
1628
  let isWithinRoot = () => {
1600
- let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
1601
- return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
1629
+ let relativePath = path8.relative(ctx.rootDirectory, buildDirectory);
1630
+ return !relativePath.startsWith("..") && !path8.isAbsolute(relativePath);
1602
1631
  };
1603
1632
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1604
- await (0, import_promises2.rm)(buildDirectory, { force: true, recursive: true });
1633
+ await (0, import_promises3.rm)(buildDirectory, { force: true, recursive: true });
1605
1634
  }
1606
1635
  }
1607
1636
  async function cleanViteManifests(environmentsOptions, ctx) {
@@ -1609,7 +1638,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1609
1638
  ([environmentName, options]) => {
1610
1639
  let outDir = options.build?.outDir;
1611
1640
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
1612
- return path7.join(outDir, ".vite/manifest.json");
1641
+ return path8.join(outDir, ".vite/manifest.json");
1613
1642
  }
1614
1643
  );
1615
1644
  await Promise.all(
@@ -1617,12 +1646,12 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1617
1646
  let manifestExists = (0, import_node_fs3.existsSync)(viteManifestPath);
1618
1647
  if (!manifestExists) return;
1619
1648
  if (!ctx.viteManifestEnabled) {
1620
- await (0, import_promises2.rm)(viteManifestPath, { force: true, recursive: true });
1649
+ await (0, import_promises3.rm)(viteManifestPath, { force: true, recursive: true });
1621
1650
  }
1622
- let viteDir = path7.dirname(viteManifestPath);
1623
- let viteDirFiles = await (0, import_promises2.readdir)(viteDir, { recursive: true });
1651
+ let viteDir = path8.dirname(viteManifestPath);
1652
+ let viteDirFiles = await (0, import_promises3.readdir)(viteDir, { recursive: true });
1624
1653
  if (viteDirFiles.length === 0) {
1625
- await (0, import_promises2.rm)(viteDir, { force: true, recursive: true });
1654
+ await (0, import_promises3.rm)(viteDir, { force: true, recursive: true });
1626
1655
  }
1627
1656
  })
1628
1657
  );
@@ -1636,10 +1665,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
1636
1665
  }
1637
1666
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1638
1667
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1639
- let packageRoot = path7.dirname(
1668
+ let packageRoot = path8.dirname(
1640
1669
  require.resolve("@react-router/dev/package.json")
1641
1670
  );
1642
- let { moduleSyncEnabled } = await import(`file:///${path7.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1671
+ let { moduleSyncEnabled } = await import(`file:///${path8.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1643
1672
  let vite2 = getVite();
1644
1673
  function getBaseOptions({
1645
1674
  viteUserConfig
@@ -1718,7 +1747,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1718
1747
  ctx.entryClientFilePath,
1719
1748
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
1720
1749
  (route) => {
1721
- let routeFilePath = path7.resolve(
1750
+ let routeFilePath = path8.resolve(
1722
1751
  ctx.reactRouterConfig.appDirectory,
1723
1752
  route.file
1724
1753
  );
@@ -1742,7 +1771,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1742
1771
  ) : null;
1743
1772
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1744
1773
  let assetsDir = (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1745
- return path7.posix.join(
1774
+ return path8.posix.join(
1746
1775
  assetsDir,
1747
1776
  `[name]${routeChunkSuffix}-[hash].js`
1748
1777
  );
@@ -1792,14 +1821,14 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1792
1821
  function isNonNullable(x) {
1793
1822
  return x != null;
1794
1823
  }
1795
- var import_node_crypto, import_node_fs3, import_promises2, path7, url, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors5, 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;
1824
+ var import_node_crypto, import_node_fs3, import_promises3, path8, url, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors5, 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;
1796
1825
  var init_plugin = __esm({
1797
1826
  "vite/plugin.ts"() {
1798
1827
  "use strict";
1799
1828
  import_node_crypto = require("crypto");
1800
1829
  import_node_fs3 = require("fs");
1801
- import_promises2 = require("fs/promises");
1802
- path7 = __toESM(require("path"));
1830
+ import_promises3 = require("fs/promises");
1831
+ path8 = __toESM(require("path"));
1803
1832
  url = __toESM(require("url"));
1804
1833
  babel2 = __toESM(require("@babel/core"));
1805
1834
  import_react_router2 = require("react-router");
@@ -1828,6 +1857,7 @@ var init_plugin = __esm({
1828
1857
  init_load_dotenv();
1829
1858
  init_validate_plugin_order();
1830
1859
  init_warn_on_client_source_maps();
1860
+ init_prerender();
1831
1861
  CLIENT_NON_COMPONENT_EXPORTS = [
1832
1862
  "clientAction",
1833
1863
  "clientLoader",
@@ -1853,20 +1883,20 @@ var init_plugin = __esm({
1853
1883
  serverManifest: create("server-manifest"),
1854
1884
  browserManifest: create("browser-manifest")
1855
1885
  };
1856
- getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1886
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path8.join(
1857
1887
  reactRouterConfig.buildDirectory,
1858
1888
  "server",
1859
1889
  ...serverBundleId ? [serverBundleId] : []
1860
1890
  );
1861
- getClientBuildDirectory = (reactRouterConfig) => path7.join(reactRouterConfig.buildDirectory, "client");
1862
- defaultEntriesDir = path7.resolve(
1863
- path7.dirname(require.resolve("@react-router/dev/package.json")),
1891
+ getClientBuildDirectory = (reactRouterConfig) => path8.join(reactRouterConfig.buildDirectory, "client");
1892
+ defaultEntriesDir = path8.resolve(
1893
+ path8.dirname(require.resolve("@react-router/dev/package.json")),
1864
1894
  "dist",
1865
1895
  "config",
1866
1896
  "defaults"
1867
1897
  );
1868
1898
  defaultEntries = (0, import_node_fs3.readdirSync)(defaultEntriesDir).map(
1869
- (filename2) => path7.join(defaultEntriesDir, filename2)
1899
+ (filename2) => path8.join(defaultEntriesDir, filename2)
1870
1900
  );
1871
1901
  invariant(defaultEntries.length > 0, "No default entries found");
1872
1902
  REACT_REFRESH_HEADER = `
@@ -2151,8 +2181,8 @@ var import_picocolors9 = __toESM(require("picocolors"));
2151
2181
 
2152
2182
  // cli/commands.ts
2153
2183
  var import_node_fs4 = require("fs");
2154
- var import_promises3 = require("fs/promises");
2155
- var path8 = __toESM(require("path"));
2184
+ var import_promises4 = require("fs/promises");
2185
+ var path9 = __toESM(require("path"));
2156
2186
  var import_exit_hook = __toESM(require("exit-hook"));
2157
2187
  var import_picocolors8 = __toESM(require("picocolors"));
2158
2188
  var import_react_router3 = require("react-router");
@@ -2325,14 +2355,14 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2325
2355
  console.error(import_picocolors8.default.red(`No default server entry detected.`));
2326
2356
  return;
2327
2357
  }
2328
- let defaultsDirectory = path8.resolve(
2329
- path8.dirname(require.resolve("@react-router/dev/package.json")),
2358
+ let defaultsDirectory = path9.resolve(
2359
+ path9.dirname(require.resolve("@react-router/dev/package.json")),
2330
2360
  "dist",
2331
2361
  "config",
2332
2362
  "defaults"
2333
2363
  );
2334
- let defaultEntryClient = path8.resolve(defaultsDirectory, "entry.client.tsx");
2335
- let defaultEntryServer = path8.resolve(
2364
+ let defaultEntryClient = path9.resolve(defaultsDirectory, "entry.client.tsx");
2365
+ let defaultEntryServer = path9.resolve(
2336
2366
  defaultsDirectory,
2337
2367
  `entry.server.node.tsx`
2338
2368
  );
@@ -2341,19 +2371,19 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2341
2371
  let useTypeScript = flags.typescript ?? true;
2342
2372
  let outputExtension = useTypeScript ? "tsx" : "jsx";
2343
2373
  let outputEntry = `${entry}.${outputExtension}`;
2344
- let outputFile = path8.resolve(appDirectory, outputEntry);
2374
+ let outputFile = path9.resolve(appDirectory, outputEntry);
2345
2375
  if (!useTypeScript) {
2346
2376
  let javascript = await transpile(contents, {
2347
2377
  cwd: rootDirectory,
2348
2378
  filename: isServerEntry ? defaultEntryServer : defaultEntryClient
2349
2379
  });
2350
- await (0, import_promises3.writeFile)(outputFile, javascript, "utf-8");
2380
+ await (0, import_promises4.writeFile)(outputFile, javascript, "utf-8");
2351
2381
  } else {
2352
- await (0, import_promises3.writeFile)(outputFile, contents, "utf-8");
2382
+ await (0, import_promises4.writeFile)(outputFile, contents, "utf-8");
2353
2383
  }
2354
2384
  console.log(
2355
2385
  import_picocolors8.default.blue(
2356
- `Entry file ${entry} created at ${path8.relative(
2386
+ `Entry file ${entry} created at ${path9.relative(
2357
2387
  rootDirectory,
2358
2388
  outputFile
2359
2389
  )}.`
@@ -2362,16 +2392,16 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2362
2392
  }
2363
2393
  function resolveRootDirectory(root, flags) {
2364
2394
  if (root) {
2365
- return path8.resolve(root);
2395
+ return path9.resolve(root);
2366
2396
  }
2367
- return process.env.REACT_ROUTER_ROOT || (flags?.config ? path8.dirname(path8.resolve(flags.config)) : process.cwd());
2397
+ return process.env.REACT_ROUTER_ROOT || (flags?.config ? path9.dirname(path9.resolve(flags.config)) : process.cwd());
2368
2398
  }
2369
2399
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
2370
2400
  for (let entry of entries2) {
2371
- let entryPath = path8.resolve(appDirectory, entry);
2401
+ let entryPath = path9.resolve(appDirectory, entry);
2372
2402
  let exists = (0, import_node_fs4.existsSync)(entryPath);
2373
2403
  if (exists) {
2374
- let relative7 = path8.relative(rootDirectory, entryPath);
2404
+ let relative7 = path9.relative(rootDirectory, entryPath);
2375
2405
  console.error(import_picocolors8.default.red(`Entry file ${relative7} already exists.`));
2376
2406
  return process.exit(1);
2377
2407
  }
@@ -2379,12 +2409,12 @@ async function checkForEntry(rootDirectory, appDirectory, entries2) {
2379
2409
  }
2380
2410
  async function createServerEntry(rootDirectory, appDirectory, inputFile) {
2381
2411
  await checkForEntry(rootDirectory, appDirectory, serverEntries);
2382
- let contents = await (0, import_promises3.readFile)(inputFile, "utf-8");
2412
+ let contents = await (0, import_promises4.readFile)(inputFile, "utf-8");
2383
2413
  return contents;
2384
2414
  }
2385
2415
  async function createClientEntry(rootDirectory, appDirectory, inputFile) {
2386
2416
  await checkForEntry(rootDirectory, appDirectory, clientEntries);
2387
- let contents = await (0, import_promises3.readFile)(inputFile, "utf-8");
2417
+ let contents = await (0, import_promises4.readFile)(inputFile, "utf-8");
2388
2418
  return contents;
2389
2419
  }
2390
2420
  async function typegen(root, flags) {
package/dist/config.d.ts CHANGED
@@ -38,8 +38,13 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
38
38
  type ServerModuleFormat = "esm" | "cjs";
39
39
  interface FutureConfig {
40
40
  unstable_optimizeDeps: boolean;
41
+ unstable_passThroughRequests: boolean;
41
42
  unstable_subResourceIntegrity: boolean;
42
43
  unstable_trailingSlashAwareDataRequests: boolean;
44
+ /**
45
+ * Prerender with Vite Preview server
46
+ */
47
+ unstable_previewServerPrerendering?: boolean;
43
48
  /**
44
49
  * Enable route middleware
45
50
  */
package/dist/config.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
  *
package/dist/routes.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
  *
@@ -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
  *
@@ -531,8 +531,10 @@ async function resolveConfig({
531
531
  }
532
532
  let future = {
533
533
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
534
+ unstable_passThroughRequests: userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
534
535
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
535
536
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
537
+ unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
536
538
  v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
537
539
  v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
538
540
  v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
@@ -611,13 +613,11 @@ async function createConfigLoader({
611
613
  if (!fsWatcher) {
612
614
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
613
615
  ignoreInitial: true,
614
- ignored: (path3) => {
615
- let dirname = import_pathe3.default.dirname(path3);
616
- return !dirname.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
617
- // that are at the root level, not nested in subdirectories
618
- path3 !== root && // Watch the root directory itself
619
- dirname !== root;
620
- }
616
+ ignored: (path3) => isIgnoredByWatcher(path3, { root, appDirectory })
617
+ });
618
+ fsWatcher.on("error", (error) => {
619
+ let message = error instanceof Error ? error.message : String(error);
620
+ console.warn(import_picocolors.default.yellow(`File watcher error: ${message}`));
621
621
  });
622
622
  fsWatcher.on("all", async (...args) => {
623
623
  let [event, rawFilepath] = args;
@@ -759,6 +759,25 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
759
759
  }
760
760
  return false;
761
761
  }
762
+ function isIgnoredByWatcher(path3, { root, appDirectory }) {
763
+ let dirname = import_pathe3.default.dirname(path3);
764
+ let ignoredByPath = !dirname.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
765
+ // that are at the root level, not nested in subdirectories
766
+ path3 !== root && // Watch the root directory itself
767
+ dirname !== root;
768
+ if (ignoredByPath) {
769
+ return true;
770
+ }
771
+ try {
772
+ let stat = import_node_fs.default.statSync(path3, { throwIfNoEntry: false });
773
+ if (stat && !stat.isFile() && !stat.isDirectory()) {
774
+ return true;
775
+ }
776
+ } catch {
777
+ return true;
778
+ }
779
+ return false;
780
+ }
762
781
 
763
782
  // vite/cloudflare-dev-proxy.ts
764
783
  var serverBuildId = "virtual:react-router/server-build";