react-router 8.0.0-pre.0 → 8.0.0

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.
Files changed (177) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/development/dom-export.js +1 -1
  3. package/dist/development/index-react-server-client.js +1 -1
  4. package/dist/development/index-react-server.d.ts +9 -2
  5. package/dist/development/index-react-server.js +91 -88
  6. package/dist/development/index.d.ts +1 -2
  7. package/dist/development/index.js +2 -3
  8. package/dist/development/lib/actions.js +6 -18
  9. package/dist/development/lib/components.d.ts +11 -3
  10. package/dist/development/lib/components.js +8 -2
  11. package/dist/development/lib/context.js +1 -1
  12. package/dist/development/lib/dom/dom.js +1 -1
  13. package/dist/development/lib/dom/lib.d.ts +12 -1
  14. package/dist/development/lib/dom/lib.js +18 -6
  15. package/dist/development/lib/dom/server.js +2 -2
  16. package/dist/development/lib/dom/ssr/components.d.ts +4 -2
  17. package/dist/development/lib/dom/ssr/components.js +13 -3
  18. package/dist/development/lib/dom/ssr/data.js +1 -1
  19. package/dist/development/lib/dom/ssr/entry.d.ts +1 -0
  20. package/dist/development/lib/dom/ssr/errorBoundaries.js +7 -3
  21. package/dist/development/lib/dom/ssr/fallback.js +8 -3
  22. package/dist/development/lib/dom/ssr/fog-of-war.js +12 -2
  23. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  24. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  25. package/dist/development/lib/dom/ssr/links.js +1 -1
  26. package/dist/development/lib/dom/ssr/markup.js +1 -1
  27. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  28. package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
  29. package/dist/development/lib/dom/ssr/routes.js +1 -1
  30. package/dist/development/lib/dom/ssr/server.d.ts +4 -1
  31. package/dist/development/lib/dom/ssr/server.js +2 -1
  32. package/dist/development/lib/dom/ssr/single-fetch.js +2 -3
  33. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  34. package/dist/development/lib/dom-export/hydrated-router.d.ts +1 -1
  35. package/dist/development/lib/dom-export/hydrated-router.js +14 -17
  36. package/dist/development/lib/errors.js +1 -1
  37. package/dist/development/lib/hooks.js +6 -4
  38. package/dist/development/lib/href.js +1 -1
  39. package/dist/development/lib/router/history.js +3 -2
  40. package/dist/development/lib/router/instrumentation.js +1 -1
  41. package/dist/development/lib/router/links.d.ts +3 -2
  42. package/dist/development/lib/router/router.js +13 -6
  43. package/dist/development/lib/router/url.js +18 -0
  44. package/dist/development/lib/router/utils.d.ts +6 -0
  45. package/dist/development/lib/router/utils.js +27 -8
  46. package/dist/development/lib/rsc/browser.js +21 -17
  47. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  48. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  49. package/dist/development/lib/rsc/html-stream/server.js +1 -1
  50. package/dist/development/lib/rsc/route-modules.js +1 -1
  51. package/dist/development/lib/rsc/server.ssr.js +27 -11
  52. package/dist/development/lib/server-runtime/cookies.js +1 -1
  53. package/dist/development/lib/server-runtime/crypto.js +1 -1
  54. package/dist/development/lib/server-runtime/data.js +1 -1
  55. package/dist/development/lib/server-runtime/dev.js +1 -1
  56. package/dist/development/lib/server-runtime/entry.js +1 -1
  57. package/dist/development/lib/server-runtime/errors.js +2 -22
  58. package/dist/development/lib/server-runtime/headers.js +1 -1
  59. package/dist/development/lib/server-runtime/invariant.js +1 -1
  60. package/dist/development/lib/server-runtime/mode.js +1 -1
  61. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  62. package/dist/development/lib/server-runtime/routes.js +1 -1
  63. package/dist/development/lib/server-runtime/server.js +17 -23
  64. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  65. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  66. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  67. package/dist/development/lib/server-runtime/sessions.js +1 -1
  68. package/dist/development/lib/server-runtime/single-fetch.js +4 -4
  69. package/dist/development/lib/server-runtime/urls.js +2 -5
  70. package/dist/development/lib/server-runtime/warnings.js +1 -1
  71. package/dist/development/lib/types/internal.js +1 -1
  72. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  73. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +2 -1
  74. package/dist/development/vendor/turbo-stream-v2/unflatten.js +3 -2
  75. package/dist/development/vendor/turbo-stream-v2/utils.js +2 -10
  76. package/dist/production/dom-export.js +1 -1
  77. package/dist/production/index-react-server-client.js +1 -1
  78. package/dist/production/index-react-server.d.ts +9 -2
  79. package/dist/production/index-react-server.js +91 -88
  80. package/dist/production/index.d.ts +1 -2
  81. package/dist/production/index.js +2 -3
  82. package/dist/production/lib/actions.js +6 -18
  83. package/dist/production/lib/components.d.ts +11 -3
  84. package/dist/production/lib/components.js +8 -2
  85. package/dist/production/lib/context.js +1 -1
  86. package/dist/production/lib/dom/dom.js +1 -1
  87. package/dist/production/lib/dom/lib.d.ts +12 -1
  88. package/dist/production/lib/dom/lib.js +18 -6
  89. package/dist/production/lib/dom/server.js +2 -2
  90. package/dist/production/lib/dom/ssr/components.d.ts +4 -2
  91. package/dist/production/lib/dom/ssr/components.js +13 -3
  92. package/dist/production/lib/dom/ssr/data.js +1 -1
  93. package/dist/production/lib/dom/ssr/entry.d.ts +1 -0
  94. package/dist/production/lib/dom/ssr/errorBoundaries.js +7 -3
  95. package/dist/production/lib/dom/ssr/fallback.js +3 -1
  96. package/dist/production/lib/dom/ssr/fog-of-war.js +12 -2
  97. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  98. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  99. package/dist/production/lib/dom/ssr/links.js +1 -1
  100. package/dist/production/lib/dom/ssr/markup.js +1 -1
  101. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  102. package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
  103. package/dist/production/lib/dom/ssr/routes.js +1 -1
  104. package/dist/production/lib/dom/ssr/server.d.ts +4 -1
  105. package/dist/production/lib/dom/ssr/server.js +2 -1
  106. package/dist/production/lib/dom/ssr/single-fetch.js +2 -3
  107. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  108. package/dist/production/lib/dom-export/hydrated-router.d.ts +1 -1
  109. package/dist/production/lib/dom-export/hydrated-router.js +14 -17
  110. package/dist/production/lib/errors.js +1 -1
  111. package/dist/production/lib/hooks.js +6 -4
  112. package/dist/production/lib/href.js +1 -1
  113. package/dist/production/lib/router/history.js +3 -2
  114. package/dist/production/lib/router/instrumentation.js +1 -1
  115. package/dist/production/lib/router/links.d.ts +3 -2
  116. package/dist/production/lib/router/router.js +13 -6
  117. package/dist/production/lib/router/url.js +18 -0
  118. package/dist/production/lib/router/utils.d.ts +6 -0
  119. package/dist/production/lib/router/utils.js +27 -8
  120. package/dist/production/lib/rsc/browser.js +21 -17
  121. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  122. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  123. package/dist/production/lib/rsc/html-stream/server.js +1 -1
  124. package/dist/production/lib/rsc/route-modules.js +1 -1
  125. package/dist/production/lib/rsc/server.ssr.js +27 -11
  126. package/dist/production/lib/server-runtime/cookies.js +1 -1
  127. package/dist/production/lib/server-runtime/crypto.js +1 -1
  128. package/dist/production/lib/server-runtime/data.js +1 -1
  129. package/dist/production/lib/server-runtime/dev.js +1 -1
  130. package/dist/production/lib/server-runtime/entry.js +1 -1
  131. package/dist/production/lib/server-runtime/errors.js +2 -22
  132. package/dist/production/lib/server-runtime/headers.js +1 -1
  133. package/dist/production/lib/server-runtime/invariant.js +1 -1
  134. package/dist/production/lib/server-runtime/mode.js +1 -1
  135. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  136. package/dist/production/lib/server-runtime/routes.js +1 -1
  137. package/dist/production/lib/server-runtime/server.js +17 -23
  138. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  139. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  140. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  141. package/dist/production/lib/server-runtime/sessions.js +1 -1
  142. package/dist/production/lib/server-runtime/single-fetch.js +4 -4
  143. package/dist/production/lib/server-runtime/urls.js +2 -5
  144. package/dist/production/lib/server-runtime/warnings.js +1 -1
  145. package/dist/production/lib/types/internal.js +1 -1
  146. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  147. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +2 -1
  148. package/dist/production/vendor/turbo-stream-v2/unflatten.js +3 -2
  149. package/dist/production/vendor/turbo-stream-v2/utils.js +2 -10
  150. package/docs/explanation/code-splitting.md +1 -1
  151. package/docs/explanation/index-query-param.md +2 -2
  152. package/docs/explanation/type-safety.md +1 -1
  153. package/docs/how-to/data-strategy.md +5 -5
  154. package/docs/how-to/error-reporting.md +10 -2
  155. package/docs/how-to/headers.md +2 -1
  156. package/docs/how-to/middleware.md +8 -89
  157. package/docs/how-to/security.md +9 -7
  158. package/docs/how-to/status.md +1 -1
  159. package/docs/index.md +3 -6
  160. package/docs/start/data/installation.md +4 -0
  161. package/docs/start/data/route-object.md +20 -0
  162. package/docs/start/framework/actions.md +0 -1
  163. package/docs/start/framework/data-loading.md +1 -1
  164. package/docs/start/framework/deploying.md +4 -0
  165. package/docs/start/framework/installation.md +0 -1
  166. package/docs/start/modes.md +1 -2
  167. package/docs/upgrading/component-routes.md +2 -2
  168. package/docs/upgrading/future.md +58 -11
  169. package/docs/upgrading/router-provider.md +6 -3
  170. package/docs/upgrading/v7.md +443 -0
  171. package/package.json +7 -7
  172. package/dist/development/lib/dom/ssr/errors.d.ts +0 -7
  173. package/dist/development/lib/dom/ssr/errors.js +0 -36
  174. package/dist/production/lib/dom/ssr/errors.d.ts +0 -7
  175. package/dist/production/lib/dom/ssr/errors.js +0 -36
  176. package/docs/upgrading/remix.md +0 -403
  177. package/docs/upgrading/v6.md +0 -379
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { PROTOCOL_RELATIVE_URL_REGEX } from "./url.js";
11
12
  //#region lib/router/history.ts
12
13
  /**
13
14
  * Actions represent the type of change to a location value.
@@ -364,7 +365,7 @@ function createBrowserURLImpl(windowImpl, to, isAbsolute = false) {
364
365
  invariant(base, "No window.location.(origin|href) available to create URL");
365
366
  let href = typeof to === "string" ? to : createPath(to);
366
367
  href = href.replace(/ $/, "%20");
367
- if (!isAbsolute && href.startsWith("//")) href = base + href;
368
+ if (!isAbsolute && PROTOCOL_RELATIVE_URL_REGEX.test(href)) href = base + href;
368
369
  return new URL(href, base);
369
370
  }
370
371
  //#endregion
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -100,8 +100,9 @@ interface PageLinkDescriptor extends Omit<HtmlLinkDescriptor, "href" | "rel" | "
100
100
  /**
101
101
  * A [`nonce`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce)
102
102
  * attribute to render on the [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
103
- * element
104
- */
103
+ * element. If not provided in Framework Mode, it will default to any
104
+ * {@link ServerRouter | `<ServerRouter nonce>`} prop.
105
+ */
105
106
  nonce?: string | undefined;
106
107
  /**
107
108
  * The absolute path of the page to prefetch, e.g. `/absolute/path`.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl } from "./url.js";
11
12
  import { createBrowserURLImpl, createLocation, createPath, invariant, parsePath, warning } from "./history.js";
12
13
  import { ErrorResponseImpl, RouterContextProvider, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, flattenAndRankRoutes, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, matchRoutesImpl, prependBasename, removeDoubleSlashes, resolveTo, stripBasename } from "./utils.js";
13
14
  import { getRouteInstrumentationUpdates, instrumentClientSideRouter } from "./instrumentation.js";
@@ -2572,17 +2573,23 @@ const invalidProtocols = [
2572
2573
  "filesystem:",
2573
2574
  "javascript:"
2574
2575
  ];
2576
+ function hasInvalidProtocol(location) {
2577
+ try {
2578
+ return invalidProtocols.includes(new URL(location).protocol);
2579
+ } catch {
2580
+ return false;
2581
+ }
2582
+ }
2575
2583
  function normalizeRedirectLocation(location, currentUrl, basename, historyInstance) {
2576
2584
  if (isAbsoluteUrl(location)) {
2577
2585
  let normalizedLocation = location;
2578
- let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation);
2579
- if (invalidProtocols.includes(url.protocol)) throw new Error("Invalid redirect location");
2586
+ let url = PROTOCOL_RELATIVE_URL_REGEX.test(normalizedLocation) ? new URL(normalizeProtocolRelativeUrl(normalizedLocation, currentUrl.protocol)) : new URL(normalizedLocation);
2587
+ if (hasInvalidProtocol(url.toString())) throw new Error("Invalid redirect location");
2580
2588
  let isSameBasename = stripBasename(url.pathname, basename) != null;
2581
2589
  if (url.origin === currentUrl.origin && isSameBasename) return removeDoubleSlashes(url.pathname) + url.search + url.hash;
2582
2590
  }
2583
2591
  try {
2584
- let url = historyInstance.createURL(location);
2585
- if (invalidProtocols.includes(url.protocol)) throw new Error("Invalid redirect location");
2592
+ if (hasInvalidProtocol(historyInstance.createURL(location).toString())) throw new Error("Invalid redirect location");
2586
2593
  } catch (e) {}
2587
2594
  return location;
2588
2595
  }
@@ -2978,4 +2985,4 @@ function createDeferred() {
2978
2985
  };
2979
2986
  }
2980
2987
  //#endregion
2981
- export { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, createRouter, createStaticHandler, getStaticContextFromError, invalidProtocols, isDataWithResponseInit, isMutationMethod, isRedirectResponse, isRedirectStatusCode, isResponse };
2988
+ export { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, createRouter, createStaticHandler, getStaticContextFromError, hasInvalidProtocol, isDataWithResponseInit, isMutationMethod, isRedirectResponse, isRedirectStatusCode, isResponse };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * react-router v8.0.0
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ //#region lib/router/url.ts
12
+ const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i;
13
+ const PROTOCOL_RELATIVE_URL_REGEX = /^[\\/]{2}/;
14
+ function normalizeProtocolRelativeUrl(url, protocol) {
15
+ return protocol + url.replace(/\\/g, "/");
16
+ }
17
+ //#endregion
18
+ export { ABSOLUTE_URL_REGEX, PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl };
@@ -668,6 +668,8 @@ interface RouteMeta<RouteObjectType extends RouteObject = RouteObject> {
668
668
  caseSensitive: boolean;
669
669
  childrenIndex: number;
670
670
  route: RouteObjectType;
671
+ matcher?: RegExp;
672
+ compiledParams?: CompiledPathParam[];
671
673
  }
672
674
  /**
673
675
  * @private
@@ -752,6 +754,10 @@ interface PathMatch<ParamKey extends string = string> {
752
754
  * or `null` if it does not match.
753
755
  */
754
756
  declare function matchPath<Path extends string>(pattern: PathPattern<Path> | Path, pathname: string): PathMatch<ParamParseKey<Path>> | null;
757
+ type CompiledPathParam = {
758
+ paramName: string;
759
+ isOptional?: boolean;
760
+ };
755
761
  /**
756
762
  * Returns a resolved {@link Path} object relative to the given pathname.
757
763
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { ABSOLUTE_URL_REGEX, PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl } from "./url.js";
11
12
  import { invariant, parsePath, warning } from "./history.js";
12
13
  import * as React$1 from "react";
13
14
  //#region lib/router/utils.ts
@@ -280,7 +281,14 @@ function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "",
280
281
  branches.push({
281
282
  path,
282
283
  score: computeScore(path, route.index),
283
- routesMeta
284
+ routesMeta: routesMeta.map((meta, i) => {
285
+ let [matcher, params] = compilePath(meta.relativePath, meta.caseSensitive, i === routesMeta.length - 1);
286
+ return {
287
+ ...meta,
288
+ matcher,
289
+ compiledParams: params
290
+ };
291
+ })
284
292
  });
285
293
  };
286
294
  routes.forEach((route, index) => {
@@ -331,11 +339,12 @@ function matchRouteBranch(branch, pathname, allowPartial = false) {
331
339
  let meta = routesMeta[i];
332
340
  let end = i === routesMeta.length - 1;
333
341
  let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
334
- let match = matchPath({
342
+ let pattern = {
335
343
  path: meta.relativePath,
336
344
  caseSensitive: meta.caseSensitive,
337
345
  end
338
- }, remainingPathname);
346
+ };
347
+ let match = meta.matcher && meta.compiledParams ? matchPathImpl(pattern, remainingPathname, meta.matcher, meta.compiledParams) : matchPath(pattern, remainingPathname);
339
348
  let route = meta.route;
340
349
  if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) match = matchPath({
341
350
  path: meta.relativePath,
@@ -409,6 +418,9 @@ function matchPath(pattern, pathname) {
409
418
  end: true
410
419
  };
411
420
  let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
421
+ return matchPathImpl(pattern, pathname, matcher, compiledParams);
422
+ }
423
+ function matchPathImpl(pattern, pathname, matcher, compiledParams) {
412
424
  let match = pathname.match(matcher);
413
425
  if (!match) return null;
414
426
  let matchedPathname = match[0];
@@ -471,7 +483,6 @@ function stripBasename(pathname, basename) {
471
483
  function prependBasename({ basename, pathname }) {
472
484
  return pathname === "/" ? basename : joinPaths([basename, pathname]);
473
485
  }
474
- const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
475
486
  const isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);
476
487
  /**
477
488
  * Returns a resolved {@link Path} object relative to the given pathname.
@@ -547,7 +558,7 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = fal
547
558
  if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) path.pathname += "/";
548
559
  return path;
549
560
  }
550
- const removeDoubleSlashes = (path) => path.replace(/\/\/+/g, "/");
561
+ const removeDoubleSlashes = (path) => path.replace(/[\\/]{2,}/g, "/");
551
562
  const joinPaths = (paths) => removeDoubleSlashes(paths.join("/"));
552
563
  const removeTrailingSlash = (path) => path.replace(/\/+$/, "");
553
564
  const normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\/*/, "/");
@@ -700,6 +711,14 @@ const replace = (url, init) => {
700
711
  response.headers.set("X-Remix-Replace", "true");
701
712
  return response;
702
713
  };
714
+ const SUPPORTED_ERROR_TYPES = [
715
+ "EvalError",
716
+ "RangeError",
717
+ "ReferenceError",
718
+ "SyntaxError",
719
+ "TypeError",
720
+ "URIError"
721
+ ];
703
722
  var ErrorResponseImpl = class {
704
723
  status;
705
724
  statusText;
@@ -765,7 +784,7 @@ function parseToInfo(_to, basename) {
765
784
  let isExternal = false;
766
785
  if (isBrowser) try {
767
786
  let currentUrl = new URL(window.location.href);
768
- let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to);
787
+ let targetUrl = PROTOCOL_RELATIVE_URL_REGEX.test(to) ? new URL(normalizeProtocolRelativeUrl(to, currentUrl.protocol)) : new URL(to);
769
788
  let path = stripBasename(targetUrl.pathname, basename);
770
789
  if (targetUrl.origin === currentUrl.origin && path != null) to = path + targetUrl.search + targetUrl.hash;
771
790
  else isExternal = true;
@@ -779,4 +798,4 @@ function parseToInfo(_to, basename) {
779
798
  };
780
799
  }
781
800
  //#endregion
782
- export { ErrorResponseImpl, RouterContextProvider, compilePath, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createContext, data, decodePath, defaultMapRouteProperties, flattenAndRankRoutes, generatePath, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isBrowser, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, joinPaths, matchPath, matchRoutes, matchRoutesImpl, parseToInfo, prependBasename, redirect, redirectDocument, removeDoubleSlashes, replace, resolvePath, resolveTo, stripBasename };
801
+ export { ErrorResponseImpl, RouterContextProvider, SUPPORTED_ERROR_TYPES, compilePath, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createContext, data, decodePath, defaultMapRouteProperties, flattenAndRankRoutes, generatePath, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isBrowser, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, joinPaths, matchPath, matchRoutes, matchRoutesImpl, parseToInfo, prependBasename, redirect, redirectDocument, removeDoubleSlashes, removeTrailingSlash, replace, resolvePath, resolveTo, stripBasename };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,15 +8,16 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { PROTOCOL_RELATIVE_URL_REGEX } from "../router/url.js";
11
12
  import { createBrowserHistory, invariant } from "../router/history.js";
12
- import { ErrorResponseImpl, createContext } from "../router/utils.js";
13
- import { createRouter, invalidProtocols, isMutationMethod } from "../router/router.js";
13
+ import { ErrorResponseImpl, createContext, resolvePath } from "../router/utils.js";
14
+ import { createRouter, hasInvalidProtocol, isMutationMethod } from "../router/router.js";
14
15
  import { RSCRouterContext } from "../context.js";
15
16
  import { RouterProvider } from "../components.js";
16
17
  import { createRequestInit } from "../dom/ssr/data.js";
17
18
  import { getSingleFetchDataStrategyImpl, singleFetchUrl, stripIndexParam } from "../dom/ssr/single-fetch.js";
18
19
  import { noActionDefinedError, shouldHydrateRouteLoader } from "../dom/ssr/routes.js";
19
- import "../dom/ssr/fog-of-war.js";
20
+ import { getPathsWithAncestors } from "../dom/ssr/fog-of-war.js";
20
21
  import { FrameworkContext, setIsHydrated } from "../dom/ssr/components.js";
21
22
  import { RSCRouterGlobalErrorBoundary } from "./errorBoundaries.js";
22
23
  import { populateRSCRouteModules } from "./route-modules.js";
@@ -80,13 +81,14 @@ function createCallServer({ createFromReadableStream, createTemporaryReferenceSe
80
81
  });
81
82
  React$1.startTransition(() => Promise.resolve(payloadPromise).then(async (payload) => {
82
83
  if (payload.type === "redirect") {
83
- if (payload.reload || isExternalLocation(payload.location)) {
84
- if (hasInvalidProtocol(payload.location)) throw new Error("Invalid redirect location");
85
- window.location.href = payload.location;
84
+ let location = normalizeRedirectLocation(payload.location);
85
+ if (payload.reload || isExternalLocation(location)) {
86
+ if (hasInvalidProtocol(location)) throw new Error("Invalid redirect location");
87
+ window.location.href = location;
86
88
  return;
87
89
  }
88
90
  React$1.startTransition(() => {
89
- globalVar.__reactRouterDataRouter.navigate(payload.location, { replace: payload.replace });
91
+ globalVar.__reactRouterDataRouter.navigate(location, { replace: payload.replace });
90
92
  });
91
93
  return;
92
94
  }
@@ -94,13 +96,14 @@ function createCallServer({ createFromReadableStream, createTemporaryReferenceSe
94
96
  const rerender = await payload.rerender;
95
97
  if (rerender && landedActionId < actionId && globalVar.__routerActionID <= actionId) {
96
98
  if (rerender.type === "redirect") {
97
- if (rerender.reload || isExternalLocation(rerender.location)) {
98
- if (hasInvalidProtocol(rerender.location)) throw new Error("Invalid redirect location");
99
- window.location.href = rerender.location;
99
+ let location = normalizeRedirectLocation(rerender.location);
100
+ if (rerender.reload || isExternalLocation(location)) {
101
+ if (hasInvalidProtocol(location)) throw new Error("Invalid redirect location");
102
+ window.location.href = location;
100
103
  return;
101
104
  }
102
105
  React$1.startTransition(() => {
103
- globalVar.__reactRouterDataRouter.navigate(rerender.location, { replace: rerender.replace });
106
+ globalVar.__reactRouterDataRouter.navigate(location, { replace: rerender.replace });
104
107
  });
105
108
  return;
106
109
  }
@@ -533,6 +536,7 @@ function getManifestUrl(paths) {
533
536
  return url;
534
537
  }
535
538
  async function fetchAndApplyManifestPatches(paths, createFromReadableStream, fetchImplementation, signal) {
539
+ paths = getPathsWithAncestors(paths);
536
540
  let url = getManifestUrl(paths);
537
541
  if (url == null) return;
538
542
  if (url.toString().length > 7680) {
@@ -568,12 +572,12 @@ function debounce(callback, wait) {
568
572
  function isExternalLocation(location) {
569
573
  return new URL(location, window.location.href).origin !== window.location.origin;
570
574
  }
571
- function hasInvalidProtocol(location) {
572
- try {
573
- return invalidProtocols.includes(new URL(location).protocol);
574
- } catch {
575
- return false;
575
+ function normalizeRedirectLocation(location) {
576
+ if (PROTOCOL_RELATIVE_URL_REGEX.test(location)) {
577
+ let path = resolvePath(location);
578
+ return path.pathname + path.search + path.hash;
576
579
  }
580
+ return location;
577
581
  }
578
582
  function cloneRoutes(routes) {
579
583
  if (!routes) return void 0;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -9,6 +9,7 @@
9
9
  * @license MIT
10
10
  */
11
11
  import { isRouteErrorResponse } from "../router/utils.js";
12
+ import { hasInvalidProtocol } from "../router/router.js";
12
13
  import { RSCRouterContext } from "../context.js";
13
14
  import { decodeRedirectErrorDigest, decodeRouteErrorResponseDigest } from "../errors.js";
14
15
  import { escapeHtml } from "../dom/ssr/markup.js";
@@ -122,6 +123,7 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
122
123
  if (!detectRedirectResponse.body) throw new Error("Failed to clone server response");
123
124
  const payload = await createFromReadableStream(detectRedirectResponse.body);
124
125
  if (serverResponse.status === 202 && payload.type === "redirect") {
126
+ if (hasInvalidProtocol(payload.location)) throw new Error("Invalid redirect location");
125
127
  const headers = new Headers(serverResponse.headers);
126
128
  headers.delete("Content-Encoding");
127
129
  headers.delete("Content-Length");
@@ -159,6 +161,7 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
159
161
  for (const [key, value] of serverResponse.headers) headers.append(key, value);
160
162
  headers.set("Content-Type", "text/html; charset=utf-8");
161
163
  if (renderRedirect) {
164
+ if (hasInvalidProtocol(renderRedirect.location)) throw new Error("Invalid redirect location");
162
165
  headers.set("Location", renderRedirect.location);
163
166
  return new Response(html, {
164
167
  status: renderRedirect.status,
@@ -166,7 +169,10 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
166
169
  });
167
170
  }
168
171
  const redirectTransform = new TransformStream({ flush(controller) {
169
- if (renderRedirect) controller.enqueue(new TextEncoder().encode(`<meta http-equiv="refresh" content="0;url=${escapeHtml(renderRedirect.location)}"/>`));
172
+ if (renderRedirect) {
173
+ if (hasInvalidProtocol(renderRedirect.location)) return;
174
+ controller.enqueue(new TextEncoder().encode(`<meta http-equiv="refresh" content="0;url=${escapeHtml(renderRedirect.location)}"/>`));
175
+ }
170
176
  } });
171
177
  if (!hydrate) return new Response(html.pipeThrough(redirectTransform), {
172
178
  status,
@@ -182,10 +188,13 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
182
188
  });
183
189
  } catch (error) {
184
190
  if (error instanceof Response) return error;
185
- if (renderRedirect) return new Response(`Redirect: ${renderRedirect.location}`, {
186
- status: renderRedirect.status,
187
- headers: { Location: renderRedirect.location }
188
- });
191
+ if (renderRedirect) {
192
+ if (hasInvalidProtocol(renderRedirect.location)) throw new Error("Invalid redirect location");
193
+ return new Response(`Redirect: ${renderRedirect.location}`, {
194
+ status: renderRedirect.status,
195
+ headers: { Location: renderRedirect.location }
196
+ });
197
+ }
189
198
  try {
190
199
  let normalizedError = renderError ?? error;
191
200
  let [status, statusText] = isRouteErrorResponse(normalizedError) ? [normalizedError.status, normalizedError.statusText] : [500, ""];
@@ -230,6 +239,7 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
230
239
  for (const [key, value] of serverResponse.headers) headers.append(key, value);
231
240
  headers.set("Content-Type", "text/html; charset=utf-8");
232
241
  if (retryRedirect) {
242
+ if (hasInvalidProtocol(retryRedirect.location)) throw new Error("Invalid redirect location");
233
243
  headers.set("Location", retryRedirect.location);
234
244
  return new Response(html, {
235
245
  status: retryRedirect.status,
@@ -237,7 +247,10 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
237
247
  });
238
248
  }
239
249
  const retryRedirectTransform = new TransformStream({ flush(controller) {
240
- if (retryRedirect) controller.enqueue(new TextEncoder().encode(`<meta http-equiv="refresh" content="0;url=${escapeHtml(retryRedirect.location)}"/>`));
250
+ if (retryRedirect) {
251
+ if (hasInvalidProtocol(retryRedirect.location)) return;
252
+ controller.enqueue(new TextEncoder().encode(`<meta http-equiv="refresh" content="0;url=${escapeHtml(retryRedirect.location)}"/>`));
253
+ }
241
254
  } });
242
255
  if (!hydrate) return new Response(html.pipeThrough(retryRedirectTransform), {
243
256
  status,
@@ -295,10 +308,13 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
295
308
  function RSCStaticRouter({ getPayload }) {
296
309
  const decoded = getPayload();
297
310
  const payload = React$1.use(decoded);
298
- if (payload.type === "redirect") throw new Response(null, {
299
- status: payload.status,
300
- headers: { Location: payload.location }
301
- });
311
+ if (payload.type === "redirect") {
312
+ if (hasInvalidProtocol(payload.location)) throw new Error("Invalid redirect location");
313
+ throw new Response(null, {
314
+ status: payload.status,
315
+ headers: { Location: payload.location }
316
+ });
317
+ }
302
318
  if (payload.type !== "render") return null;
303
319
  let patchedLoaderData = { ...payload.loaderData };
304
320
  for (const match of payload.matches) if (shouldHydrateRouteLoader(match.id, match.clientLoader, match.hasLoader, false) && (match.hydrateFallbackElement || !match.hasLoader)) delete patchedLoaderData[match.id];
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,7 +8,6 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { isRouteErrorResponse } from "../router/utils.js";
12
11
  import "./mode.js";
13
12
  //#region lib/server-runtime/errors.ts
14
13
  /**
@@ -72,24 +71,5 @@ function serializeError(error, serverMode) {
72
71
  stack: sanitized.stack
73
72
  };
74
73
  }
75
- function serializeErrors(errors, serverMode) {
76
- if (!errors) return null;
77
- let entries = Object.entries(errors);
78
- let serialized = {};
79
- for (let [key, val] of entries) if (isRouteErrorResponse(val)) serialized[key] = {
80
- ...val,
81
- __type: "RouteErrorResponse"
82
- };
83
- else if (val instanceof Error) {
84
- let sanitized = sanitizeError(val, serverMode);
85
- serialized[key] = {
86
- message: sanitized.message,
87
- stack: sanitized.stack,
88
- __type: "Error",
89
- ...sanitized.name !== "Error" ? { __subType: sanitized.name } : {}
90
- };
91
- } else serialized[key] = val;
92
- return serialized;
93
- }
94
74
  //#endregion
95
- export { sanitizeError, sanitizeErrors, serializeError, serializeErrors };
75
+ export { sanitizeError, sanitizeErrors, serializeError };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *