react-router 8.2.0 → 8.3.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.
- package/CHANGELOG.md +67 -0
- 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 +106 -17
- package/dist/development/index-react-server.js +168 -42
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/components.js +1 -1
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.d.ts +24 -24
- package/dist/development/lib/dom/dom.js +25 -25
- package/dist/development/lib/dom/lib.d.ts +2 -1
- package/dist/development/lib/dom/lib.js +5 -4
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +1 -1
- 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 +26 -21
- 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.d.ts +13 -0
- package/dist/development/lib/dom/ssr/routes-test-stub.js +14 -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 +1 -1
- 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 +1 -1
- package/dist/development/lib/href.d.ts +24 -8
- package/dist/development/lib/href.js +28 -11
- package/dist/development/lib/router/history.d.ts +6 -0
- package/dist/development/lib/router/history.js +7 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/router.js +1 -1
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +12 -0
- package/dist/development/lib/router/utils.js +57 -3
- package/dist/development/lib/rsc/browser.js +34 -24
- 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 +29 -10
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +5 -1
- package/dist/development/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/development/lib/rsc/server.ssr.js +27 -12
- package/dist/development/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/development/lib/server-runtime/cookies.js +17 -3
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- 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.d.ts +12 -0
- package/dist/development/lib/server-runtime/server.js +13 -1
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.d.ts +8 -0
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +9 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.d.ts +10 -4
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +12 -6
- package/dist/development/lib/server-runtime/sessions.d.ts +31 -2
- package/dist/development/lib/server-runtime/sessions.js +20 -3
- package/dist/development/lib/server-runtime/single-fetch.js +1 -1
- 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 +1 -1
- 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 +106 -17
- package/dist/production/index-react-server.js +168 -42
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/components.js +1 -1
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.d.ts +24 -24
- package/dist/production/lib/dom/dom.js +25 -25
- package/dist/production/lib/dom/lib.d.ts +2 -1
- package/dist/production/lib/dom/lib.js +5 -4
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +1 -1
- 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 +26 -21
- 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.d.ts +13 -0
- package/dist/production/lib/dom/ssr/routes-test-stub.js +14 -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 +1 -1
- 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 +1 -1
- package/dist/production/lib/href.d.ts +24 -8
- package/dist/production/lib/href.js +28 -11
- package/dist/production/lib/router/history.d.ts +6 -0
- package/dist/production/lib/router/history.js +7 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/router.js +1 -1
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +12 -0
- package/dist/production/lib/router/utils.js +57 -3
- package/dist/production/lib/rsc/browser.js +34 -24
- 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 +29 -10
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +5 -1
- package/dist/production/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/production/lib/rsc/server.ssr.js +27 -12
- package/dist/production/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/production/lib/server-runtime/cookies.js +17 -3
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- 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.d.ts +12 -0
- package/dist/production/lib/server-runtime/server.js +13 -1
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.d.ts +8 -0
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +9 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.d.ts +10 -4
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +12 -6
- package/dist/production/lib/server-runtime/sessions.d.ts +31 -2
- package/dist/production/lib/server-runtime/sessions.js +20 -3
- package/dist/production/lib/server-runtime/single-fetch.js +1 -1
- 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 +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/sessions-and-cookies.md +13 -13
- package/docs/explanation/state-management.md +2 -2
- package/docs/how-to/presets.md +2 -2
- package/docs/how-to/react-server-components.md +53 -1
- package/docs/how-to/security.md +8 -1
- package/docs/how-to/server-bundles.md +2 -2
- package/docs/start/data/route-object.md +2 -2
- package/docs/start/data/routing.md +1 -1
- package/docs/start/framework/pending-ui.md +1 -1
- package/docs/start/framework/route-module.md +8 -8
- package/docs/start/framework/routing.md +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -47,7 +47,10 @@ function createLocation(current, to, state = null, key, mask) {
|
|
|
47
47
|
/**
|
|
48
48
|
* Creates a string URL path from the given pathname, search, and hash components.
|
|
49
49
|
*
|
|
50
|
+
* @public
|
|
50
51
|
* @category Utils
|
|
52
|
+
* @param path The pathname, search, and hash components to combine.
|
|
53
|
+
* @returns The combined URL path.
|
|
51
54
|
*/
|
|
52
55
|
function createPath({ pathname = "/", search = "", hash = "" }) {
|
|
53
56
|
if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
|
|
@@ -57,7 +60,10 @@ function createPath({ pathname = "/", search = "", hash = "" }) {
|
|
|
57
60
|
/**
|
|
58
61
|
* Parses a string URL path into its separate pathname, search, and hash components.
|
|
59
62
|
*
|
|
63
|
+
* @public
|
|
60
64
|
* @category Utils
|
|
65
|
+
* @param path The URL path to parse.
|
|
66
|
+
* @returns The parsed pathname, search, and hash components.
|
|
61
67
|
*/
|
|
62
68
|
function parsePath(path) {
|
|
63
69
|
let parsedPath = {};
|
|
@@ -432,6 +438,48 @@ function matchRouteBranch(branch, pathname, allowPartial = false) {
|
|
|
432
438
|
return matches;
|
|
433
439
|
}
|
|
434
440
|
/**
|
|
441
|
+
* Characters that `encodeURIComponent` escapes but that are valid literally in
|
|
442
|
+
* a URL path segment. Per RFC 3986 §3.3, a path segment is made of `pchar`:
|
|
443
|
+
*
|
|
444
|
+
* ```
|
|
445
|
+
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
446
|
+
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
447
|
+
* ```
|
|
448
|
+
*
|
|
449
|
+
* `encodeURIComponent` targets query-string values, where `$ & + , ; = : @`
|
|
450
|
+
* are delimiters and must be escaped — but in a path segment they carry no
|
|
451
|
+
* special meaning, and browsers keep them literal in `location.pathname`.
|
|
452
|
+
* (`! ' ( ) *` and the unreserved set are already left alone by
|
|
453
|
+
* `encodeURIComponent`, so they need no restoring.)
|
|
454
|
+
*/
|
|
455
|
+
const PATH_PARAM_OVERESCAPED = {
|
|
456
|
+
"%24": "$",
|
|
457
|
+
"%26": "&",
|
|
458
|
+
"%2B": "+",
|
|
459
|
+
"%2C": ",",
|
|
460
|
+
"%3A": ":",
|
|
461
|
+
"%3B": ";",
|
|
462
|
+
"%3D": "=",
|
|
463
|
+
"%40": "@"
|
|
464
|
+
};
|
|
465
|
+
/**
|
|
466
|
+
* Encodes a param value for interpolation into a single URL path segment.
|
|
467
|
+
*
|
|
468
|
+
* Escapes characters that would break the path (`/ ? # %`, whitespace,
|
|
469
|
+
* non-ASCII, …) while leaving characters that RFC 3986 permits literally in a
|
|
470
|
+
* path segment untouched. Escaping those would needlessly rewrite URLs — e.g.
|
|
471
|
+
* a semver build param `1.0.0+1` would become `1.0.0%2B1` even though browsers
|
|
472
|
+
* display and match the `+` literally in `location.pathname`.
|
|
473
|
+
*
|
|
474
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3))
|
|
475
|
+
*
|
|
476
|
+
* @param value The param value to encode.
|
|
477
|
+
* @returns The encoded value, safe for use as a single path segment.
|
|
478
|
+
*/
|
|
479
|
+
function encodePathParam(value) {
|
|
480
|
+
return encodeURIComponent(value).replace(/%(?:24|26|2B|2C|3A|3B|3D|40)/g, (match) => PATH_PARAM_OVERESCAPED[match]);
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
435
483
|
* Performs pattern matching on a URL pathname and returns information about
|
|
436
484
|
* the match.
|
|
437
485
|
*
|
|
@@ -2323,6 +2371,8 @@ const Await = (async ({ children, resolve, errorElement }) => {
|
|
|
2323
2371
|
* encoding the {@link unstable_RSCPayload}.
|
|
2324
2372
|
* @param opts.loadServerAction Your `react-server-dom-xyz/server`'s
|
|
2325
2373
|
* `loadServerAction` function, used to load a server action by ID.
|
|
2374
|
+
* @param opts.clientVersion A version derived from the client build output used
|
|
2375
|
+
* to detect stale clients during lazy route discovery.
|
|
2326
2376
|
* @param opts.onError An optional error handler that will be called with any
|
|
2327
2377
|
* errors that occur during the request processing.
|
|
2328
2378
|
* @param opts.request The [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
|
|
@@ -2336,7 +2386,7 @@ const Await = (async ({ children, resolve, errorElement }) => {
|
|
|
2336
2386
|
* that contains the [RSC](https://react.dev/reference/rsc/server-components)
|
|
2337
2387
|
* data for hydration.
|
|
2338
2388
|
*/
|
|
2339
|
-
async function matchRSCServerRequest({ allowedActionOrigins, createTemporaryReferenceSet, basename, decodeReply, requestContext, routeDiscovery, loadServerAction, decodeAction, decodeFormState, onError, request, routes, generateResponse }) {
|
|
2389
|
+
async function matchRSCServerRequest({ allowedActionOrigins, createTemporaryReferenceSet, basename, decodeReply, requestContext, routeDiscovery, loadServerAction, decodeAction, decodeFormState, clientVersion, onError, request, routes, generateResponse }) {
|
|
2340
2390
|
let url = new URL(request.url);
|
|
2341
2391
|
basename = basename || "/";
|
|
2342
2392
|
let normalizedPath = url.pathname;
|
|
@@ -2354,22 +2404,26 @@ async function matchRSCServerRequest({ allowedActionOrigins, createTemporaryRefe
|
|
|
2354
2404
|
});
|
|
2355
2405
|
const temporaryReferences = createTemporaryReferenceSet();
|
|
2356
2406
|
const requestUrl = new URL(request.url);
|
|
2357
|
-
if (isManifestRequest(requestUrl)) return await generateManifestResponse(routes, basename, request, generateResponse, temporaryReferences, routeDiscovery);
|
|
2407
|
+
if (isManifestRequest(requestUrl)) return await generateManifestResponse(routes, basename, request, generateResponse, temporaryReferences, routeDiscovery, clientVersion);
|
|
2358
2408
|
let isDataRequest = isReactServerRequest(requestUrl);
|
|
2359
2409
|
let matches = matchRoutes(routes, url.pathname, basename);
|
|
2360
2410
|
if (matches) await Promise.all(matches.map((m) => explodeLazyRoute(m.route)));
|
|
2361
2411
|
const leafMatch = matches?.[matches.length - 1];
|
|
2362
2412
|
if (!isDataRequest && leafMatch && !leafMatch.route.Component && !leafMatch.route.ErrorBoundary) return generateResourceResponse(routerRequest, routes, basename, leafMatch.route.id, requestContext, onError);
|
|
2363
|
-
let response = await generateRenderResponse(routerRequest, routes, basename, isDataRequest, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, generateResponse, temporaryReferences, allowedActionOrigins, routeDiscovery);
|
|
2413
|
+
let response = await generateRenderResponse(routerRequest, routes, basename, isDataRequest, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, generateResponse, temporaryReferences, allowedActionOrigins, routeDiscovery, clientVersion);
|
|
2364
2414
|
response.headers.set("X-Remix-Response", "yes");
|
|
2365
2415
|
return response;
|
|
2366
2416
|
}
|
|
2367
|
-
async function generateManifestResponse(routes, basename, request, generateResponse, temporaryReferences, routeDiscovery) {
|
|
2417
|
+
async function generateManifestResponse(routes, basename, request, generateResponse, temporaryReferences, routeDiscovery, clientVersion) {
|
|
2368
2418
|
let url = new URL(request.url);
|
|
2369
2419
|
if (url.toString().length > 7680) return new Response(null, {
|
|
2370
2420
|
statusText: "Bad Request",
|
|
2371
2421
|
status: 400
|
|
2372
2422
|
});
|
|
2423
|
+
if (clientVersion !== void 0 && clientVersion !== url.searchParams.get("version")) return new Response(null, {
|
|
2424
|
+
status: 204,
|
|
2425
|
+
headers: { "X-Remix-Reload-Document": "true" }
|
|
2426
|
+
});
|
|
2373
2427
|
if (routeDiscovery?.mode === "initial") {
|
|
2374
2428
|
let payload = {
|
|
2375
2429
|
type: "manifest",
|
|
@@ -2518,7 +2572,7 @@ async function generateResourceResponse(request, routes, basename, routeId, requ
|
|
|
2518
2572
|
});
|
|
2519
2573
|
}
|
|
2520
2574
|
}
|
|
2521
|
-
async function generateRenderResponse(request, routes, basename, isDataRequest, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, generateResponse, temporaryReferences, allowedActionOrigins, routeDiscovery) {
|
|
2575
|
+
async function generateRenderResponse(request, routes, basename, isDataRequest, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, generateResponse, temporaryReferences, allowedActionOrigins, routeDiscovery, clientVersion) {
|
|
2522
2576
|
let statusCode = 200;
|
|
2523
2577
|
let url = new URL(request.url);
|
|
2524
2578
|
let isSubmission = isMutationMethod(request.method);
|
|
@@ -2539,29 +2593,39 @@ async function generateRenderResponse(request, routes, basename, isDataRequest,
|
|
|
2539
2593
|
let formState;
|
|
2540
2594
|
let skipRevalidation = false;
|
|
2541
2595
|
let potentialCSRFAttackError;
|
|
2542
|
-
if (isMutationMethod(request.method))
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2596
|
+
if (isMutationMethod(request.method)) {
|
|
2597
|
+
try {
|
|
2598
|
+
throwIfPotentialCSRFAttack(request, allowedActionOrigins);
|
|
2599
|
+
} catch (error) {
|
|
2600
|
+
onError?.(error);
|
|
2601
|
+
potentialCSRFAttackError = error;
|
|
2602
|
+
request = new Request(request.url, {
|
|
2603
|
+
method: "GET",
|
|
2604
|
+
headers: request.headers,
|
|
2605
|
+
signal: request.signal
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2608
|
+
if (!potentialCSRFAttackError) {
|
|
2609
|
+
ctx.runningAction = true;
|
|
2610
|
+
let result = await processServerAction(request, basename, decodeReply, loadServerAction, decodeAction, decodeFormState, onError, temporaryReferences).finally(() => {
|
|
2611
|
+
ctx.runningAction = false;
|
|
2612
|
+
});
|
|
2613
|
+
if (isResponse(result)) return generateRedirectResponse(result, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, ctx.redirect?.headers);
|
|
2614
|
+
skipRevalidation = result?.skipRevalidation ?? false;
|
|
2615
|
+
actionResult = result?.actionResult;
|
|
2616
|
+
formState = result?.formState;
|
|
2617
|
+
request = result?.revalidationRequest ?? request;
|
|
2618
|
+
if (ctx.redirect) return generateRedirectResponse(ctx.redirect, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, void 0);
|
|
2619
|
+
}
|
|
2556
2620
|
}
|
|
2557
|
-
let staticContext = await query(request, skipRevalidation
|
|
2621
|
+
let staticContext = await query(request, skipRevalidation ? { filterMatchesToLoad: () => false } : void 0);
|
|
2558
2622
|
if (isResponse(staticContext)) return generateRedirectResponse(staticContext, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, ctx.redirect?.headers);
|
|
2559
2623
|
if (potentialCSRFAttackError) {
|
|
2560
2624
|
staticContext.errors ??= {};
|
|
2561
2625
|
staticContext.errors[staticContext.matches[0].route.id] = potentialCSRFAttackError;
|
|
2562
2626
|
staticContext.statusCode = 400;
|
|
2563
2627
|
}
|
|
2564
|
-
return generateStaticContextResponse(routes, basename, generateResponse, statusCode, routeIdsToLoad, isDataRequest, isSubmission, actionResult, formState, staticContext, temporaryReferences, skipRevalidation, ctx.redirect?.headers, routeDiscovery);
|
|
2628
|
+
return generateStaticContextResponse(routes, basename, generateResponse, statusCode, routeIdsToLoad, isDataRequest, isSubmission, actionResult, formState, staticContext, temporaryReferences, skipRevalidation, ctx.redirect?.headers, routeDiscovery, clientVersion);
|
|
2565
2629
|
}
|
|
2566
2630
|
}));
|
|
2567
2631
|
if (isRedirectResponse(result)) return generateRedirectResponse(result, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, ctx.redirect?.headers);
|
|
@@ -2595,7 +2659,7 @@ function generateRedirectResponse(response, actionResult, basename, isDataReques
|
|
|
2595
2659
|
onError: defaultOnError
|
|
2596
2660
|
});
|
|
2597
2661
|
}
|
|
2598
|
-
async function generateStaticContextResponse(routes, basename, generateResponse, statusCode, routeIdsToLoad, isDataRequest, isSubmission, actionResult, formState, staticContext, temporaryReferences, skipRevalidation, sideEffectRedirectHeaders, routeDiscovery) {
|
|
2662
|
+
async function generateStaticContextResponse(routes, basename, generateResponse, statusCode, routeIdsToLoad, isDataRequest, isSubmission, actionResult, formState, staticContext, temporaryReferences, skipRevalidation, sideEffectRedirectHeaders, routeDiscovery, clientVersion) {
|
|
2599
2663
|
statusCode = staticContext.statusCode ?? statusCode;
|
|
2600
2664
|
if (staticContext.errors) staticContext.errors = Object.fromEntries(Object.entries(staticContext.errors).map(([key, error]) => [key, isRouteErrorResponse(error) ? Object.fromEntries(Object.entries(error)) : error]));
|
|
2601
2665
|
staticContext.matches.forEach((m) => {
|
|
@@ -2608,6 +2672,7 @@ async function generateStaticContextResponse(routes, basename, generateResponse,
|
|
|
2608
2672
|
const baseRenderPayload = {
|
|
2609
2673
|
type: "render",
|
|
2610
2674
|
basename: staticContext.basename,
|
|
2675
|
+
clientVersion,
|
|
2611
2676
|
routeDiscovery: routeDiscovery ?? { mode: "lazy" },
|
|
2612
2677
|
actionData: staticContext.actionData,
|
|
2613
2678
|
errors: staticContext.errors,
|
|
@@ -2803,14 +2868,30 @@ function stringify(p) {
|
|
|
2803
2868
|
return p == null ? "" : typeof p === "string" ? p : String(p);
|
|
2804
2869
|
}
|
|
2805
2870
|
/**
|
|
2806
|
-
Returns a resolved URL path for the specified route.
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2871
|
+
* Returns a resolved URL path for the specified route.
|
|
2872
|
+
*
|
|
2873
|
+
* Param values are percent-encoded for use in a path segment: characters that
|
|
2874
|
+
* would change the URL structure (`/`, `?`, `#`, `%`, whitespace, non-ASCII)
|
|
2875
|
+
* are escaped, while characters that RFC 3986 allows literally in a path
|
|
2876
|
+
* segment (`$ & + , ; = : @`) are kept as-is. Note this differs from query-string
|
|
2877
|
+
* encoding (`encodeURIComponent`/`URLSearchParams`), where those characters are
|
|
2878
|
+
* delimiters and must be escaped. Splat (`*`) values are encoded per segment,
|
|
2879
|
+
* preserving `/` separators.
|
|
2880
|
+
*
|
|
2881
|
+
* See [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
|
|
2882
|
+
*
|
|
2883
|
+
* @example
|
|
2884
|
+
* const h = href("/:lang?/about", { lang: "en" })
|
|
2885
|
+
* // -> `/en/about`
|
|
2886
|
+
*
|
|
2887
|
+
* <Link to={href("/products/:id", { id: "abc123" })} />
|
|
2888
|
+
*
|
|
2889
|
+
* @public
|
|
2890
|
+
* @category Utils
|
|
2891
|
+
* @mode framework
|
|
2892
|
+
* @param path The route path to resolve
|
|
2893
|
+
* @param args The route params to use when resolving the path
|
|
2894
|
+
* @returns The resolved URL path
|
|
2814
2895
|
*/
|
|
2815
2896
|
function href(path, ...args) {
|
|
2816
2897
|
let params = args[0];
|
|
@@ -2818,11 +2899,11 @@ function href(path, ...args) {
|
|
|
2818
2899
|
const isRequired = questionMark === void 0;
|
|
2819
2900
|
const value = params?.[param];
|
|
2820
2901
|
if (isRequired && value === void 0) throw new Error(`Path '${path}' requires param '${param}' but it was not provided`);
|
|
2821
|
-
return value == null ? "" : "/" +
|
|
2902
|
+
return value == null ? "" : "/" + encodePathParam(stringify(value));
|
|
2822
2903
|
});
|
|
2823
2904
|
if (path.endsWith("*")) {
|
|
2824
2905
|
const value = params?.["*"];
|
|
2825
|
-
if (value !== void 0) result += "/" + stringify(value).split("/").map(
|
|
2906
|
+
if (value !== void 0) result += "/" + stringify(value).split("/").map(encodePathParam).join("/");
|
|
2826
2907
|
}
|
|
2827
2908
|
return result || "/";
|
|
2828
2909
|
}
|
|
@@ -2875,6 +2956,14 @@ function byteStringToUint8Array(byteString) {
|
|
|
2875
2956
|
//#region lib/server-runtime/cookies.ts
|
|
2876
2957
|
/**
|
|
2877
2958
|
* Creates a logical container for managing a browser cookie from the server.
|
|
2959
|
+
*
|
|
2960
|
+
* @public
|
|
2961
|
+
* @category Utils
|
|
2962
|
+
* @mode framework
|
|
2963
|
+
* @mode data
|
|
2964
|
+
* @param name The name of the cookie.
|
|
2965
|
+
* @param cookieOptions Options for parsing and serializing the cookie.
|
|
2966
|
+
* @returns A {@link Cookie} object for parsing and serializing the cookie.
|
|
2878
2967
|
*/
|
|
2879
2968
|
const createCookie = (name, cookieOptions = {}) => {
|
|
2880
2969
|
let { secrets = [], ...options } = {
|
|
@@ -2914,9 +3003,15 @@ const createCookie = (name, cookieOptions = {}) => {
|
|
|
2914
3003
|
};
|
|
2915
3004
|
};
|
|
2916
3005
|
/**
|
|
2917
|
-
* Returns true if
|
|
3006
|
+
* Returns `true` if a value is a React Router {@link Cookie} object.
|
|
2918
3007
|
*
|
|
2919
|
-
* @
|
|
3008
|
+
* @public
|
|
3009
|
+
* @category Utils
|
|
3010
|
+
* @mode framework
|
|
3011
|
+
* @mode data
|
|
3012
|
+
* @param object The value to check.
|
|
3013
|
+
* @returns `true` if the value is a React Router {@link Cookie} object;
|
|
3014
|
+
* otherwise, `false`.
|
|
2920
3015
|
*/
|
|
2921
3016
|
const isCookie = (object) => {
|
|
2922
3017
|
return object != null && typeof object.name === "string" && typeof object.isSigned === "boolean" && typeof object.parse === "function" && typeof object.serialize === "function";
|
|
@@ -3006,6 +3101,12 @@ function flash(name) {
|
|
|
3006
3101
|
*
|
|
3007
3102
|
* Note: This function is typically not invoked directly by application code.
|
|
3008
3103
|
* Instead, use a `SessionStorage` object's `getSession` method.
|
|
3104
|
+
*
|
|
3105
|
+
* @category Utils
|
|
3106
|
+
* @param initialData The initial data for the session.
|
|
3107
|
+
* @param id The identifier for the session. Defaults to an empty string for a
|
|
3108
|
+
* new session.
|
|
3109
|
+
* @returns A new {@link Session} object.
|
|
3009
3110
|
*/
|
|
3010
3111
|
const createSession = (initialData = {}, id = "") => {
|
|
3011
3112
|
let map = new Map(Object.entries(initialData));
|
|
@@ -3040,9 +3141,15 @@ const createSession = (initialData = {}, id = "") => {
|
|
|
3040
3141
|
};
|
|
3041
3142
|
};
|
|
3042
3143
|
/**
|
|
3043
|
-
* Returns true if
|
|
3144
|
+
* Returns `true` if a value is a React Router {@link Session} object.
|
|
3044
3145
|
*
|
|
3045
|
-
* @
|
|
3146
|
+
* @public
|
|
3147
|
+
* @category Utils
|
|
3148
|
+
* @mode framework
|
|
3149
|
+
* @mode data
|
|
3150
|
+
* @param object The value to check.
|
|
3151
|
+
* @returns `true` if the value is a React Router {@link Session} object;
|
|
3152
|
+
* otherwise, `false`.
|
|
3046
3153
|
*/
|
|
3047
3154
|
const isSession = (object) => {
|
|
3048
3155
|
return object != null && typeof object.id === "string" && typeof object.data !== "undefined" && typeof object.has === "function" && typeof object.get === "function" && typeof object.set === "function" && typeof object.flash === "function" && typeof object.unset === "function";
|
|
@@ -3052,6 +3159,11 @@ const isSession = (object) => {
|
|
|
3052
3159
|
*
|
|
3053
3160
|
* Note: This is a low-level API that should only be used if none of the
|
|
3054
3161
|
* existing session storage options meet your requirements.
|
|
3162
|
+
*
|
|
3163
|
+
* @category Utils
|
|
3164
|
+
* @param strategy The strategy used to store session identifiers and data.
|
|
3165
|
+
* @returns A {@link SessionStorage} object that persists session data using the
|
|
3166
|
+
* provided strategy.
|
|
3055
3167
|
*/
|
|
3056
3168
|
function createSessionStorage({ cookie: cookieArg, createData, readData, updateData, deleteData }) {
|
|
3057
3169
|
let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
|
|
@@ -3091,6 +3203,14 @@ function warnOnceAboutSigningSessionCookie(cookie) {
|
|
|
3091
3203
|
* needed, and can help to simplify some load-balanced scenarios. However, it
|
|
3092
3204
|
* also has the limitation that serialized session data may not exceed the
|
|
3093
3205
|
* browser's maximum cookie size. Trade-offs!
|
|
3206
|
+
*
|
|
3207
|
+
* @public
|
|
3208
|
+
* @category Utils
|
|
3209
|
+
* @mode framework
|
|
3210
|
+
* @mode data
|
|
3211
|
+
* @param options Options for creating the cookie-backed session storage.
|
|
3212
|
+
* @returns A {@link SessionStorage} object that stores all session data in its
|
|
3213
|
+
* cookie.
|
|
3094
3214
|
*/
|
|
3095
3215
|
function createCookieSessionStorage({ cookie: cookieArg } = {}) {
|
|
3096
3216
|
let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
|
|
@@ -3116,18 +3236,24 @@ function createCookieSessionStorage({ cookie: cookieArg } = {}) {
|
|
|
3116
3236
|
//#endregion
|
|
3117
3237
|
//#region lib/server-runtime/sessions/memoryStorage.ts
|
|
3118
3238
|
/**
|
|
3119
|
-
* Creates and returns a simple in-memory SessionStorage object
|
|
3120
|
-
* for testing and as a reference implementation.
|
|
3239
|
+
* Creates and returns a simple in-memory SessionStorage object.
|
|
3121
3240
|
*
|
|
3122
|
-
*
|
|
3123
|
-
*
|
|
3241
|
+
* Intended for local development and testing. It does not scale beyond a single
|
|
3242
|
+
* process, and all session data is lost when the server process stops/restarts.
|
|
3243
|
+
*
|
|
3244
|
+
* @public
|
|
3245
|
+
* @category Utils
|
|
3246
|
+
* @mode framework
|
|
3247
|
+
* @mode data
|
|
3248
|
+
* @param options Options for creating the in-memory session storage.
|
|
3249
|
+
* @returns A {@link SessionStorage} object that stores session data in memory.
|
|
3124
3250
|
*/
|
|
3125
3251
|
function createMemorySessionStorage({ cookie } = {}) {
|
|
3126
3252
|
let map = /* @__PURE__ */ new Map();
|
|
3127
3253
|
return createSessionStorage({
|
|
3128
3254
|
cookie,
|
|
3129
3255
|
async createData(data, expires) {
|
|
3130
|
-
let id =
|
|
3256
|
+
let id = crypto.randomUUID();
|
|
3131
3257
|
map.set(id, {
|
|
3132
3258
|
data,
|
|
3133
3259
|
expires
|
package/dist/production/index.js
CHANGED
|
@@ -6,30 +6,30 @@ import { RelativeRoutingType } from "../router/router.js";
|
|
|
6
6
|
type ParamKeyValuePair = [string, string];
|
|
7
7
|
type URLSearchParamsInit = string | ParamKeyValuePair[] | Record<string, string | string[]> | URLSearchParams;
|
|
8
8
|
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
9
|
+
* Creates a URLSearchParams object using the given initializer.
|
|
10
|
+
*
|
|
11
|
+
* This is identical to `new URLSearchParams(init)` except it also supports
|
|
12
|
+
* arrays as values in the object form of the initializer instead of just
|
|
13
|
+
* strings. This is convenient when you need multiple values for a given key,
|
|
14
|
+
* but don't want to use an array initializer.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Instead of:
|
|
18
|
+
* let searchParams = new URLSearchParams([
|
|
19
|
+
* ["sort", "name"],
|
|
20
|
+
* ["sort", "price"],
|
|
21
|
+
* ]);
|
|
22
|
+
*
|
|
23
|
+
* // You can do:
|
|
24
|
+
* let searchParams = createSearchParams({
|
|
25
|
+
* sort: ["name", "price"],
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
* @category Utils
|
|
30
|
+
* @param init The value used to initialize the URL search parameters.
|
|
31
|
+
* @returns A URLSearchParams object containing the initialized search
|
|
32
|
+
* parameters.
|
|
33
33
|
*/
|
|
34
34
|
declare function createSearchParams(init?: URLSearchParamsInit): URLSearchParams;
|
|
35
35
|
type JsonObject = { [Key in string]: JsonValue } & { [Key in string]?: JsonValue | undefined };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -30,30 +30,30 @@ function shouldProcessLinkClick(event, target) {
|
|
|
30
30
|
return event.button === 0 && (!target || target === "_self") && !isModifiedEvent(event);
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
Creates a URLSearchParams object using the given initializer.
|
|
34
|
-
|
|
35
|
-
This is identical to `new URLSearchParams(init)` except it also
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
33
|
+
* Creates a URLSearchParams object using the given initializer.
|
|
34
|
+
*
|
|
35
|
+
* This is identical to `new URLSearchParams(init)` except it also supports
|
|
36
|
+
* arrays as values in the object form of the initializer instead of just
|
|
37
|
+
* strings. This is convenient when you need multiple values for a given key,
|
|
38
|
+
* but don't want to use an array initializer.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Instead of:
|
|
42
|
+
* let searchParams = new URLSearchParams([
|
|
43
|
+
* ["sort", "name"],
|
|
44
|
+
* ["sort", "price"],
|
|
45
|
+
* ]);
|
|
46
|
+
*
|
|
47
|
+
* // You can do:
|
|
48
|
+
* let searchParams = createSearchParams({
|
|
49
|
+
* sort: ["name", "price"],
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* @public
|
|
53
|
+
* @category Utils
|
|
54
|
+
* @param init The value used to initialize the URL search parameters.
|
|
55
|
+
* @returns A URLSearchParams object containing the initialized search
|
|
56
|
+
* parameters.
|
|
57
57
|
*/
|
|
58
58
|
function createSearchParams(init = "") {
|
|
59
59
|
return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
|
|
@@ -1409,7 +1409,8 @@ declare namespace ScrollRestoration {
|
|
|
1409
1409
|
* for this navigation. To apply specific styles during the transition, see
|
|
1410
1410
|
* {@link useViewTransitionState}. Defaults to `false`.
|
|
1411
1411
|
* @param options.defaultShouldRevalidate Specify the default revalidation
|
|
1412
|
-
* behavior for the navigation.
|
|
1412
|
+
* behavior for the navigation. When not specified, loaders revalidate
|
|
1413
|
+
* according to the router's standard revalidation behavior.
|
|
1413
1414
|
* @param options.mask Masked location to display in the browser instead
|
|
1414
1415
|
* of the router location. Defaults to `undefined`.
|
|
1415
1416
|
* @param options.useTransitions Wraps the navigation in
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -22,7 +22,7 @@ import * as React$1 from "react";
|
|
|
22
22
|
//#region lib/dom/lib.tsx
|
|
23
23
|
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
24
24
|
try {
|
|
25
|
-
if (isBrowser) window.__reactRouterVersion = "8.
|
|
25
|
+
if (isBrowser) window.__reactRouterVersion = "8.3.0";
|
|
26
26
|
} catch (e) {}
|
|
27
27
|
/**
|
|
28
28
|
* Create a new {@link DataRouter| data router} that manages the application
|
|
@@ -386,7 +386,7 @@ const NavLink = React$1.forwardRef(function NavLinkWithRef({ "aria-current": ari
|
|
|
386
386
|
if (nextLocationPathname && basename) nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
|
|
387
387
|
const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
|
|
388
388
|
let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
|
|
389
|
-
let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(
|
|
389
|
+
let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(endSlashPosition) === "/");
|
|
390
390
|
let renderProps = {
|
|
391
391
|
isActive,
|
|
392
392
|
isPending,
|
|
@@ -609,7 +609,8 @@ function useDataRouterState(hookName) {
|
|
|
609
609
|
* for this navigation. To apply specific styles during the transition, see
|
|
610
610
|
* {@link useViewTransitionState}. Defaults to `false`.
|
|
611
611
|
* @param options.defaultShouldRevalidate Specify the default revalidation
|
|
612
|
-
* behavior for the navigation.
|
|
612
|
+
* behavior for the navigation. When not specified, loaders revalidate
|
|
613
|
+
* according to the router's standard revalidation behavior.
|
|
613
614
|
* @param options.mask Masked location to display in the browser instead
|
|
614
615
|
* of the router location. Defaults to `undefined`.
|
|
615
616
|
* @param options.useTransitions Wraps the navigation in
|