react-router 8.3.0 → 8.4.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 +46 -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 +50 -48
- package/dist/development/index-react-server.js +96 -43
- package/dist/development/index.d.ts +2 -2
- package/dist/development/index.js +3 -3
- package/dist/development/lib/actions.js +10 -5
- package/dist/development/lib/components.js +50 -10
- package/dist/development/lib/context.d.ts +14 -5
- package/dist/development/lib/context.js +11 -3
- package/dist/development/lib/dom/dom.js +2 -2
- package/dist/development/lib/dom/lib.js +33 -36
- package/dist/development/lib/dom/server.d.ts +6 -1
- package/dist/development/lib/dom/server.js +40 -14
- package/dist/development/lib/dom/ssr/components.js +16 -24
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/entry.d.ts +4 -0
- 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 +34 -12
- package/dist/development/lib/dom/ssr/hydration.d.ts +3 -1
- package/dist/development/lib/dom/ssr/hydration.js +6 -4
- 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 +5 -2
- 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 +2 -2
- package/dist/development/lib/dom/ssr/single-fetch.js +13 -22
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +2 -1
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.js +54 -46
- 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/matcher-route-pattern.d.ts +2 -0
- package/dist/development/lib/router/matcher-route-pattern.js +216 -0
- package/dist/development/lib/router/matcher-route-pattern.preload.d.ts +20 -0
- package/dist/development/lib/router/matcher-route-pattern.preload.js +36 -0
- package/dist/development/lib/router/matcher.d.ts +2 -0
- package/dist/development/lib/router/matcher.js +29 -0
- package/dist/development/lib/router/navigation.js +45 -0
- package/dist/development/lib/router/router.d.ts +21 -7
- package/dist/development/lib/router/router.js +111 -82
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +6 -1
- package/dist/development/lib/router/utils.js +15 -9
- package/dist/development/lib/rsc/browser.js +5 -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 +3 -5
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +7 -0
- package/dist/development/lib/rsc/server.ssr.js +26 -22
- 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 +3 -4
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +8 -7
- 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/route-pattern.d.ts +3 -0
- package/dist/development/route-pattern.js +12 -0
- 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 +50 -48
- package/dist/production/index-react-server.js +96 -43
- package/dist/production/index.d.ts +2 -2
- package/dist/production/index.js +3 -3
- package/dist/production/lib/actions.js +10 -5
- package/dist/production/lib/components.js +50 -10
- package/dist/production/lib/context.d.ts +14 -5
- package/dist/production/lib/context.js +11 -3
- package/dist/production/lib/dom/dom.js +2 -2
- package/dist/production/lib/dom/lib.js +33 -36
- package/dist/production/lib/dom/server.d.ts +6 -1
- package/dist/production/lib/dom/server.js +40 -14
- package/dist/production/lib/dom/ssr/components.js +16 -24
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/entry.d.ts +4 -0
- 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 +34 -12
- package/dist/production/lib/dom/ssr/hydration.d.ts +3 -1
- package/dist/production/lib/dom/ssr/hydration.js +6 -4
- 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 +5 -2
- 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 +2 -2
- package/dist/production/lib/dom/ssr/single-fetch.js +13 -22
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +2 -1
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.js +54 -46
- 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/matcher-route-pattern.d.ts +2 -0
- package/dist/production/lib/router/matcher-route-pattern.js +216 -0
- package/dist/production/lib/router/matcher-route-pattern.preload.d.ts +20 -0
- package/dist/production/lib/router/matcher-route-pattern.preload.js +36 -0
- package/dist/production/lib/router/matcher.d.ts +2 -0
- package/dist/production/lib/router/matcher.js +29 -0
- package/dist/production/lib/router/navigation.js +45 -0
- package/dist/production/lib/router/router.d.ts +21 -7
- package/dist/production/lib/router/router.js +111 -82
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +6 -1
- package/dist/production/lib/router/utils.js +15 -9
- package/dist/production/lib/rsc/browser.js +5 -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 +3 -5
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +7 -0
- package/dist/production/lib/rsc/server.ssr.js +26 -22
- 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 +3 -4
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +8 -7
- 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/route-pattern.d.ts +3 -0
- package/dist/production/route-pattern.js +12 -0
- 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/docs/how-to/fetchers.md +6 -1
- package/docs/how-to/middleware.md +3 -1
- package/docs/how-to/optimize-revalidation.md +178 -5
- package/docs/how-to/react-server-components.md +26 -3
- package/docs/how-to/resource-routes.md +3 -0
- package/docs/start/data/actions.md +2 -1
- package/docs/start/data/route-object.md +21 -6
- package/docs/start/framework/actions.md +4 -2
- package/docs/start/framework/route-module.md +32 -5
- package/docs/upgrading/future.md +68 -0
- package/package.json +11 -1
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-router v8.4.0
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
import { invariant, parsePath, warning } from "./history.js";
|
|
12
|
+
import { decodePath, explodeOptionalSegments, joinPaths, matchPath, normalizePathname, stripBasename } from "./utils.js";
|
|
13
|
+
import { createMultiMatcher } from "@remix-run/route-pattern/match";
|
|
14
|
+
import { descending } from "@remix-run/route-pattern/specificity";
|
|
15
|
+
//#region lib/router/matcher-route-pattern.ts
|
|
16
|
+
var RoutePatternDataRouteMatcher = class {
|
|
17
|
+
#state;
|
|
18
|
+
#basename;
|
|
19
|
+
constructor(basename) {
|
|
20
|
+
this.#basename = basename;
|
|
21
|
+
}
|
|
22
|
+
update(routes) {
|
|
23
|
+
let branches = flattenRoutes(routes);
|
|
24
|
+
let matcher = createMultiMatcher({ ignoreCase: true });
|
|
25
|
+
let partialMatcher = createMultiMatcher({ ignoreCase: true });
|
|
26
|
+
for (let branch of branches) {
|
|
27
|
+
let routePattern = convertReactRouterPathToRoutePattern(branch.path);
|
|
28
|
+
validateRoutePatternSplat(branch.path, routePattern);
|
|
29
|
+
routePattern = addOptionalTrailingSlash(routePattern);
|
|
30
|
+
matcher.add(routePattern, branch);
|
|
31
|
+
if (!branch.routesMeta[branch.routesMeta.length - 1].route.index) partialMatcher.add(routePattern === "/" ? `/*__rr_partial` : `${routePattern}(/*__rr_partial)`, branch);
|
|
32
|
+
}
|
|
33
|
+
this.#state = {
|
|
34
|
+
branches,
|
|
35
|
+
matcher,
|
|
36
|
+
partialMatcher
|
|
37
|
+
};
|
|
38
|
+
return branches;
|
|
39
|
+
}
|
|
40
|
+
match(locationArg, allowPartial = false) {
|
|
41
|
+
let pathname = stripBasename((typeof locationArg === "string" ? parsePath(locationArg) : locationArg).pathname || "/", this.#basename);
|
|
42
|
+
if (pathname == null) return null;
|
|
43
|
+
let decoded = decodePath(pathname);
|
|
44
|
+
let url = new URL("http://reactrouter.local");
|
|
45
|
+
url.pathname = pathname.endsWith("/") ? pathname : `${pathname}/`;
|
|
46
|
+
invariant(this.#state, "Route pattern routes must be initialized before matching.");
|
|
47
|
+
let matches = this.#state.matcher.matchAll(url);
|
|
48
|
+
if (allowPartial) matches.push(...this.#state.partialMatcher.matchAll(url));
|
|
49
|
+
for (let match of prioritizeValidatedMatches(matches)) {
|
|
50
|
+
let routeMatches = convertRoutePatternMatchToRouteMatches(match, decoded, allowPartial);
|
|
51
|
+
if (routeMatches && validateRouteMatchParams(routeMatches)) return routeMatches;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
function validateRoutePatternSplat(routePath, routePattern) {
|
|
57
|
+
invariant(getRoutePatternSplatIndexes(routePattern).length <= 1 && isTerminalRoutePatternSplat(routePattern), `Route path "${routePath}" is not supported with \`future.unstable_routePatternMatching\` because React Router only supports a single splat at the end of a route path.`);
|
|
58
|
+
}
|
|
59
|
+
function getRoutePatternSplatIndexes(routePattern) {
|
|
60
|
+
let splatIndexes = [];
|
|
61
|
+
for (let i = 0; i < routePattern.length; i++) {
|
|
62
|
+
let char = routePattern[i];
|
|
63
|
+
if (char === "\\") {
|
|
64
|
+
i++;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (char === "*") splatIndexes.push(i);
|
|
68
|
+
}
|
|
69
|
+
return splatIndexes;
|
|
70
|
+
}
|
|
71
|
+
function isTerminalRoutePatternSplat(routePattern) {
|
|
72
|
+
for (let i = 0; i < routePattern.length; i++) {
|
|
73
|
+
let char = routePattern[i];
|
|
74
|
+
if (char === "\\") {
|
|
75
|
+
i++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (char !== "*") continue;
|
|
79
|
+
let suffix = routePattern.slice(i + 1);
|
|
80
|
+
return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(suffix) || suffix === "";
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function addOptionalTrailingSlash(routePattern) {
|
|
85
|
+
return routePattern === "/" ? routePattern : `${routePattern.replace(/\/+$/, "")}(/)`;
|
|
86
|
+
}
|
|
87
|
+
function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "") {
|
|
88
|
+
routes.forEach((route, index) => {
|
|
89
|
+
invariant(route.caseSensitive !== true, "`caseSensitive` routes are not supported with `future.unstable_routePatternMatching`.");
|
|
90
|
+
let meta = {
|
|
91
|
+
relativePath: route.path || "",
|
|
92
|
+
caseSensitive: false,
|
|
93
|
+
childrenIndex: index,
|
|
94
|
+
route
|
|
95
|
+
};
|
|
96
|
+
let absolutePath;
|
|
97
|
+
if (meta.relativePath.startsWith("/")) {
|
|
98
|
+
absolutePath = meta.relativePath;
|
|
99
|
+
let parentPathMatch = explodeOptionalSegments(parentPath).find((path) => meta.relativePath.startsWith(path));
|
|
100
|
+
invariant(parentPathMatch != null, `Absolute route path "${meta.relativePath}" nested under path "${parentPath}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`);
|
|
101
|
+
meta.relativePath = meta.relativePath.slice(parentPathMatch.length);
|
|
102
|
+
}
|
|
103
|
+
let routesMeta = parentsMeta.concat(meta);
|
|
104
|
+
let path = absolutePath ?? (meta.relativePath ? joinPaths([parentPath, meta.relativePath]) : parentPath);
|
|
105
|
+
if (route.children && route.children.length > 0) {
|
|
106
|
+
invariant(route.index !== true, `Index routes must not have child routes. Please remove all child routes from route path "${path}".`);
|
|
107
|
+
flattenRoutes(route.children, branches, routesMeta, path);
|
|
108
|
+
if (route.children?.some((child) => child.index)) return;
|
|
109
|
+
}
|
|
110
|
+
if (route.path != null || route.index) branches.push({
|
|
111
|
+
path,
|
|
112
|
+
score: 0,
|
|
113
|
+
routesMeta
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
return branches;
|
|
117
|
+
}
|
|
118
|
+
function convertReactRouterPathToRoutePattern(path) {
|
|
119
|
+
warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`);
|
|
120
|
+
if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) path = path.replace(/\*$/, "/*");
|
|
121
|
+
path = path.replace(/^\/*/, "/");
|
|
122
|
+
if (path === "") return "/";
|
|
123
|
+
let segments = path.split("/");
|
|
124
|
+
let pattern = segments.shift() || "";
|
|
125
|
+
for (let i = 0; i < segments.length;) {
|
|
126
|
+
let optionalRun = [];
|
|
127
|
+
while (i < segments.length && isOptionalRouteSegment(segments[i])) {
|
|
128
|
+
optionalRun.push(convertRouteSegment(segments[i].slice(0, -1)));
|
|
129
|
+
i++;
|
|
130
|
+
}
|
|
131
|
+
if (optionalRun.length > 0) {
|
|
132
|
+
let nested = optionalRun.reduceRight((child, segment) => `/${segment}${child ? `(${child})` : ""}`, "");
|
|
133
|
+
pattern += `(${nested})`;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
pattern += `/${convertRouteSegment(segments[i])}`;
|
|
137
|
+
i++;
|
|
138
|
+
}
|
|
139
|
+
return pattern || "/";
|
|
140
|
+
}
|
|
141
|
+
function isOptionalRouteSegment(segment) {
|
|
142
|
+
return segment.endsWith("?");
|
|
143
|
+
}
|
|
144
|
+
function convertRouteSegment(segment) {
|
|
145
|
+
if (segment === "*") return "*__rr_splat";
|
|
146
|
+
let paramMatch = segment.match(/^:([\w-]+)(\?)?(.*)$/);
|
|
147
|
+
if (paramMatch) {
|
|
148
|
+
let [, paramName, optional, suffix] = paramMatch;
|
|
149
|
+
let converted = `:${paramName}${escapeRoutePatternLiteral(suffix)}`;
|
|
150
|
+
return optional ? `(:${paramName})${escapeRoutePatternLiteral(suffix)}` : converted;
|
|
151
|
+
}
|
|
152
|
+
return escapeRoutePatternLiteral(segment);
|
|
153
|
+
}
|
|
154
|
+
function escapeRoutePatternLiteral(value) {
|
|
155
|
+
return value.replace(/[\\():*]/g, "\\$&");
|
|
156
|
+
}
|
|
157
|
+
function validateRouteMatchParams(matches) {
|
|
158
|
+
return matches.every(({ route, params }) => route.unstable_validateParams == null || Object.keys(route.unstable_validateParams).length === 0 || Object.entries(route.unstable_validateParams).every(([param, re]) => params[param] != null ? new RegExp(re.source, re.flags).test(params[param]) : true));
|
|
159
|
+
}
|
|
160
|
+
function prioritizeValidatedMatches(matches) {
|
|
161
|
+
return matches.sort((a, b) => {
|
|
162
|
+
let specificity = descending(a, b);
|
|
163
|
+
if (specificity !== 0) return specificity;
|
|
164
|
+
return Number(hasParamValidators(b)) - Number(hasParamValidators(a));
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function hasParamValidators(match) {
|
|
168
|
+
return match.data.routesMeta.some((meta) => meta.route.unstable_validateParams != null && Object.keys(meta.route.unstable_validateParams).length > 0);
|
|
169
|
+
}
|
|
170
|
+
function convertRoutePatternMatchToRouteMatches(match, pathname, allowPartial) {
|
|
171
|
+
let result = matchRoutePatternBranch(match.data, pathname, allowPartial, 0, "/", {});
|
|
172
|
+
if (result == null) return null;
|
|
173
|
+
for (let routeMatch of result.matches) routeMatch.params = result.params;
|
|
174
|
+
return result.matches;
|
|
175
|
+
}
|
|
176
|
+
function matchRoutePatternBranch(branch, pathname, allowPartial, metaIndex, matchedPathname, matchedParams) {
|
|
177
|
+
let meta = branch.routesMeta[metaIndex];
|
|
178
|
+
let end = metaIndex === branch.routesMeta.length - 1;
|
|
179
|
+
let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
|
|
180
|
+
for (let relativePath of explodeOptionalSegments(meta.relativePath)) {
|
|
181
|
+
let pattern = {
|
|
182
|
+
path: relativePath,
|
|
183
|
+
caseSensitive: false,
|
|
184
|
+
end
|
|
185
|
+
};
|
|
186
|
+
let pathMatch = matchPath(pattern, remainingPathname);
|
|
187
|
+
if (!pathMatch && end && allowPartial && !meta.route.index) pathMatch = matchPath({
|
|
188
|
+
...pattern,
|
|
189
|
+
end: false
|
|
190
|
+
}, remainingPathname);
|
|
191
|
+
if (!pathMatch) continue;
|
|
192
|
+
let params = {
|
|
193
|
+
...matchedParams,
|
|
194
|
+
...pathMatch.params
|
|
195
|
+
};
|
|
196
|
+
let routeMatch = {
|
|
197
|
+
params,
|
|
198
|
+
pathname: joinPaths([matchedPathname, pathMatch.pathname]),
|
|
199
|
+
pathnameBase: normalizePathname(joinPaths([matchedPathname, pathMatch.pathnameBase])),
|
|
200
|
+
route: meta.route
|
|
201
|
+
};
|
|
202
|
+
let nextMatchedPathname = pathMatch.pathnameBase === "/" ? matchedPathname : joinPaths([matchedPathname, pathMatch.pathnameBase]);
|
|
203
|
+
if (end) return {
|
|
204
|
+
matches: [routeMatch],
|
|
205
|
+
params
|
|
206
|
+
};
|
|
207
|
+
let childResult = matchRoutePatternBranch(branch, pathname, allowPartial, metaIndex + 1, nextMatchedPathname, params);
|
|
208
|
+
if (childResult) return {
|
|
209
|
+
matches: [routeMatch, ...childResult.matches],
|
|
210
|
+
params: childResult.params
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
//#endregion
|
|
216
|
+
export { RoutePatternDataRouteMatcher };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
//#region lib/router/matcher-route-pattern.preload.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Initialize the route-pattern matcher before creating a Data Router or static
|
|
5
|
+
* handler with `future.unstable_routePatternMatching` enabled. Import from
|
|
6
|
+
* `react-router/route-pattern` and call this once during application startup.
|
|
7
|
+
* Server and browser applications must each preload their own matcher.
|
|
8
|
+
*
|
|
9
|
+
* The matcher is statically imported by this module. Tree-shaking bundlers can
|
|
10
|
+
* remove it from applications that do not use this function. Initialization is
|
|
11
|
+
* synchronous, and repeated calls are safe.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
* @category Data Routers
|
|
15
|
+
* @mode data
|
|
16
|
+
* @returns {void}
|
|
17
|
+
*/
|
|
18
|
+
declare function unstable_preloadRoutePattern(): void;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { unstable_preloadRoutePattern };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-router v8.4.0
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
import { RoutePatternDataRouteMatcher } from "./matcher-route-pattern.js";
|
|
12
|
+
//#region lib/router/matcher-route-pattern.preload.ts
|
|
13
|
+
let RoutePatternMatcher;
|
|
14
|
+
function getRoutePatternMatcher() {
|
|
15
|
+
return RoutePatternMatcher;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the route-pattern matcher before creating a Data Router or static
|
|
19
|
+
* handler with `future.unstable_routePatternMatching` enabled. Import from
|
|
20
|
+
* `react-router/route-pattern` and call this once during application startup.
|
|
21
|
+
* Server and browser applications must each preload their own matcher.
|
|
22
|
+
*
|
|
23
|
+
* The matcher is statically imported by this module. Tree-shaking bundlers can
|
|
24
|
+
* remove it from applications that do not use this function. Initialization is
|
|
25
|
+
* synchronous, and repeated calls are safe.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
* @category Data Routers
|
|
29
|
+
* @mode data
|
|
30
|
+
* @returns {void}
|
|
31
|
+
*/
|
|
32
|
+
function unstable_preloadRoutePattern() {
|
|
33
|
+
RoutePatternMatcher = RoutePatternDataRouteMatcher;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { getRoutePatternMatcher, unstable_preloadRoutePattern };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-router v8.4.0
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
import { flattenAndRankRoutes, matchRoutesImpl } from "./utils.js";
|
|
12
|
+
//#region lib/router/matcher.ts
|
|
13
|
+
var V6RegExMatcher = class {
|
|
14
|
+
#routes = [];
|
|
15
|
+
#branches = [];
|
|
16
|
+
#basename;
|
|
17
|
+
constructor(basename) {
|
|
18
|
+
this.#basename = basename;
|
|
19
|
+
}
|
|
20
|
+
update(routes) {
|
|
21
|
+
this.#routes = routes;
|
|
22
|
+
this.#branches = flattenAndRankRoutes(routes);
|
|
23
|
+
}
|
|
24
|
+
match(locationArg, allowPartial = false) {
|
|
25
|
+
return matchRoutesImpl(this.#routes, locationArg, this.#basename, allowPartial, this.#branches);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { V6RegExMatcher };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-router v8.4.0
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
//#region lib/router/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 };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import { Action, History, Location, Path, To } from "./history.js";
|
|
3
|
-
import { DataRouteMatch, DataRouteObject, DataStrategyFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, MaybePromise, PatchRoutesOnNavigationFunction,
|
|
3
|
+
import { DataRouteMatch, DataRouteObject, DataStrategyFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, MaybePromise, PatchRoutesOnNavigationFunction, RouteData, RouteManifest, RouteObject, RouterContextProvider, Submission, UIMatch } from "./utils.js";
|
|
4
4
|
import { ClientInstrumentation, ServerInstrumentation } from "./instrumentation.js";
|
|
5
5
|
|
|
6
6
|
//#region lib/router/router.d.ts
|
|
@@ -40,9 +40,10 @@ interface Router {
|
|
|
40
40
|
* @private
|
|
41
41
|
* PRIVATE - DO NOT USE
|
|
42
42
|
*
|
|
43
|
-
*
|
|
43
|
+
* Match routes against a location using the router's configured route
|
|
44
|
+
* matching implementation.
|
|
44
45
|
*/
|
|
45
|
-
|
|
46
|
+
match(locationArg: Partial<Location> | string): DataRouteMatch[] | null;
|
|
46
47
|
/**
|
|
47
48
|
* @private
|
|
48
49
|
* PRIVATE - DO NOT USE
|
|
@@ -128,6 +129,14 @@ interface Router {
|
|
|
128
129
|
* @param location
|
|
129
130
|
*/
|
|
130
131
|
createHref(location: Location | URL): string;
|
|
132
|
+
/**
|
|
133
|
+
* @private
|
|
134
|
+
* PRIVATE - DO NOT USE
|
|
135
|
+
*
|
|
136
|
+
* Utility function to create a URL for the given location
|
|
137
|
+
* @param location
|
|
138
|
+
*/
|
|
139
|
+
createURL?(to: To): URL;
|
|
131
140
|
/**
|
|
132
141
|
* @private
|
|
133
142
|
* PRIVATE - DO NOT USE
|
|
@@ -296,7 +305,10 @@ type HydrationState = Partial<Pick<RouterState, "loaderData" | "actionData" | "e
|
|
|
296
305
|
/**
|
|
297
306
|
* Future flags to toggle new feature behavior
|
|
298
307
|
*/
|
|
299
|
-
interface FutureConfig {
|
|
308
|
+
interface FutureConfig {
|
|
309
|
+
/** Enables route-pattern matching after calling `unstable_preloadRoutePattern()`. */
|
|
310
|
+
unstable_routePatternMatching?: boolean;
|
|
311
|
+
}
|
|
300
312
|
/**
|
|
301
313
|
* Initialization options for createRouter
|
|
302
314
|
*/
|
|
@@ -328,6 +340,8 @@ interface StaticHandlerContext {
|
|
|
328
340
|
loaderHeaders: Record<string, Headers>;
|
|
329
341
|
actionHeaders: Record<string, Headers>;
|
|
330
342
|
_deepestRenderedBoundaryId?: string | null;
|
|
343
|
+
/** @private */
|
|
344
|
+
_match: StaticHandler["match"];
|
|
331
345
|
}
|
|
332
346
|
/**
|
|
333
347
|
* A StaticHandler instance manages a singular SSR navigation/fetch event
|
|
@@ -341,10 +355,10 @@ interface StaticHandler {
|
|
|
341
355
|
* @private
|
|
342
356
|
* PRIVATE - DO NOT USE
|
|
343
357
|
*
|
|
344
|
-
*
|
|
345
|
-
* matching
|
|
358
|
+
* Match routes against a location using the handler's configured route
|
|
359
|
+
* matching implementation.
|
|
346
360
|
*/
|
|
347
|
-
|
|
361
|
+
match(locationArg: Partial<Location> | string): DataRouteMatch[] | null;
|
|
348
362
|
/**
|
|
349
363
|
* Perform a query for a given request - executing all matched route
|
|
350
364
|
* loaders/actions. Used for document requests.
|