react-router 8.3.0 → 8.3.1

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 (138) hide show
  1. package/CHANGELOG.md +13 -2
  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 +8 -0
  5. package/dist/development/index-react-server.js +22 -13
  6. package/dist/development/index.js +1 -1
  7. package/dist/development/lib/actions.js +10 -5
  8. package/dist/development/lib/components.js +6 -3
  9. package/dist/development/lib/context.d.ts +1 -0
  10. package/dist/development/lib/context.js +1 -1
  11. package/dist/development/lib/dom/dom.js +2 -2
  12. package/dist/development/lib/dom/lib.js +20 -5
  13. package/dist/development/lib/dom/server.js +1 -1
  14. package/dist/development/lib/dom/ssr/components.js +2 -2
  15. package/dist/development/lib/dom/ssr/data.js +1 -1
  16. package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
  17. package/dist/development/lib/dom/ssr/fallback.js +1 -1
  18. package/dist/development/lib/dom/ssr/fog-of-war.js +2 -1
  19. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  20. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  21. package/dist/development/lib/dom/ssr/links.js +1 -1
  22. package/dist/development/lib/dom/ssr/markup.js +1 -1
  23. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  24. package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
  25. package/dist/development/lib/dom/ssr/routes.js +1 -1
  26. package/dist/development/lib/dom/ssr/server.js +1 -1
  27. package/dist/development/lib/dom/ssr/single-fetch.js +5 -5
  28. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  29. package/dist/development/lib/dom-export/hydrated-router.js +1 -1
  30. package/dist/development/lib/errors.js +1 -1
  31. package/dist/development/lib/hooks.js +6 -3
  32. package/dist/development/lib/href.js +1 -1
  33. package/dist/development/lib/router/history.js +2 -2
  34. package/dist/development/lib/router/instrumentation.js +1 -1
  35. package/dist/development/lib/router/navigation.js +45 -0
  36. package/dist/development/lib/router/router.d.ts +8 -0
  37. package/dist/development/lib/router/router.js +31 -17
  38. package/dist/development/lib/router/url.js +1 -1
  39. package/dist/development/lib/router/utils.js +10 -6
  40. package/dist/development/lib/rsc/browser.js +4 -1
  41. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  42. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  43. package/dist/development/lib/rsc/html-stream/server.js +2 -2
  44. package/dist/development/lib/rsc/route-modules.js +1 -1
  45. package/dist/development/lib/rsc/server.ssr.js +2 -2
  46. package/dist/development/lib/server-runtime/cookies.js +2 -2
  47. package/dist/development/lib/server-runtime/crypto.js +2 -2
  48. package/dist/development/lib/server-runtime/data.js +1 -1
  49. package/dist/development/lib/server-runtime/dev.js +2 -2
  50. package/dist/development/lib/server-runtime/entry.js +1 -1
  51. package/dist/development/lib/server-runtime/errors.js +1 -1
  52. package/dist/development/lib/server-runtime/headers.js +1 -1
  53. package/dist/development/lib/server-runtime/invariant.js +1 -1
  54. package/dist/development/lib/server-runtime/mode.js +1 -1
  55. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  56. package/dist/development/lib/server-runtime/routes.js +1 -1
  57. package/dist/development/lib/server-runtime/server.js +2 -2
  58. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  59. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  60. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  61. package/dist/development/lib/server-runtime/sessions.js +1 -1
  62. package/dist/development/lib/server-runtime/single-fetch.js +2 -2
  63. package/dist/development/lib/server-runtime/urls.js +1 -1
  64. package/dist/development/lib/server-runtime/warnings.js +1 -1
  65. package/dist/development/lib/types/internal.js +1 -1
  66. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  67. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +4 -4
  68. package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
  69. package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
  70. package/dist/production/dom-export.js +1 -1
  71. package/dist/production/index-react-server-client.js +1 -1
  72. package/dist/production/index-react-server.d.ts +8 -0
  73. package/dist/production/index-react-server.js +22 -13
  74. package/dist/production/index.js +1 -1
  75. package/dist/production/lib/actions.js +10 -5
  76. package/dist/production/lib/components.js +6 -3
  77. package/dist/production/lib/context.d.ts +1 -0
  78. package/dist/production/lib/context.js +1 -1
  79. package/dist/production/lib/dom/dom.js +2 -2
  80. package/dist/production/lib/dom/lib.js +20 -5
  81. package/dist/production/lib/dom/server.js +1 -1
  82. package/dist/production/lib/dom/ssr/components.js +2 -2
  83. package/dist/production/lib/dom/ssr/data.js +1 -1
  84. package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
  85. package/dist/production/lib/dom/ssr/fallback.js +1 -1
  86. package/dist/production/lib/dom/ssr/fog-of-war.js +2 -1
  87. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  88. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  89. package/dist/production/lib/dom/ssr/links.js +1 -1
  90. package/dist/production/lib/dom/ssr/markup.js +1 -1
  91. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  92. package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
  93. package/dist/production/lib/dom/ssr/routes.js +1 -1
  94. package/dist/production/lib/dom/ssr/server.js +1 -1
  95. package/dist/production/lib/dom/ssr/single-fetch.js +5 -5
  96. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  97. package/dist/production/lib/dom-export/hydrated-router.js +1 -1
  98. package/dist/production/lib/errors.js +1 -1
  99. package/dist/production/lib/hooks.js +6 -3
  100. package/dist/production/lib/href.js +1 -1
  101. package/dist/production/lib/router/history.js +2 -2
  102. package/dist/production/lib/router/instrumentation.js +1 -1
  103. package/dist/production/lib/router/navigation.js +45 -0
  104. package/dist/production/lib/router/router.d.ts +8 -0
  105. package/dist/production/lib/router/router.js +31 -17
  106. package/dist/production/lib/router/url.js +1 -1
  107. package/dist/production/lib/router/utils.js +10 -6
  108. package/dist/production/lib/rsc/browser.js +4 -1
  109. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  110. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  111. package/dist/production/lib/rsc/html-stream/server.js +2 -2
  112. package/dist/production/lib/rsc/route-modules.js +1 -1
  113. package/dist/production/lib/rsc/server.ssr.js +2 -2
  114. package/dist/production/lib/server-runtime/cookies.js +2 -2
  115. package/dist/production/lib/server-runtime/crypto.js +2 -2
  116. package/dist/production/lib/server-runtime/data.js +1 -1
  117. package/dist/production/lib/server-runtime/dev.js +2 -2
  118. package/dist/production/lib/server-runtime/entry.js +1 -1
  119. package/dist/production/lib/server-runtime/errors.js +1 -1
  120. package/dist/production/lib/server-runtime/headers.js +1 -1
  121. package/dist/production/lib/server-runtime/invariant.js +1 -1
  122. package/dist/production/lib/server-runtime/mode.js +1 -1
  123. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  124. package/dist/production/lib/server-runtime/routes.js +1 -1
  125. package/dist/production/lib/server-runtime/server.js +2 -2
  126. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  127. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  128. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  129. package/dist/production/lib/server-runtime/sessions.js +1 -1
  130. package/dist/production/lib/server-runtime/single-fetch.js +2 -2
  131. package/dist/production/lib/server-runtime/urls.js +1 -1
  132. package/dist/production/lib/server-runtime/warnings.js +1 -1
  133. package/dist/production/lib/types/internal.js +1 -1
  134. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  135. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +4 -4
  136. package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
  137. package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
  138. package/package.json +1 -1
@@ -0,0 +1,45 @@
1
+ /**
2
+ * react-router v8.3.1
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/navigation.ts
12
+ const DEFAULT_NAVIGATION_URL = new URL("http://localhost");
13
+ function getNavigatorCurrentUrl(navigator) {
14
+ if (navigator.createURL) return navigator.createURL("/");
15
+ try {
16
+ return new URL(navigator.createHref("/"), DEFAULT_NAVIGATION_URL);
17
+ } catch {
18
+ return DEFAULT_NAVIGATION_URL;
19
+ }
20
+ }
21
+ function isSameOrigin(a, b) {
22
+ return a.origin === b.origin && (a.origin !== "null" || a.protocol === b.protocol && a.host === b.host);
23
+ }
24
+ function isExplicitUrl(destination, target) {
25
+ if (destination.startsWith("//")) return true;
26
+ let protocol = target.protocol.toLowerCase();
27
+ if (!destination.toLowerCase().startsWith(protocol)) return false;
28
+ return target.host === "" || destination.slice(protocol.length).startsWith("//");
29
+ }
30
+ function validateNavigationTarget(original, resolved, currentUrl, externalPolicy) {
31
+ let originalUrl = null;
32
+ try {
33
+ originalUrl = original == null ? null : new URL(original, currentUrl);
34
+ } catch {}
35
+ let resolvedUrl = new URL(resolved, currentUrl);
36
+ let originalIsExternal = originalUrl != null && !isSameOrigin(originalUrl, currentUrl);
37
+ let resolvedIsExternal = !isSameOrigin(resolvedUrl, currentUrl);
38
+ if (externalPolicy === "reject") {
39
+ if (originalIsExternal || resolvedIsExternal) throw new Error("External navigation is not allowed");
40
+ } else if (resolvedIsExternal) {
41
+ if (originalUrl == null || !isExplicitUrl(original, originalUrl) || !isSameOrigin(originalUrl, resolvedUrl)) throw new Error("External navigation is not allowed");
42
+ }
43
+ }
44
+ //#endregion
45
+ export { getNavigatorCurrentUrl, validateNavigationTarget };
@@ -128,6 +128,14 @@ interface Router {
128
128
  * @param location
129
129
  */
130
130
  createHref(location: Location | URL): string;
131
+ /**
132
+ * @private
133
+ * PRIVATE - DO NOT USE
134
+ *
135
+ * Utility function to create a URL for the given location
136
+ * @param location
137
+ */
138
+ createURL?(to: To): URL;
131
139
  /**
132
140
  * @private
133
141
  * PRIVATE - DO NOT USE
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -12,6 +12,7 @@ import { PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl } from "./url
12
12
  import { createBrowserURLImpl, createLocation, createPath, invariant, parsePath, warning } from "./history.js";
13
13
  import { ErrorResponseImpl, RouterContextProvider, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createDataFunctionUrl, flattenAndRankRoutes, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, matchRoutesImpl, prependBasename, removeDoubleSlashes, resolveTo, stripBasename } from "./utils.js";
14
14
  import { consumeInstrumentationClientResultMetaReceiver, getRouteInstrumentationUpdates, instrumentClientSideRouter } from "./instrumentation.js";
15
+ import { validateNavigationTarget } from "./navigation.js";
15
16
  //#region lib/router/router.ts
16
17
  const validMutationMethodsArr = [
17
18
  "POST",
@@ -412,21 +413,27 @@ function createRouter(init) {
412
413
  let instrumentationNavigateMetaReceiver = consumeInstrumentationClientResultMetaReceiver(router);
413
414
  let { path, submission, error } = normalizeNavigateOptions(false, normalizeTo(state.location, state.matches, basename, to, opts?.fromRouteId, opts?.relative), opts);
414
415
  let maskPath;
415
- if (opts?.mask) maskPath = {
416
- pathname: "",
417
- search: "",
418
- hash: "",
419
- ...typeof opts.mask === "string" ? parsePath(opts.mask) : {
416
+ if (opts?.mask) {
417
+ let partialPath = typeof opts.mask === "string" ? parsePath(opts.mask) : {
420
418
  ...state.location.mask,
421
419
  ...opts.mask
422
- }
423
- };
420
+ };
421
+ maskPath = {
422
+ pathname: partialPath.pathname ?? "",
423
+ search: partialPath.search ?? "",
424
+ hash: partialPath.hash ?? ""
425
+ };
426
+ if (PROTOCOL_RELATIVE_URL_REGEX.test(maskPath.pathname)) throw new Error("External navigation is not allowed");
427
+ else if (maskPath.pathname.startsWith("\\")) maskPath.pathname = maskPath.pathname.replace(/^\\+/, "/");
428
+ validateNavigationTarget(typeof opts.mask === "string" ? opts.mask : createPath(opts.mask), createPath(maskPath), init.history.createURL("/"), "reject");
429
+ }
424
430
  let currentLocation = state.location;
425
431
  let nextLocation = createLocation(currentLocation, path, opts && opts.state, void 0, maskPath);
426
432
  nextLocation = {
427
433
  ...nextLocation,
428
434
  ...init.history.encodeLocation(nextLocation)
429
435
  };
436
+ validateNavigationTarget(to == null ? init.history.createHref(state.location) : typeof to === "string" ? to : createPath(to), init.history.createHref(nextLocation.mask || nextLocation), init.history.createURL("/"), "reject");
430
437
  let userReplace = opts && opts.replace != null ? opts.replace : void 0;
431
438
  let historyAction = "PUSH";
432
439
  if (userReplace === true) historyAction = "REPLACE";
@@ -883,7 +890,10 @@ function createRouter(init) {
883
890
  let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));
884
891
  abortController.signal.addEventListener("abort", abortPendingFetchRevalidations);
885
892
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, revalidationRequest, nextLocation, scopedContext);
886
- if (abortController.signal.aborted) return;
893
+ if (abortController.signal.aborted) {
894
+ if (fetchReloadIds.get(key) === loadId) fetchReloadIds.delete(key);
895
+ return;
896
+ }
887
897
  abortController.signal.removeEventListener("abort", abortPendingFetchRevalidations);
888
898
  fetchReloadIds.delete(key);
889
899
  fetchControllers.delete(key);
@@ -1005,7 +1015,10 @@ function createRouter(init) {
1005
1015
  if (redirect.response.headers.has("X-Remix-Revalidate")) isRevalidationRequired = true;
1006
1016
  let location = redirect.response.headers.get("Location");
1007
1017
  invariant(location, "Expected a Location header on the redirect Response");
1008
- location = normalizeRedirectLocation(location, new URL(request.url), basename, init.history);
1018
+ let originalLocation = location;
1019
+ let currentUrl = new URL(request.url);
1020
+ location = normalizeRedirectLocation(location, currentUrl, basename, init.history);
1021
+ validateNavigationTarget(originalLocation, location, currentUrl, "allow-explicit");
1009
1022
  let redirectLocation = createLocation(state.location, location, { _isRedirect: true });
1010
1023
  if (isBrowser) {
1011
1024
  let isDocumentReload = false;
@@ -1357,6 +1370,7 @@ function createRouter(init) {
1357
1370
  fetch,
1358
1371
  revalidate,
1359
1372
  createHref: (to) => init.history.createHref(to),
1373
+ createURL: (to) => init.history.createURL(to),
1360
1374
  encodeLocation: (to) => init.history.encodeLocation(to),
1361
1375
  getFetcher,
1362
1376
  resetFetcher,
@@ -1876,7 +1890,7 @@ function normalizeNavigateOptions(isFetcher, path, opts) {
1876
1890
  text: void 0
1877
1891
  }
1878
1892
  };
1879
- } catch (e) {
1893
+ } catch {
1880
1894
  return getInvalidBodyError();
1881
1895
  }
1882
1896
  }
@@ -1899,7 +1913,7 @@ function normalizeNavigateOptions(isFetcher, path, opts) {
1899
1913
  } else try {
1900
1914
  searchParams = new URLSearchParams(opts.body);
1901
1915
  formData = convertSearchParamsToFormData(searchParams);
1902
- } catch (e) {
1916
+ } catch {
1903
1917
  return getInvalidBodyError();
1904
1918
  }
1905
1919
  let submission = {
@@ -2415,7 +2429,7 @@ async function callDataStrategyImpl(dataStrategyImpl, request, path, matches, fe
2415
2429
  });
2416
2430
  try {
2417
2431
  await Promise.all(matches.flatMap((m) => [m._lazyPromises?.handler, m._lazyPromises?.route]));
2418
- } catch (e) {}
2432
+ } catch {}
2419
2433
  return results;
2420
2434
  }
2421
2435
  async function callLoaderOrAction({ request, path, pattern, match, lazyHandlerPromise, lazyRoutePromise, handlerOverride, scopedContext }) {
@@ -2598,7 +2612,7 @@ function normalizeRedirectLocation(location, currentUrl, basename, historyInstan
2598
2612
  }
2599
2613
  try {
2600
2614
  if (hasInvalidProtocol(historyInstance.createURL(location).toString())) throw new Error("Invalid redirect location");
2601
- } catch (e) {}
2615
+ } catch {}
2602
2616
  return location;
2603
2617
  }
2604
2618
  function createClientSideRequest(history, location, signal, submission) {
@@ -2948,7 +2962,7 @@ function restoreAppliedTransitions(_window, transitions) {
2948
2962
  let json = JSON.parse(sessionPositions);
2949
2963
  for (let [k, v] of Object.entries(json || {})) if (v && Array.isArray(v)) transitions.set(k, new Set(v || []));
2950
2964
  }
2951
- } catch (e) {}
2965
+ } catch {}
2952
2966
  }
2953
2967
  function persistAppliedTransitions(_window, transitions) {
2954
2968
  if (transitions.size > 0) {
@@ -2969,13 +2983,13 @@ function createDeferred() {
2969
2983
  res(val);
2970
2984
  try {
2971
2985
  await promise;
2972
- } catch (e) {}
2986
+ } catch {}
2973
2987
  };
2974
2988
  reject = async (error) => {
2975
2989
  rej(error);
2976
2990
  try {
2977
2991
  await promise;
2978
- } catch (e) {}
2992
+ } catch {}
2979
2993
  };
2980
2994
  });
2981
2995
  return {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -489,13 +489,13 @@ function matchPathImpl(pattern, pathname, matcher, compiledParams) {
489
489
  let match = pathname.match(matcher);
490
490
  if (!match) return null;
491
491
  let matchedPathname = match[0];
492
- let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
492
+ let pathnameBase = removeTrailingSlash(matchedPathname, 1);
493
493
  let captureGroups = match.slice(1);
494
494
  return {
495
495
  params: compiledParams.reduce((memo, { paramName, isOptional }, index) => {
496
496
  if (paramName === "*") {
497
497
  let splatValue = captureGroups[index] || "";
498
- pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
498
+ pathnameBase = removeTrailingSlash(matchedPathname.slice(0, matchedPathname.length - splatValue.length), 1);
499
499
  }
500
500
  const value = captureGroups[index];
501
501
  if (isOptional && !value) memo[paramName] = void 0;
@@ -564,7 +564,7 @@ function resolvePath(to, fromPathname = "/") {
564
564
  let pathname;
565
565
  if (toPathname) {
566
566
  toPathname = removeDoubleSlashes(toPathname);
567
- if (toPathname.startsWith("/")) pathname = resolvePathname(toPathname.substring(1), "/");
567
+ if (toPathname.startsWith("/") || toPathname.startsWith("\\")) pathname = resolvePathname(toPathname.substring(1), "/");
568
568
  else pathname = resolvePathname(toPathname, fromPathname);
569
569
  } else pathname = fromPathname;
570
570
  return {
@@ -625,7 +625,11 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = fal
625
625
  }
626
626
  const removeDoubleSlashes = (path) => path.replace(/[\\/]{2,}/g, "/");
627
627
  const joinPaths = (paths) => removeDoubleSlashes(paths.join("/"));
628
- const removeTrailingSlash = (path) => path.replace(/\/+$/, "");
628
+ function removeTrailingSlash(path, minLength = 0) {
629
+ let end = path.length;
630
+ while (end > minLength && path.charCodeAt(end - 1) === 47) end--;
631
+ return end === path.length ? path : path.slice(0, end);
632
+ }
629
633
  const normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\/*/, "/");
630
634
  const normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
631
635
  const normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
@@ -868,7 +872,7 @@ function parseToInfo(_to, basename) {
868
872
  let path = stripBasename(targetUrl.pathname, basename);
869
873
  if (targetUrl.origin === currentUrl.origin && path != null) to = path + targetUrl.search + targetUrl.hash;
870
874
  else isExternal = true;
871
- } catch (e) {
875
+ } catch {
872
876
  warning(false, `<Link to="${to}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`);
873
877
  }
874
878
  return {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -11,6 +11,7 @@
11
11
  import { PROTOCOL_RELATIVE_URL_REGEX } from "../router/url.js";
12
12
  import { createBrowserHistory, createPath, invariant } from "../router/history.js";
13
13
  import { ErrorResponseImpl, createContext, resolvePath } from "../router/utils.js";
14
+ import { validateNavigationTarget } from "../router/navigation.js";
14
15
  import { createRouter, hasInvalidProtocol, isMutationMethod } from "../router/router.js";
15
16
  import { RSCRouterContext } from "../context.js";
16
17
  import { RouterProvider } from "../components.js";
@@ -82,6 +83,7 @@ function createCallServer({ createFromReadableStream, createTemporaryReferenceSe
82
83
  React$1.startTransition(() => Promise.resolve(payloadPromise).then(async (payload) => {
83
84
  if (payload.type === "redirect") {
84
85
  let location = normalizeRedirectLocation(payload.location);
86
+ validateNavigationTarget(payload.location, location, new URL(window.location.href), "allow-explicit");
85
87
  if (payload.reload || isExternalLocation(location)) {
86
88
  if (hasInvalidProtocol(location)) throw new Error("Invalid redirect location");
87
89
  window.location.href = location;
@@ -97,6 +99,7 @@ function createCallServer({ createFromReadableStream, createTemporaryReferenceSe
97
99
  if (rerender && landedActionId < actionId && globalVar.__routerActionID <= actionId) {
98
100
  if (rerender.type === "redirect") {
99
101
  let location = normalizeRedirectLocation(rerender.location);
102
+ validateNavigationTarget(rerender.location, location, new URL(window.location.href), "allow-explicit");
100
103
  if (rerender.reload || isExternalLocation(location)) {
101
104
  if (hasInvalidProtocol(location)) throw new Error("Invalid redirect location");
102
105
  window.location.href = location;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -73,7 +73,7 @@ async function writeRSCStream(reader, controller, isCancelled, nonce) {
73
73
  const chunk = read.value;
74
74
  try {
75
75
  writeChunk(JSON.stringify(decoder.decode(chunk, { stream: true })), controller, nonce);
76
- } catch (e) {
76
+ } catch {
77
77
  writeChunk(`Uint8Array.from(atob(${JSON.stringify(btoa(String.fromCodePoint(...chunk)))}), m => m.codePointAt(0))`, controller, nonce);
78
78
  }
79
79
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -273,7 +273,7 @@ async function routeRSCServerRequest({ request, serverResponse, createFromReadab
273
273
  statusText,
274
274
  headers
275
275
  });
276
- } catch (error2) {}
276
+ } catch {}
277
277
  throw error;
278
278
  }
279
279
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -95,7 +95,7 @@ function encodeData(value) {
95
95
  function decodeData(value) {
96
96
  try {
97
97
  return JSON.parse(decodeURIComponent(myEscape(atob(value))));
98
- } catch (e) {
98
+ } catch {
99
99
  return {};
100
100
  }
101
101
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -26,7 +26,7 @@ const unsign = async (cookie, secret) => {
26
26
  try {
27
27
  let signature = byteStringToUint8Array(atob(hash));
28
28
  return await crypto.subtle.verify("HMAC", key, signature, data) ? value : false;
29
- } catch (e) {
29
+ } catch {
30
30
  return false;
31
31
  }
32
32
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -19,7 +19,7 @@ function getDevServerHooks() {
19
19
  function getBuildTimeHeader(request, headerName) {
20
20
  if (typeof process !== "undefined") try {
21
21
  if (process.env.hasOwnProperty("IS_RR_BUILD_REQUEST") && process.env.IS_RR_BUILD_REQUEST === "yes") return request.headers.get(headerName);
22
- } catch (e) {}
22
+ } catch {}
23
23
  return null;
24
24
  }
25
25
  //#endregion
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -281,7 +281,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
281
281
  if (isResponse(error)) try {
282
282
  let data = await unwrapResponse(error);
283
283
  errorForSecondRender = new ErrorResponseImpl(error.status, error.statusText, data);
284
- } catch (e) {}
284
+ } catch {}
285
285
  context = getStaticContextFromError(staticHandler.dataRoutes, context, errorForSecondRender);
286
286
  if (context.errors) context.errors = sanitizeErrors(context.errors, serverMode);
287
287
  let state = {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -23,7 +23,7 @@ async function singleFetchAction(build, serverMode, staticHandler, request, load
23
23
  try {
24
24
  try {
25
25
  throwIfPotentialCSRFAttack(request, Array.isArray(build.allowedActionOrigins) ? build.allowedActionOrigins : []);
26
- } catch (e) {
26
+ } catch {
27
27
  return handleQueryError(/* @__PURE__ */ new Error("Bad Request"), 400);
28
28
  }
29
29
  return handleQueryResult(await staticHandler.query(request, {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -41,7 +41,7 @@ async function decodeInitial(reader) {
41
41
  let line;
42
42
  try {
43
43
  line = JSON.parse(read.value);
44
- } catch (reason) {
44
+ } catch {
45
45
  throw new SyntaxError();
46
46
  }
47
47
  return {
@@ -64,7 +64,7 @@ async function decodeDeferred(reader) {
64
64
  let jsonLine;
65
65
  try {
66
66
  jsonLine = JSON.parse(lineData);
67
- } catch (reason) {
67
+ } catch {
68
68
  throw new SyntaxError();
69
69
  }
70
70
  const value = unflatten.call(this, jsonLine);
@@ -80,7 +80,7 @@ async function decodeDeferred(reader) {
80
80
  let jsonLine;
81
81
  try {
82
82
  jsonLine = JSON.parse(lineData);
83
- } catch (reason) {
83
+ } catch {
84
84
  throw new SyntaxError();
85
85
  }
86
86
  const value = unflatten.call(this, jsonLine);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.3.0
2
+ * react-router v8.3.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1231,6 +1231,14 @@ interface Router$1 {
1231
1231
  * @param location
1232
1232
  */
1233
1233
  createHref(location: Location | URL): string;
1234
+ /**
1235
+ * @private
1236
+ * PRIVATE - DO NOT USE
1237
+ *
1238
+ * Utility function to create a URL for the given location
1239
+ * @param location
1240
+ */
1241
+ createURL?(to: To): URL;
1234
1242
  /**
1235
1243
  * @private
1236
1244
  * PRIVATE - DO NOT USE