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.
- package/CHANGELOG.md +13 -2
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +1 -1
- package/dist/development/index-react-server.d.ts +8 -0
- package/dist/development/index-react-server.js +22 -13
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +10 -5
- package/dist/development/lib/components.js +6 -3
- package/dist/development/lib/context.d.ts +1 -0
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.js +2 -2
- package/dist/development/lib/dom/lib.js +20 -5
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +2 -2
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/development/lib/dom/ssr/fallback.js +1 -1
- package/dist/development/lib/dom/ssr/fog-of-war.js +2 -1
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/development/lib/dom/ssr/routes.js +1 -1
- package/dist/development/lib/dom/ssr/server.js +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.js +5 -5
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +1 -1
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.js +6 -3
- package/dist/development/lib/href.js +1 -1
- package/dist/development/lib/router/history.js +2 -2
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/navigation.js +45 -0
- package/dist/development/lib/router/router.d.ts +8 -0
- package/dist/development/lib/router/router.js +31 -17
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.js +10 -6
- package/dist/development/lib/rsc/browser.js +4 -1
- package/dist/development/lib/rsc/errorBoundaries.js +1 -1
- package/dist/development/lib/rsc/html-stream/browser.js +1 -1
- package/dist/development/lib/rsc/html-stream/server.js +2 -2
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.ssr.js +2 -2
- package/dist/development/lib/server-runtime/cookies.js +2 -2
- package/dist/development/lib/server-runtime/crypto.js +2 -2
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +2 -2
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +2 -2
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions.js +1 -1
- package/dist/development/lib/server-runtime/single-fetch.js +2 -2
- package/dist/development/lib/server-runtime/urls.js +1 -1
- package/dist/development/lib/server-runtime/warnings.js +1 -1
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +4 -4
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
- package/dist/production/dom-export.js +1 -1
- package/dist/production/index-react-server-client.js +1 -1
- package/dist/production/index-react-server.d.ts +8 -0
- package/dist/production/index-react-server.js +22 -13
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +10 -5
- package/dist/production/lib/components.js +6 -3
- package/dist/production/lib/context.d.ts +1 -0
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.js +2 -2
- package/dist/production/lib/dom/lib.js +20 -5
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +2 -2
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/production/lib/dom/ssr/fallback.js +1 -1
- package/dist/production/lib/dom/ssr/fog-of-war.js +2 -1
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/production/lib/dom/ssr/routes.js +1 -1
- package/dist/production/lib/dom/ssr/server.js +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.js +5 -5
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +1 -1
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.js +6 -3
- package/dist/production/lib/href.js +1 -1
- package/dist/production/lib/router/history.js +2 -2
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/navigation.js +45 -0
- package/dist/production/lib/router/router.d.ts +8 -0
- package/dist/production/lib/router/router.js +31 -17
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.js +10 -6
- package/dist/production/lib/rsc/browser.js +4 -1
- package/dist/production/lib/rsc/errorBoundaries.js +1 -1
- package/dist/production/lib/rsc/html-stream/browser.js +1 -1
- package/dist/production/lib/rsc/html-stream/server.js +2 -2
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.ssr.js +2 -2
- package/dist/production/lib/server-runtime/cookies.js +2 -2
- package/dist/production/lib/server-runtime/crypto.js +2 -2
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +2 -2
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +2 -2
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions.js +1 -1
- package/dist/production/lib/server-runtime/single-fetch.js +2 -2
- package/dist/production/lib/server-runtime/urls.js +1 -1
- package/dist/production/lib/server-runtime/warnings.js +1 -1
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +4 -4
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- 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.
|
|
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)
|
|
416
|
-
|
|
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)
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2986
|
+
} catch {}
|
|
2973
2987
|
};
|
|
2974
2988
|
reject = async (error) => {
|
|
2975
2989
|
rej(error);
|
|
2976
2990
|
try {
|
|
2977
2991
|
await promise;
|
|
2978
|
-
} catch
|
|
2992
|
+
} catch {}
|
|
2979
2993
|
};
|
|
2980
2994
|
});
|
|
2981
2995
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.3.
|
|
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
|
|
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)
|
|
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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
276
|
+
} catch {}
|
|
277
277
|
throw error;
|
|
278
278
|
}
|
|
279
279
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.3.
|
|
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
|
|
98
|
+
} catch {
|
|
99
99
|
return {};
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.3.
|
|
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
|
|
29
|
+
} catch {
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
32
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.3.
|
|
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
|
|
22
|
+
} catch {}
|
|
23
23
|
return null;
|
|
24
24
|
}
|
|
25
25
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.3.
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
83
|
+
} catch {
|
|
84
84
|
throw new SyntaxError();
|
|
85
85
|
}
|
|
86
86
|
const value = unflatten.call(this, jsonLine);
|
|
@@ -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
|