UNPKG

111 kBJavaScriptView Raw
1import { AsyncLocalStorage } from 'node:async_hooks';
2import * as React2 from 'react';
3import { splitCookiesString } from 'set-cookie-parser';
4import { UNSAFE_AwaitContextProvider, UNSAFE_WithComponentProps, Outlet as Outlet$1, UNSAFE_WithErrorBoundaryProps, UNSAFE_WithHydrateFallbackProps } from 'react-router/internal/react-server-client';
5export { BrowserRouter, Form, HashRouter, Link, Links, MemoryRouter, Meta, NavLink, Navigate, Outlet, Route, Router, RouterProvider, Routes, ScrollRestoration, StaticRouter, StaticRouterProvider, unstable_HistoryRouter } from 'react-router/internal/react-server-client';
6import { serialize, parse } from 'cookie';
7
8/**
9 * react-router v7.10.0
10 *
11 * Copyright (c) Remix Software Inc.
12 *
13 * This source code is licensed under the MIT license found in the
14 * LICENSE.md file in the root directory of this source tree.
15 *
16 * @license MIT
17 */
18var __typeError = (msg) => {
19 throw TypeError(msg);
20};
21var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
22var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
23var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
24
25// lib/router/history.ts
26function invariant(value, message) {
27 if (value === false || value === null || typeof value === "undefined") {
28 throw new Error(message);
29 }
30}
31function warning(cond, message) {
32 if (!cond) {
33 if (typeof console !== "undefined") console.warn(message);
34 try {
35 throw new Error(message);
36 } catch (e) {
37 }
38 }
39}
40function createKey() {
41 return Math.random().toString(36).substring(2, 10);
42}
43function createLocation(current, to, state = null, key) {
44 let location = {
45 pathname: typeof current === "string" ? current : current.pathname,
46 search: "",
47 hash: "",
48 ...typeof to === "string" ? parsePath(to) : to,
49 state,
50 // TODO: This could be cleaned up. push/replace should probably just take
51 // full Locations now and avoid the need to run through this flow at all
52 // But that's a pretty big refactor to the current test suite so going to
53 // keep as is for the time being and just let any incoming keys take precedence
54 key: to && to.key || key || createKey()
55 };
56 return location;
57}
58function createPath({
59 pathname = "/",
60 search = "",
61 hash = ""
62}) {
63 if (search && search !== "?")
64 pathname += search.charAt(0) === "?" ? search : "?" + search;
65 if (hash && hash !== "#")
66 pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
67 return pathname;
68}
69function parsePath(path) {
70 let parsedPath = {};
71 if (path) {
72 let hashIndex = path.indexOf("#");
73 if (hashIndex >= 0) {
74 parsedPath.hash = path.substring(hashIndex);
75 path = path.substring(0, hashIndex);
76 }
77 let searchIndex = path.indexOf("?");
78 if (searchIndex >= 0) {
79 parsedPath.search = path.substring(searchIndex);
80 path = path.substring(0, searchIndex);
81 }
82 if (path) {
83 parsedPath.pathname = path;
84 }
85 }
86 return parsedPath;
87}
88
89// lib/router/instrumentation.ts
90var UninstrumentedSymbol = Symbol("Uninstrumented");
91function getRouteInstrumentationUpdates(fns, route) {
92 let aggregated = {
93 lazy: [],
94 "lazy.loader": [],
95 "lazy.action": [],
96 "lazy.middleware": [],
97 middleware: [],
98 loader: [],
99 action: []
100 };
101 fns.forEach(
102 (fn) => fn({
103 id: route.id,
104 index: route.index,
105 path: route.path,
106 instrument(i) {
107 let keys = Object.keys(aggregated);
108 for (let key of keys) {
109 if (i[key]) {
110 aggregated[key].push(i[key]);
111 }
112 }
113 }
114 })
115 );
116 let updates = {};
117 if (typeof route.lazy === "function" && aggregated.lazy.length > 0) {
118 let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0);
119 if (instrumented) {
120 updates.lazy = instrumented;
121 }
122 }
123 if (typeof route.lazy === "object") {
124 let lazyObject = route.lazy;
125 ["middleware", "loader", "action"].forEach((key) => {
126 let lazyFn = lazyObject[key];
127 let instrumentations = aggregated[`lazy.${key}`];
128 if (typeof lazyFn === "function" && instrumentations.length > 0) {
129 let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);
130 if (instrumented) {
131 updates.lazy = Object.assign(updates.lazy || {}, {
132 [key]: instrumented
133 });
134 }
135 }
136 });
137 }
138 ["loader", "action"].forEach((key) => {
139 let handler = route[key];
140 if (typeof handler === "function" && aggregated[key].length > 0) {
141 let original = handler[UninstrumentedSymbol] ?? handler;
142 let instrumented = wrapImpl(
143 aggregated[key],
144 original,
145 (...args) => getHandlerInfo(args[0])
146 );
147 if (instrumented) {
148 instrumented[UninstrumentedSymbol] = original;
149 updates[key] = instrumented;
150 }
151 }
152 });
153 if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) {
154 updates.middleware = route.middleware.map((middleware) => {
155 let original = middleware[UninstrumentedSymbol] ?? middleware;
156 let instrumented = wrapImpl(
157 aggregated.middleware,
158 original,
159 (...args) => getHandlerInfo(args[0])
160 );
161 if (instrumented) {
162 instrumented[UninstrumentedSymbol] = original;
163 return instrumented;
164 }
165 return middleware;
166 });
167 }
168 return updates;
169}
170function wrapImpl(impls, handler, getInfo) {
171 if (impls.length === 0) {
172 return null;
173 }
174 return async (...args) => {
175 let result = await recurseRight(
176 impls,
177 getInfo(...args),
178 () => handler(...args),
179 impls.length - 1
180 );
181 if (result.type === "error") {
182 throw result.value;
183 }
184 return result.value;
185 };
186}
187async function recurseRight(impls, info, handler, index) {
188 let impl = impls[index];
189 let result;
190 if (!impl) {
191 try {
192 let value = await handler();
193 result = { type: "success", value };
194 } catch (e) {
195 result = { type: "error", value: e };
196 }
197 } else {
198 let handlerPromise = void 0;
199 let callHandler = async () => {
200 if (handlerPromise) {
201 console.error("You cannot call instrumented handlers more than once");
202 } else {
203 handlerPromise = recurseRight(impls, info, handler, index - 1);
204 }
205 result = await handlerPromise;
206 invariant(result, "Expected a result");
207 if (result.type === "error" && result.value instanceof Error) {
208 return { status: "error", error: result.value };
209 }
210 return { status: "success", error: void 0 };
211 };
212 try {
213 await impl(callHandler, info);
214 } catch (e) {
215 console.error("An instrumentation function threw an error:", e);
216 }
217 if (!handlerPromise) {
218 await callHandler();
219 }
220 await handlerPromise;
221 }
222 if (result) {
223 return result;
224 }
225 return {
226 type: "error",
227 value: new Error("No result assigned in instrumentation chain.")
228 };
229}
230function getHandlerInfo(args) {
231 let { request, context, params, unstable_pattern } = args;
232 return {
233 request: getReadonlyRequest(request),
234 params: { ...params },
235 unstable_pattern,
236 context: getReadonlyContext(context)
237 };
238}
239function getReadonlyRequest(request) {
240 return {
241 method: request.method,
242 url: request.url,
243 headers: {
244 get: (...args) => request.headers.get(...args)
245 }
246 };
247}
248function getReadonlyContext(context) {
249 if (isPlainObject(context)) {
250 let frozen = { ...context };
251 Object.freeze(frozen);
252 return frozen;
253 } else {
254 return {
255 get: (ctx) => context.get(ctx)
256 };
257 }
258}
259var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
260function isPlainObject(thing) {
261 if (thing === null || typeof thing !== "object") {
262 return false;
263 }
264 const proto = Object.getPrototypeOf(thing);
265 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
266}
267
268// lib/router/utils.ts
269function createContext(defaultValue) {
270 return { defaultValue };
271}
272var _map;
273var RouterContextProvider = class {
274 /**
275 * Create a new `RouterContextProvider` instance
276 * @param init An optional initial context map to populate the provider with
277 */
278 constructor(init) {
279 __privateAdd(this, _map, /* @__PURE__ */ new Map());
280 if (init) {
281 for (let [context, value] of init) {
282 this.set(context, value);
283 }
284 }
285 }
286 /**
287 * Access a value from the context. If no value has been set for the context,
288 * it will return the context's `defaultValue` if provided, or throw an error
289 * if no `defaultValue` was set.
290 * @param context The context to get the value for
291 * @returns The value for the context, or the context's `defaultValue` if no
292 * value was set
293 */
294 get(context) {
295 if (__privateGet(this, _map).has(context)) {
296 return __privateGet(this, _map).get(context);
297 }
298 if (context.defaultValue !== void 0) {
299 return context.defaultValue;
300 }
301 throw new Error("No value found for context");
302 }
303 /**
304 * Set a value for the context. If the context already has a value set, this
305 * will overwrite it.
306 *
307 * @param context The context to set the value for
308 * @param value The value to set for the context
309 * @returns {void}
310 */
311 set(context, value) {
312 __privateGet(this, _map).set(context, value);
313 }
314};
315_map = new WeakMap();
316var unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([
317 "lazy",
318 "caseSensitive",
319 "path",
320 "id",
321 "index",
322 "children"
323]);
324function isUnsupportedLazyRouteObjectKey(key) {
325 return unsupportedLazyRouteObjectKeys.has(
326 key
327 );
328}
329var unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([
330 "lazy",
331 "caseSensitive",
332 "path",
333 "id",
334 "index",
335 "middleware",
336 "children"
337]);
338function isUnsupportedLazyRouteFunctionKey(key) {
339 return unsupportedLazyRouteFunctionKeys.has(
340 key
341 );
342}
343function isIndexRoute(route) {
344 return route.index === true;
345}
346function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath = [], manifest = {}, allowInPlaceMutations = false) {
347 return routes.map((route, index) => {
348 let treePath = [...parentPath, String(index)];
349 let id = typeof route.id === "string" ? route.id : treePath.join("-");
350 invariant(
351 route.index !== true || !route.children,
352 `Cannot specify children on an index route`
353 );
354 invariant(
355 allowInPlaceMutations || !manifest[id],
356 `Found a route id collision on id "${id}". Route id's must be globally unique within Data Router usages`
357 );
358 if (isIndexRoute(route)) {
359 let indexRoute = {
360 ...route,
361 id
362 };
363 manifest[id] = mergeRouteUpdates(
364 indexRoute,
365 mapRouteProperties(indexRoute)
366 );
367 return indexRoute;
368 } else {
369 let pathOrLayoutRoute = {
370 ...route,
371 id,
372 children: void 0
373 };
374 manifest[id] = mergeRouteUpdates(
375 pathOrLayoutRoute,
376 mapRouteProperties(pathOrLayoutRoute)
377 );
378 if (route.children) {
379 pathOrLayoutRoute.children = convertRoutesToDataRoutes(
380 route.children,
381 mapRouteProperties,
382 treePath,
383 manifest,
384 allowInPlaceMutations
385 );
386 }
387 return pathOrLayoutRoute;
388 }
389 });
390}
391function mergeRouteUpdates(route, updates) {
392 return Object.assign(route, {
393 ...updates,
394 ...typeof updates.lazy === "object" && updates.lazy != null ? {
395 lazy: {
396 ...route.lazy,
397 ...updates.lazy
398 }
399 } : {}
400 });
401}
402function matchRoutes(routes, locationArg, basename = "/") {
403 return matchRoutesImpl(routes, locationArg, basename, false);
404}
405function matchRoutesImpl(routes, locationArg, basename, allowPartial) {
406 let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
407 let pathname = stripBasename(location.pathname || "/", basename);
408 if (pathname == null) {
409 return null;
410 }
411 let branches = flattenRoutes(routes);
412 rankRouteBranches(branches);
413 let matches = null;
414 for (let i = 0; matches == null && i < branches.length; ++i) {
415 let decoded = decodePath(pathname);
416 matches = matchRouteBranch(
417 branches[i],
418 decoded,
419 allowPartial
420 );
421 }
422 return matches;
423}
424function convertRouteMatchToUiMatch(match, loaderData) {
425 let { route, pathname, params } = match;
426 return {
427 id: route.id,
428 pathname,
429 params,
430 data: loaderData[route.id],
431 loaderData: loaderData[route.id],
432 handle: route.handle
433 };
434}
435function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) {
436 let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => {
437 let meta = {
438 relativePath: relativePath === void 0 ? route.path || "" : relativePath,
439 caseSensitive: route.caseSensitive === true,
440 childrenIndex: index,
441 route
442 };
443 if (meta.relativePath.startsWith("/")) {
444 if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {
445 return;
446 }
447 invariant(
448 meta.relativePath.startsWith(parentPath),
449 `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.`
450 );
451 meta.relativePath = meta.relativePath.slice(parentPath.length);
452 }
453 let path = joinPaths([parentPath, meta.relativePath]);
454 let routesMeta = parentsMeta.concat(meta);
455 if (route.children && route.children.length > 0) {
456 invariant(
457 // Our types know better, but runtime JS may not!
458 // @ts-expect-error
459 route.index !== true,
460 `Index routes must not have child routes. Please remove all child routes from route path "${path}".`
461 );
462 flattenRoutes(
463 route.children,
464 branches,
465 routesMeta,
466 path,
467 hasParentOptionalSegments
468 );
469 }
470 if (route.path == null && !route.index) {
471 return;
472 }
473 branches.push({
474 path,
475 score: computeScore(path, route.index),
476 routesMeta
477 });
478 };
479 routes.forEach((route, index) => {
480 if (route.path === "" || !route.path?.includes("?")) {
481 flattenRoute(route, index);
482 } else {
483 for (let exploded of explodeOptionalSegments(route.path)) {
484 flattenRoute(route, index, true, exploded);
485 }
486 }
487 });
488 return branches;
489}
490function explodeOptionalSegments(path) {
491 let segments = path.split("/");
492 if (segments.length === 0) return [];
493 let [first, ...rest] = segments;
494 let isOptional = first.endsWith("?");
495 let required = first.replace(/\?$/, "");
496 if (rest.length === 0) {
497 return isOptional ? [required, ""] : [required];
498 }
499 let restExploded = explodeOptionalSegments(rest.join("/"));
500 let result = [];
501 result.push(
502 ...restExploded.map(
503 (subpath) => subpath === "" ? required : [required, subpath].join("/")
504 )
505 );
506 if (isOptional) {
507 result.push(...restExploded);
508 }
509 return result.map(
510 (exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded
511 );
512}
513function rankRouteBranches(branches) {
514 branches.sort(
515 (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(
516 a.routesMeta.map((meta) => meta.childrenIndex),
517 b.routesMeta.map((meta) => meta.childrenIndex)
518 )
519 );
520}
521var paramRe = /^:[\w-]+$/;
522var dynamicSegmentValue = 3;
523var indexRouteValue = 2;
524var emptySegmentValue = 1;
525var staticSegmentValue = 10;
526var splatPenalty = -2;
527var isSplat = (s) => s === "*";
528function computeScore(path, index) {
529 let segments = path.split("/");
530 let initialScore = segments.length;
531 if (segments.some(isSplat)) {
532 initialScore += splatPenalty;
533 }
534 if (index) {
535 initialScore += indexRouteValue;
536 }
537 return segments.filter((s) => !isSplat(s)).reduce(
538 (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue),
539 initialScore
540 );
541}
542function compareIndexes(a, b) {
543 let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
544 return siblings ? (
545 // If two routes are siblings, we should try to match the earlier sibling
546 // first. This allows people to have fine-grained control over the matching
547 // behavior by simply putting routes with identical paths in the order they
548 // want them tried.
549 a[a.length - 1] - b[b.length - 1]
550 ) : (
551 // Otherwise, it doesn't really make sense to rank non-siblings by index,
552 // so they sort equally.
553 0
554 );
555}
556function matchRouteBranch(branch, pathname, allowPartial = false) {
557 let { routesMeta } = branch;
558 let matchedParams = {};
559 let matchedPathname = "/";
560 let matches = [];
561 for (let i = 0; i < routesMeta.length; ++i) {
562 let meta = routesMeta[i];
563 let end = i === routesMeta.length - 1;
564 let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
565 let match = matchPath(
566 { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },
567 remainingPathname
568 );
569 let route = meta.route;
570 if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {
571 match = matchPath(
572 {
573 path: meta.relativePath,
574 caseSensitive: meta.caseSensitive,
575 end: false
576 },
577 remainingPathname
578 );
579 }
580 if (!match) {
581 return null;
582 }
583 Object.assign(matchedParams, match.params);
584 matches.push({
585 // TODO: Can this as be avoided?
586 params: matchedParams,
587 pathname: joinPaths([matchedPathname, match.pathname]),
588 pathnameBase: normalizePathname(
589 joinPaths([matchedPathname, match.pathnameBase])
590 ),
591 route
592 });
593 if (match.pathnameBase !== "/") {
594 matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
595 }
596 }
597 return matches;
598}
599function matchPath(pattern, pathname) {
600 if (typeof pattern === "string") {
601 pattern = { path: pattern, caseSensitive: false, end: true };
602 }
603 let [matcher, compiledParams] = compilePath(
604 pattern.path,
605 pattern.caseSensitive,
606 pattern.end
607 );
608 let match = pathname.match(matcher);
609 if (!match) return null;
610 let matchedPathname = match[0];
611 let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
612 let captureGroups = match.slice(1);
613 let params = compiledParams.reduce(
614 (memo, { paramName, isOptional }, index) => {
615 if (paramName === "*") {
616 let splatValue = captureGroups[index] || "";
617 pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
618 }
619 const value = captureGroups[index];
620 if (isOptional && !value) {
621 memo[paramName] = void 0;
622 } else {
623 memo[paramName] = (value || "").replace(/%2F/g, "/");
624 }
625 return memo;
626 },
627 {}
628 );
629 return {
630 params,
631 pathname: matchedPathname,
632 pathnameBase,
633 pattern
634 };
635}
636function compilePath(path, caseSensitive = false, end = true) {
637 warning(
638 path === "*" || !path.endsWith("*") || path.endsWith("/*"),
639 `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(/\*$/, "/*")}".`
640 );
641 let params = [];
642 let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(
643 /\/:([\w-]+)(\?)?/g,
644 (_, paramName, isOptional) => {
645 params.push({ paramName, isOptional: isOptional != null });
646 return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
647 }
648 ).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2");
649 if (path.endsWith("*")) {
650 params.push({ paramName: "*" });
651 regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
652 } else if (end) {
653 regexpSource += "\\/*$";
654 } else if (path !== "" && path !== "/") {
655 regexpSource += "(?:(?=\\/|$))";
656 } else ;
657 let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
658 return [matcher, params];
659}
660function decodePath(value) {
661 try {
662 return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
663 } catch (error) {
664 warning(
665 false,
666 `The URL path "${value}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).`
667 );
668 return value;
669 }
670}
671function stripBasename(pathname, basename) {
672 if (basename === "/") return pathname;
673 if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
674 return null;
675 }
676 let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
677 let nextChar = pathname.charAt(startIndex);
678 if (nextChar && nextChar !== "/") {
679 return null;
680 }
681 return pathname.slice(startIndex) || "/";
682}
683function prependBasename({
684 basename,
685 pathname
686}) {
687 return pathname === "/" ? basename : joinPaths([basename, pathname]);
688}
689var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
690var isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);
691function resolvePath(to, fromPathname = "/") {
692 let {
693 pathname: toPathname,
694 search = "",
695 hash = ""
696 } = typeof to === "string" ? parsePath(to) : to;
697 let pathname;
698 if (toPathname) {
699 if (isAbsoluteUrl(toPathname)) {
700 pathname = toPathname;
701 } else {
702 if (toPathname.includes("//")) {
703 let oldPathname = toPathname;
704 toPathname = toPathname.replace(/\/\/+/g, "/");
705 warning(
706 false,
707 `Pathnames cannot have embedded double slashes - normalizing ${oldPathname} -> ${toPathname}`
708 );
709 }
710 if (toPathname.startsWith("/")) {
711 pathname = resolvePathname(toPathname.substring(1), "/");
712 } else {
713 pathname = resolvePathname(toPathname, fromPathname);
714 }
715 }
716 } else {
717 pathname = fromPathname;
718 }
719 return {
720 pathname,
721 search: normalizeSearch(search),
722 hash: normalizeHash(hash)
723 };
724}
725function resolvePathname(relativePath, fromPathname) {
726 let segments = fromPathname.replace(/\/+$/, "").split("/");
727 let relativeSegments = relativePath.split("/");
728 relativeSegments.forEach((segment) => {
729 if (segment === "..") {
730 if (segments.length > 1) segments.pop();
731 } else if (segment !== ".") {
732 segments.push(segment);
733 }
734 });
735 return segments.length > 1 ? segments.join("/") : "/";
736}
737function getInvalidPathError(char, field, dest, path) {
738 return `Cannot include a '${char}' character in a manually specified \`to.${field}\` field [${JSON.stringify(
739 path
740 )}]. Please separate it out to the \`to.${dest}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`;
741}
742function getPathContributingMatches(matches) {
743 return matches.filter(
744 (match, index) => index === 0 || match.route.path && match.route.path.length > 0
745 );
746}
747function getResolveToMatches(matches) {
748 let pathMatches = getPathContributingMatches(matches);
749 return pathMatches.map(
750 (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase
751 );
752}
753function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {
754 let to;
755 if (typeof toArg === "string") {
756 to = parsePath(toArg);
757 } else {
758 to = { ...toArg };
759 invariant(
760 !to.pathname || !to.pathname.includes("?"),
761 getInvalidPathError("?", "pathname", "search", to)
762 );
763 invariant(
764 !to.pathname || !to.pathname.includes("#"),
765 getInvalidPathError("#", "pathname", "hash", to)
766 );
767 invariant(
768 !to.search || !to.search.includes("#"),
769 getInvalidPathError("#", "search", "hash", to)
770 );
771 }
772 let isEmptyPath = toArg === "" || to.pathname === "";
773 let toPathname = isEmptyPath ? "/" : to.pathname;
774 let from;
775 if (toPathname == null) {
776 from = locationPathname;
777 } else {
778 let routePathnameIndex = routePathnames.length - 1;
779 if (!isPathRelative && toPathname.startsWith("..")) {
780 let toSegments = toPathname.split("/");
781 while (toSegments[0] === "..") {
782 toSegments.shift();
783 routePathnameIndex -= 1;
784 }
785 to.pathname = toSegments.join("/");
786 }
787 from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
788 }
789 let path = resolvePath(to, from);
790 let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
791 let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/");
792 if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {
793 path.pathname += "/";
794 }
795 return path;
796}
797var joinPaths = (paths) => paths.join("/").replace(/\/\/+/g, "/");
798var normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
799var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
800var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
801var DataWithResponseInit = class {
802 constructor(data2, init) {
803 this.type = "DataWithResponseInit";
804 this.data = data2;
805 this.init = init || null;
806 }
807};
808function data(data2, init) {
809 return new DataWithResponseInit(
810 data2,
811 typeof init === "number" ? { status: init } : init
812 );
813}
814var redirect = (url, init = 302) => {
815 let responseInit = init;
816 if (typeof responseInit === "number") {
817 responseInit = { status: responseInit };
818 } else if (typeof responseInit.status === "undefined") {
819 responseInit.status = 302;
820 }
821 let headers = new Headers(responseInit.headers);
822 headers.set("Location", url);
823 return new Response(null, { ...responseInit, headers });
824};
825var redirectDocument = (url, init) => {
826 let response = redirect(url, init);
827 response.headers.set("X-Remix-Reload-Document", "true");
828 return response;
829};
830var replace = (url, init) => {
831 let response = redirect(url, init);
832 response.headers.set("X-Remix-Replace", "true");
833 return response;
834};
835var ErrorResponseImpl = class {
836 constructor(status, statusText, data2, internal = false) {
837 this.status = status;
838 this.statusText = statusText || "";
839 this.internal = internal;
840 if (data2 instanceof Error) {
841 this.data = data2.toString();
842 this.error = data2;
843 } else {
844 this.data = data2;
845 }
846 }
847};
848function isRouteErrorResponse(error) {
849 return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
850}
851function getRoutePattern(matches) {
852 return matches.map((m) => m.route.path).filter(Boolean).join("/").replace(/\/\/*/g, "/") || "/";
853}
854
855// lib/router/router.ts
856var validMutationMethodsArr = [
857 "POST",
858 "PUT",
859 "PATCH",
860 "DELETE"
861];
862var validMutationMethods = new Set(
863 validMutationMethodsArr
864);
865var validRequestMethodsArr = [
866 "GET",
867 ...validMutationMethodsArr
868];
869var validRequestMethods = new Set(validRequestMethodsArr);
870var redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
871var defaultMapRouteProperties = (route) => ({
872 hasErrorBoundary: Boolean(route.hasErrorBoundary)
873});
874var ResetLoaderDataSymbol = Symbol("ResetLoaderData");
875function createStaticHandler(routes, opts) {
876 invariant(
877 routes.length > 0,
878 "You must provide a non-empty routes array to createStaticHandler"
879 );
880 let manifest = {};
881 let basename = (opts ? opts.basename : null) || "/";
882 let _mapRouteProperties = opts?.mapRouteProperties || defaultMapRouteProperties;
883 let mapRouteProperties = _mapRouteProperties;
884 if (opts?.unstable_instrumentations) {
885 let instrumentations = opts.unstable_instrumentations;
886 mapRouteProperties = (route) => {
887 return {
888 ..._mapRouteProperties(route),
889 ...getRouteInstrumentationUpdates(
890 instrumentations.map((i) => i.route).filter(Boolean),
891 route
892 )
893 };
894 };
895 }
896 let dataRoutes = convertRoutesToDataRoutes(
897 routes,
898 mapRouteProperties,
899 void 0,
900 manifest
901 );
902 async function query(request, {
903 requestContext,
904 filterMatchesToLoad,
905 skipLoaderErrorBubbling,
906 skipRevalidation,
907 dataStrategy,
908 generateMiddlewareResponse
909 } = {}) {
910 let url = new URL(request.url);
911 let method = request.method;
912 let location = createLocation("", createPath(url), null, "default");
913 let matches = matchRoutes(dataRoutes, location, basename);
914 requestContext = requestContext != null ? requestContext : new RouterContextProvider();
915 if (!isValidMethod(method) && method !== "HEAD") {
916 let error = getInternalRouterError(405, { method });
917 let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);
918 let staticContext = {
919 basename,
920 location,
921 matches: methodNotAllowedMatches,
922 loaderData: {},
923 actionData: null,
924 errors: {
925 [route.id]: error
926 },
927 statusCode: error.status,
928 loaderHeaders: {},
929 actionHeaders: {}
930 };
931 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;
932 } else if (!matches) {
933 let error = getInternalRouterError(404, { pathname: location.pathname });
934 let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);
935 let staticContext = {
936 basename,
937 location,
938 matches: notFoundMatches,
939 loaderData: {},
940 actionData: null,
941 errors: {
942 [route.id]: error
943 },
944 statusCode: error.status,
945 loaderHeaders: {},
946 actionHeaders: {}
947 };
948 return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;
949 }
950 if (generateMiddlewareResponse) {
951 invariant(
952 requestContext instanceof RouterContextProvider,
953 "When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`"
954 );
955 try {
956 await loadLazyMiddlewareForMatches(
957 matches,
958 manifest,
959 mapRouteProperties
960 );
961 let renderedStaticContext;
962 let response = await runServerMiddlewarePipeline(
963 {
964 request,
965 unstable_pattern: getRoutePattern(matches),
966 matches,
967 params: matches[0].params,
968 // If we're calling middleware then it must be enabled so we can cast
969 // this to the proper type knowing it's not an `AppLoadContext`
970 context: requestContext
971 },
972 async () => {
973 let res = await generateMiddlewareResponse(
974 async (revalidationRequest, opts2 = {}) => {
975 let result2 = await queryImpl(
976 revalidationRequest,
977 location,
978 matches,
979 requestContext,
980 dataStrategy || null,
981 skipLoaderErrorBubbling === true,
982 null,
983 "filterMatchesToLoad" in opts2 ? opts2.filterMatchesToLoad ?? null : filterMatchesToLoad ?? null,
984 skipRevalidation === true
985 );
986 if (isResponse(result2)) {
987 return result2;
988 }
989 renderedStaticContext = { location, basename, ...result2 };
990 return renderedStaticContext;
991 }
992 );
993 return res;
994 },
995 async (error, routeId) => {
996 if (isRedirectResponse(error)) {
997 return error;
998 }
999 if (isResponse(error)) {
1000 try {
1001 error = new ErrorResponseImpl(
1002 error.status,
1003 error.statusText,
1004 await parseResponseBody(error)
1005 );
1006 } catch (e) {
1007 error = e;
1008 }
1009 }
1010 if (isDataWithResponseInit(error)) {
1011 error = dataWithResponseInitToErrorResponse(error);
1012 }
1013 if (renderedStaticContext) {
1014 if (routeId in renderedStaticContext.loaderData) {
1015 renderedStaticContext.loaderData[routeId] = void 0;
1016 }
1017 let staticContext = getStaticContextFromError(
1018 dataRoutes,
1019 renderedStaticContext,
1020 error,
1021 skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id
1022 );
1023 return generateMiddlewareResponse(
1024 () => Promise.resolve(staticContext)
1025 );
1026 } else {
1027 let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary(
1028 matches,
1029 matches.find(
1030 (m) => m.route.id === routeId || m.route.loader
1031 )?.route.id || routeId
1032 ).route.id;
1033 let staticContext = {
1034 matches,
1035 location,
1036 basename,
1037 loaderData: {},
1038 actionData: null,
1039 errors: {
1040 [boundaryRouteId]: error
1041 },
1042 statusCode: isRouteErrorResponse(error) ? error.status : 500,
1043 actionHeaders: {},
1044 loaderHeaders: {}
1045 };
1046 return generateMiddlewareResponse(
1047 () => Promise.resolve(staticContext)
1048 );
1049 }
1050 }
1051 );
1052 invariant(isResponse(response), "Expected a response in query()");
1053 return response;
1054 } catch (e) {
1055 if (isResponse(e)) {
1056 return e;
1057 }
1058 throw e;
1059 }
1060 }
1061 let result = await queryImpl(
1062 request,
1063 location,
1064 matches,
1065 requestContext,
1066 dataStrategy || null,
1067 skipLoaderErrorBubbling === true,
1068 null,
1069 filterMatchesToLoad || null,
1070 skipRevalidation === true
1071 );
1072 if (isResponse(result)) {
1073 return result;
1074 }
1075 return { location, basename, ...result };
1076 }
1077 async function queryRoute(request, {
1078 routeId,
1079 requestContext,
1080 dataStrategy,
1081 generateMiddlewareResponse
1082 } = {}) {
1083 let url = new URL(request.url);
1084 let method = request.method;
1085 let location = createLocation("", createPath(url), null, "default");
1086 let matches = matchRoutes(dataRoutes, location, basename);
1087 requestContext = requestContext != null ? requestContext : new RouterContextProvider();
1088 if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
1089 throw getInternalRouterError(405, { method });
1090 } else if (!matches) {
1091 throw getInternalRouterError(404, { pathname: location.pathname });
1092 }
1093 let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location);
1094 if (routeId && !match) {
1095 throw getInternalRouterError(403, {
1096 pathname: location.pathname,
1097 routeId
1098 });
1099 } else if (!match) {
1100 throw getInternalRouterError(404, { pathname: location.pathname });
1101 }
1102 if (generateMiddlewareResponse) {
1103 invariant(
1104 requestContext instanceof RouterContextProvider,
1105 "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`"
1106 );
1107 await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties);
1108 let response = await runServerMiddlewarePipeline(
1109 {
1110 request,
1111 unstable_pattern: getRoutePattern(matches),
1112 matches,
1113 params: matches[0].params,
1114 // If we're calling middleware then it must be enabled so we can cast
1115 // this to the proper type knowing it's not an `AppLoadContext`
1116 context: requestContext
1117 },
1118 async () => {
1119 let res = await generateMiddlewareResponse(
1120 async (innerRequest) => {
1121 let result2 = await queryImpl(
1122 innerRequest,
1123 location,
1124 matches,
1125 requestContext,
1126 dataStrategy || null,
1127 false,
1128 match,
1129 null,
1130 false
1131 );
1132 let processed = handleQueryResult(result2);
1133 return isResponse(processed) ? processed : typeof processed === "string" ? new Response(processed) : Response.json(processed);
1134 }
1135 );
1136 return res;
1137 },
1138 (error) => {
1139 if (isDataWithResponseInit(error)) {
1140 return Promise.resolve(dataWithResponseInitToResponse(error));
1141 }
1142 if (isResponse(error)) {
1143 return Promise.resolve(error);
1144 }
1145 throw error;
1146 }
1147 );
1148 return response;
1149 }
1150 let result = await queryImpl(
1151 request,
1152 location,
1153 matches,
1154 requestContext,
1155 dataStrategy || null,
1156 false,
1157 match,
1158 null,
1159 false
1160 );
1161 return handleQueryResult(result);
1162 function handleQueryResult(result2) {
1163 if (isResponse(result2)) {
1164 return result2;
1165 }
1166 let error = result2.errors ? Object.values(result2.errors)[0] : void 0;
1167 if (error !== void 0) {
1168 throw error;
1169 }
1170 if (result2.actionData) {
1171 return Object.values(result2.actionData)[0];
1172 }
1173 if (result2.loaderData) {
1174 return Object.values(result2.loaderData)[0];
1175 }
1176 return void 0;
1177 }
1178 }
1179 async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {
1180 invariant(
1181 request.signal,
1182 "query()/queryRoute() requests must contain an AbortController signal"
1183 );
1184 try {
1185 if (isMutationMethod(request.method)) {
1186 let result2 = await submit(
1187 request,
1188 matches,
1189 routeMatch || getTargetMatch(matches, location),
1190 requestContext,
1191 dataStrategy,
1192 skipLoaderErrorBubbling,
1193 routeMatch != null,
1194 filterMatchesToLoad,
1195 skipRevalidation
1196 );
1197 return result2;
1198 }
1199 let result = await loadRouteData(
1200 request,
1201 matches,
1202 requestContext,
1203 dataStrategy,
1204 skipLoaderErrorBubbling,
1205 routeMatch,
1206 filterMatchesToLoad
1207 );
1208 return isResponse(result) ? result : {
1209 ...result,
1210 actionData: null,
1211 actionHeaders: {}
1212 };
1213 } catch (e) {
1214 if (isDataStrategyResult(e) && isResponse(e.result)) {
1215 if (e.type === "error" /* error */) {
1216 throw e.result;
1217 }
1218 return e.result;
1219 }
1220 if (isRedirectResponse(e)) {
1221 return e;
1222 }
1223 throw e;
1224 }
1225 }
1226 async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {
1227 let result;
1228 if (!actionMatch.route.action && !actionMatch.route.lazy) {
1229 let error = getInternalRouterError(405, {
1230 method: request.method,
1231 pathname: new URL(request.url).pathname,
1232 routeId: actionMatch.route.id
1233 });
1234 if (isRouteRequest) {
1235 throw error;
1236 }
1237 result = {
1238 type: "error" /* error */,
1239 error
1240 };
1241 } else {
1242 let dsMatches = getTargetedDataStrategyMatches(
1243 mapRouteProperties,
1244 manifest,
1245 request,
1246 matches,
1247 actionMatch,
1248 [],
1249 requestContext
1250 );
1251 let results = await callDataStrategy(
1252 request,
1253 dsMatches,
1254 isRouteRequest,
1255 requestContext,
1256 dataStrategy
1257 );
1258 result = results[actionMatch.route.id];
1259 if (request.signal.aborted) {
1260 throwStaticHandlerAbortedError(request, isRouteRequest);
1261 }
1262 }
1263 if (isRedirectResult(result)) {
1264 throw new Response(null, {
1265 status: result.response.status,
1266 headers: {
1267 Location: result.response.headers.get("Location")
1268 }
1269 });
1270 }
1271 if (isRouteRequest) {
1272 if (isErrorResult(result)) {
1273 throw result.error;
1274 }
1275 return {
1276 matches: [actionMatch],
1277 loaderData: {},
1278 actionData: { [actionMatch.route.id]: result.data },
1279 errors: null,
1280 // Note: statusCode + headers are unused here since queryRoute will
1281 // return the raw Response or value
1282 statusCode: 200,
1283 loaderHeaders: {},
1284 actionHeaders: {}
1285 };
1286 }
1287 if (skipRevalidation) {
1288 if (isErrorResult(result)) {
1289 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
1290 return {
1291 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
1292 actionData: null,
1293 actionHeaders: {
1294 ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
1295 },
1296 matches,
1297 loaderData: {},
1298 errors: {
1299 [boundaryMatch.route.id]: result.error
1300 },
1301 loaderHeaders: {}
1302 };
1303 } else {
1304 return {
1305 actionData: {
1306 [actionMatch.route.id]: result.data
1307 },
1308 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},
1309 matches,
1310 loaderData: {},
1311 errors: null,
1312 statusCode: result.statusCode || 200,
1313 loaderHeaders: {}
1314 };
1315 }
1316 }
1317 let loaderRequest = new Request(request.url, {
1318 headers: request.headers,
1319 redirect: request.redirect,
1320 signal: request.signal
1321 });
1322 if (isErrorResult(result)) {
1323 let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
1324 let handlerContext2 = await loadRouteData(
1325 loaderRequest,
1326 matches,
1327 requestContext,
1328 dataStrategy,
1329 skipLoaderErrorBubbling,
1330 null,
1331 filterMatchesToLoad,
1332 [boundaryMatch.route.id, result]
1333 );
1334 return {
1335 ...handlerContext2,
1336 statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
1337 actionData: null,
1338 actionHeaders: {
1339 ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
1340 }
1341 };
1342 }
1343 let handlerContext = await loadRouteData(
1344 loaderRequest,
1345 matches,
1346 requestContext,
1347 dataStrategy,
1348 skipLoaderErrorBubbling,
1349 null,
1350 filterMatchesToLoad
1351 );
1352 return {
1353 ...handlerContext,
1354 actionData: {
1355 [actionMatch.route.id]: result.data
1356 },
1357 // action status codes take precedence over loader status codes
1358 ...result.statusCode ? { statusCode: result.statusCode } : {},
1359 actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}
1360 };
1361 }
1362 async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {
1363 let isRouteRequest = routeMatch != null;
1364 if (isRouteRequest && !routeMatch?.route.loader && !routeMatch?.route.lazy) {
1365 throw getInternalRouterError(400, {
1366 method: request.method,
1367 pathname: new URL(request.url).pathname,
1368 routeId: routeMatch?.route.id
1369 });
1370 }
1371 let dsMatches;
1372 if (routeMatch) {
1373 dsMatches = getTargetedDataStrategyMatches(
1374 mapRouteProperties,
1375 manifest,
1376 request,
1377 matches,
1378 routeMatch,
1379 [],
1380 requestContext
1381 );
1382 } else {
1383 let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? (
1384 // Up to but not including the boundary
1385 matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1
1386 ) : void 0;
1387 let pattern = getRoutePattern(matches);
1388 dsMatches = matches.map((match, index) => {
1389 if (maxIdx != null && index > maxIdx) {
1390 return getDataStrategyMatch(
1391 mapRouteProperties,
1392 manifest,
1393 request,
1394 pattern,
1395 match,
1396 [],
1397 requestContext,
1398 false
1399 );
1400 }
1401 return getDataStrategyMatch(
1402 mapRouteProperties,
1403 manifest,
1404 request,
1405 pattern,
1406 match,
1407 [],
1408 requestContext,
1409 (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match))
1410 );
1411 });
1412 }
1413 if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) {
1414 return {
1415 matches,
1416 loaderData: {},
1417 errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {
1418 [pendingActionResult[0]]: pendingActionResult[1].error
1419 } : null,
1420 statusCode: 200,
1421 loaderHeaders: {}
1422 };
1423 }
1424 let results = await callDataStrategy(
1425 request,
1426 dsMatches,
1427 isRouteRequest,
1428 requestContext,
1429 dataStrategy
1430 );
1431 if (request.signal.aborted) {
1432 throwStaticHandlerAbortedError(request, isRouteRequest);
1433 }
1434 let handlerContext = processRouteLoaderData(
1435 matches,
1436 results,
1437 pendingActionResult,
1438 true,
1439 skipLoaderErrorBubbling
1440 );
1441 return {
1442 ...handlerContext,
1443 matches
1444 };
1445 }
1446 async function callDataStrategy(request, matches, isRouteRequest, requestContext, dataStrategy) {
1447 let results = await callDataStrategyImpl(
1448 dataStrategy || defaultDataStrategy,
1449 request,
1450 matches,
1451 null,
1452 requestContext);
1453 let dataResults = {};
1454 await Promise.all(
1455 matches.map(async (match) => {
1456 if (!(match.route.id in results)) {
1457 return;
1458 }
1459 let result = results[match.route.id];
1460 if (isRedirectDataStrategyResult(result)) {
1461 let response = result.result;
1462 throw normalizeRelativeRoutingRedirectResponse(
1463 response,
1464 request,
1465 match.route.id,
1466 matches,
1467 basename
1468 );
1469 }
1470 if (isRouteRequest) {
1471 if (isResponse(result.result)) {
1472 throw result;
1473 } else if (isDataWithResponseInit(result.result)) {
1474 throw dataWithResponseInitToResponse(result.result);
1475 }
1476 }
1477 dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);
1478 })
1479 );
1480 return dataResults;
1481 }
1482 return {
1483 dataRoutes,
1484 query,
1485 queryRoute
1486 };
1487}
1488function getStaticContextFromError(routes, handlerContext, error, boundaryId) {
1489 let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;
1490 return {
1491 ...handlerContext,
1492 statusCode: isRouteErrorResponse(error) ? error.status : 500,
1493 errors: {
1494 [errorBoundaryId]: error
1495 }
1496 };
1497}
1498function throwStaticHandlerAbortedError(request, isRouteRequest) {
1499 if (request.signal.reason !== void 0) {
1500 throw request.signal.reason;
1501 }
1502 let method = isRouteRequest ? "queryRoute" : "query";
1503 throw new Error(
1504 `${method}() call aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}`
1505 );
1506}
1507function normalizeTo(location, matches, basename, to, fromRouteId, relative) {
1508 let contextualMatches;
1509 let activeRouteMatch;
1510 {
1511 contextualMatches = matches;
1512 activeRouteMatch = matches[matches.length - 1];
1513 }
1514 let path = resolveTo(
1515 to ? to : ".",
1516 getResolveToMatches(contextualMatches),
1517 stripBasename(location.pathname, basename) || location.pathname,
1518 relative === "path"
1519 );
1520 if (to == null) {
1521 path.search = location.search;
1522 path.hash = location.hash;
1523 }
1524 if ((to == null || to === "" || to === ".") && activeRouteMatch) {
1525 let nakedIndex = hasNakedIndexQuery(path.search);
1526 if (activeRouteMatch.route.index && !nakedIndex) {
1527 path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
1528 } else if (!activeRouteMatch.route.index && nakedIndex) {
1529 let params = new URLSearchParams(path.search);
1530 let indexValues = params.getAll("index");
1531 params.delete("index");
1532 indexValues.filter((v) => v).forEach((v) => params.append("index", v));
1533 let qs = params.toString();
1534 path.search = qs ? `?${qs}` : "";
1535 }
1536 }
1537 if (basename !== "/") {
1538 path.pathname = prependBasename({ basename, pathname: path.pathname });
1539 }
1540 return createPath(path);
1541}
1542function shouldRevalidateLoader(loaderMatch, arg) {
1543 if (loaderMatch.route.shouldRevalidate) {
1544 let routeChoice = loaderMatch.route.shouldRevalidate(arg);
1545 if (typeof routeChoice === "boolean") {
1546 return routeChoice;
1547 }
1548 }
1549 return arg.defaultShouldRevalidate;
1550}
1551var lazyRoutePropertyCache = /* @__PURE__ */ new WeakMap();
1552var loadLazyRouteProperty = ({
1553 key,
1554 route,
1555 manifest,
1556 mapRouteProperties
1557}) => {
1558 let routeToUpdate = manifest[route.id];
1559 invariant(routeToUpdate, "No route found in manifest");
1560 if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== "object") {
1561 return;
1562 }
1563 let lazyFn = routeToUpdate.lazy[key];
1564 if (!lazyFn) {
1565 return;
1566 }
1567 let cache2 = lazyRoutePropertyCache.get(routeToUpdate);
1568 if (!cache2) {
1569 cache2 = {};
1570 lazyRoutePropertyCache.set(routeToUpdate, cache2);
1571 }
1572 let cachedPromise = cache2[key];
1573 if (cachedPromise) {
1574 return cachedPromise;
1575 }
1576 let propertyPromise = (async () => {
1577 let isUnsupported = isUnsupportedLazyRouteObjectKey(key);
1578 let staticRouteValue = routeToUpdate[key];
1579 let isStaticallyDefined = staticRouteValue !== void 0 && key !== "hasErrorBoundary";
1580 if (isUnsupported) {
1581 warning(
1582 !isUnsupported,
1583 "Route property " + key + " is not a supported lazy route property. This property will be ignored."
1584 );
1585 cache2[key] = Promise.resolve();
1586 } else if (isStaticallyDefined) {
1587 warning(
1588 false,
1589 `Route "${routeToUpdate.id}" has a static property "${key}" defined. The lazy property will be ignored.`
1590 );
1591 } else {
1592 let value = await lazyFn();
1593 if (value != null) {
1594 Object.assign(routeToUpdate, { [key]: value });
1595 Object.assign(routeToUpdate, mapRouteProperties(routeToUpdate));
1596 }
1597 }
1598 if (typeof routeToUpdate.lazy === "object") {
1599 routeToUpdate.lazy[key] = void 0;
1600 if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) {
1601 routeToUpdate.lazy = void 0;
1602 }
1603 }
1604 })();
1605 cache2[key] = propertyPromise;
1606 return propertyPromise;
1607};
1608var lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();
1609function loadLazyRoute(route, type, manifest, mapRouteProperties, lazyRoutePropertiesToSkip) {
1610 let routeToUpdate = manifest[route.id];
1611 invariant(routeToUpdate, "No route found in manifest");
1612 if (!route.lazy) {
1613 return {
1614 lazyRoutePromise: void 0,
1615 lazyHandlerPromise: void 0
1616 };
1617 }
1618 if (typeof route.lazy === "function") {
1619 let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate);
1620 if (cachedPromise) {
1621 return {
1622 lazyRoutePromise: cachedPromise,
1623 lazyHandlerPromise: cachedPromise
1624 };
1625 }
1626 let lazyRoutePromise2 = (async () => {
1627 invariant(
1628 typeof route.lazy === "function",
1629 "No lazy route function found"
1630 );
1631 let lazyRoute = await route.lazy();
1632 let routeUpdates = {};
1633 for (let lazyRouteProperty in lazyRoute) {
1634 let lazyValue = lazyRoute[lazyRouteProperty];
1635 if (lazyValue === void 0) {
1636 continue;
1637 }
1638 let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty);
1639 let staticRouteValue = routeToUpdate[lazyRouteProperty];
1640 let isStaticallyDefined = staticRouteValue !== void 0 && // This property isn't static since it should always be updated based
1641 // on the route updates
1642 lazyRouteProperty !== "hasErrorBoundary";
1643 if (isUnsupported) {
1644 warning(
1645 !isUnsupported,
1646 "Route property " + lazyRouteProperty + " is not a supported property to be returned from a lazy route function. This property will be ignored."
1647 );
1648 } else if (isStaticallyDefined) {
1649 warning(
1650 !isStaticallyDefined,
1651 `Route "${routeToUpdate.id}" has a static property "${lazyRouteProperty}" defined but its lazy function is also returning a value for this property. The lazy route property "${lazyRouteProperty}" will be ignored.`
1652 );
1653 } else {
1654 routeUpdates[lazyRouteProperty] = lazyValue;
1655 }
1656 }
1657 Object.assign(routeToUpdate, routeUpdates);
1658 Object.assign(routeToUpdate, {
1659 // To keep things framework agnostic, we use the provided `mapRouteProperties`
1660 // function to set the framework-aware properties (`element`/`hasErrorBoundary`)
1661 // since the logic will differ between frameworks.
1662 ...mapRouteProperties(routeToUpdate),
1663 lazy: void 0
1664 });
1665 })();
1666 lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2);
1667 lazyRoutePromise2.catch(() => {
1668 });
1669 return {
1670 lazyRoutePromise: lazyRoutePromise2,
1671 lazyHandlerPromise: lazyRoutePromise2
1672 };
1673 }
1674 let lazyKeys = Object.keys(route.lazy);
1675 let lazyPropertyPromises = [];
1676 let lazyHandlerPromise = void 0;
1677 for (let key of lazyKeys) {
1678 if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) {
1679 continue;
1680 }
1681 let promise = loadLazyRouteProperty({
1682 key,
1683 route,
1684 manifest,
1685 mapRouteProperties
1686 });
1687 if (promise) {
1688 lazyPropertyPromises.push(promise);
1689 if (key === type) {
1690 lazyHandlerPromise = promise;
1691 }
1692 }
1693 }
1694 let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => {
1695 }) : void 0;
1696 lazyRoutePromise?.catch(() => {
1697 });
1698 lazyHandlerPromise?.catch(() => {
1699 });
1700 return {
1701 lazyRoutePromise,
1702 lazyHandlerPromise
1703 };
1704}
1705function isNonNullable(value) {
1706 return value !== void 0;
1707}
1708function loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties) {
1709 let promises = matches.map(({ route }) => {
1710 if (typeof route.lazy !== "object" || !route.lazy.middleware) {
1711 return void 0;
1712 }
1713 return loadLazyRouteProperty({
1714 key: "middleware",
1715 route,
1716 manifest,
1717 mapRouteProperties
1718 });
1719 }).filter(isNonNullable);
1720 return promises.length > 0 ? Promise.all(promises) : void 0;
1721}
1722async function defaultDataStrategy(args) {
1723 let matchesToLoad = args.matches.filter((m) => m.shouldLoad);
1724 let keyedResults = {};
1725 let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));
1726 results.forEach((result, i) => {
1727 keyedResults[matchesToLoad[i].route.id] = result;
1728 });
1729 return keyedResults;
1730}
1731function runServerMiddlewarePipeline(args, handler, errorHandler) {
1732 return runMiddlewarePipeline(
1733 args,
1734 handler,
1735 processResult,
1736 isResponse,
1737 errorHandler
1738 );
1739 function processResult(result) {
1740 return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result;
1741 }
1742}
1743async function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) {
1744 let { matches, request, params, context, unstable_pattern } = args;
1745 let tuples = matches.flatMap(
1746 (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : []
1747 );
1748 let result = await callRouteMiddleware(
1749 {
1750 request,
1751 params,
1752 context,
1753 unstable_pattern
1754 },
1755 tuples,
1756 handler,
1757 processResult,
1758 isResult,
1759 errorHandler
1760 );
1761 return result;
1762}
1763async function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) {
1764 let { request } = args;
1765 if (request.signal.aborted) {
1766 throw request.signal.reason ?? new Error(`Request aborted: ${request.method} ${request.url}`);
1767 }
1768 let tuple = middlewares[idx];
1769 if (!tuple) {
1770 let result = await handler();
1771 return result;
1772 }
1773 let [routeId, middleware] = tuple;
1774 let nextResult;
1775 let next = async () => {
1776 if (nextResult) {
1777 throw new Error("You may only call `next()` once per middleware");
1778 }
1779 try {
1780 let result = await callRouteMiddleware(
1781 args,
1782 middlewares,
1783 handler,
1784 processResult,
1785 isResult,
1786 errorHandler,
1787 idx + 1
1788 );
1789 nextResult = { value: result };
1790 return nextResult.value;
1791 } catch (error) {
1792 nextResult = { value: await errorHandler(error, routeId, nextResult) };
1793 return nextResult.value;
1794 }
1795 };
1796 try {
1797 let value = await middleware(args, next);
1798 let result = value != null ? processResult(value) : void 0;
1799 if (isResult(result)) {
1800 return result;
1801 } else if (nextResult) {
1802 return result ?? nextResult.value;
1803 } else {
1804 nextResult = { value: await next() };
1805 return nextResult.value;
1806 }
1807 } catch (error) {
1808 let response = await errorHandler(error, routeId, nextResult);
1809 return response;
1810 }
1811}
1812function getDataStrategyMatchLazyPromises(mapRouteProperties, manifest, request, match, lazyRoutePropertiesToSkip) {
1813 let lazyMiddlewarePromise = loadLazyRouteProperty({
1814 key: "middleware",
1815 route: match.route,
1816 manifest,
1817 mapRouteProperties
1818 });
1819 let lazyRoutePromises = loadLazyRoute(
1820 match.route,
1821 isMutationMethod(request.method) ? "action" : "loader",
1822 manifest,
1823 mapRouteProperties,
1824 lazyRoutePropertiesToSkip
1825 );
1826 return {
1827 middleware: lazyMiddlewarePromise,
1828 route: lazyRoutePromises.lazyRoutePromise,
1829 handler: lazyRoutePromises.lazyHandlerPromise
1830 };
1831}
1832function getDataStrategyMatch(mapRouteProperties, manifest, request, unstable_pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null) {
1833 let isUsingNewApi = false;
1834 let _lazyPromises = getDataStrategyMatchLazyPromises(
1835 mapRouteProperties,
1836 manifest,
1837 request,
1838 match,
1839 lazyRoutePropertiesToSkip
1840 );
1841 return {
1842 ...match,
1843 _lazyPromises,
1844 shouldLoad,
1845 shouldRevalidateArgs,
1846 shouldCallHandler(defaultShouldRevalidate) {
1847 isUsingNewApi = true;
1848 if (!shouldRevalidateArgs) {
1849 return shouldLoad;
1850 }
1851 if (typeof defaultShouldRevalidate === "boolean") {
1852 return shouldRevalidateLoader(match, {
1853 ...shouldRevalidateArgs,
1854 defaultShouldRevalidate
1855 });
1856 }
1857 return shouldRevalidateLoader(match, shouldRevalidateArgs);
1858 },
1859 resolve(handlerOverride) {
1860 let { lazy, loader, middleware } = match.route;
1861 let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader);
1862 let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy;
1863 if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) {
1864 return callLoaderOrAction({
1865 request,
1866 unstable_pattern,
1867 match,
1868 lazyHandlerPromise: _lazyPromises?.handler,
1869 lazyRoutePromise: _lazyPromises?.route,
1870 handlerOverride,
1871 scopedContext
1872 });
1873 }
1874 return Promise.resolve({ type: "data" /* data */, result: void 0 });
1875 }
1876 };
1877}
1878function getTargetedDataStrategyMatches(mapRouteProperties, manifest, request, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) {
1879 return matches.map((match) => {
1880 if (match.route.id !== targetMatch.route.id) {
1881 return {
1882 ...match,
1883 shouldLoad: false,
1884 shouldRevalidateArgs,
1885 shouldCallHandler: () => false,
1886 _lazyPromises: getDataStrategyMatchLazyPromises(
1887 mapRouteProperties,
1888 manifest,
1889 request,
1890 match,
1891 lazyRoutePropertiesToSkip
1892 ),
1893 resolve: () => Promise.resolve({ type: "data", result: void 0 })
1894 };
1895 }
1896 return getDataStrategyMatch(
1897 mapRouteProperties,
1898 manifest,
1899 request,
1900 getRoutePattern(matches),
1901 match,
1902 lazyRoutePropertiesToSkip,
1903 scopedContext,
1904 true,
1905 shouldRevalidateArgs
1906 );
1907 });
1908}
1909async function callDataStrategyImpl(dataStrategyImpl, request, matches, fetcherKey, scopedContext, isStaticHandler) {
1910 if (matches.some((m) => m._lazyPromises?.middleware)) {
1911 await Promise.all(matches.map((m) => m._lazyPromises?.middleware));
1912 }
1913 let dataStrategyArgs = {
1914 request,
1915 unstable_pattern: getRoutePattern(matches),
1916 params: matches[0].params,
1917 context: scopedContext,
1918 matches
1919 };
1920 let runClientMiddleware = () => {
1921 throw new Error(
1922 "You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`"
1923 );
1924 } ;
1925 let results = await dataStrategyImpl({
1926 ...dataStrategyArgs,
1927 fetcherKey,
1928 runClientMiddleware
1929 });
1930 try {
1931 await Promise.all(
1932 matches.flatMap((m) => [
1933 m._lazyPromises?.handler,
1934 m._lazyPromises?.route
1935 ])
1936 );
1937 } catch (e) {
1938 }
1939 return results;
1940}
1941async function callLoaderOrAction({
1942 request,
1943 unstable_pattern,
1944 match,
1945 lazyHandlerPromise,
1946 lazyRoutePromise,
1947 handlerOverride,
1948 scopedContext
1949}) {
1950 let result;
1951 let onReject;
1952 let isAction = isMutationMethod(request.method);
1953 let type = isAction ? "action" : "loader";
1954 let runHandler = (handler) => {
1955 let reject;
1956 let abortPromise = new Promise((_, r) => reject = r);
1957 onReject = () => reject();
1958 request.signal.addEventListener("abort", onReject);
1959 let actualHandler = (ctx) => {
1960 if (typeof handler !== "function") {
1961 return Promise.reject(
1962 new Error(
1963 `You cannot call the handler for a route which defines a boolean "${type}" [routeId: ${match.route.id}]`
1964 )
1965 );
1966 }
1967 return handler(
1968 {
1969 request,
1970 unstable_pattern,
1971 params: match.params,
1972 context: scopedContext
1973 },
1974 ...ctx !== void 0 ? [ctx] : []
1975 );
1976 };
1977 let handlerPromise = (async () => {
1978 try {
1979 let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler());
1980 return { type: "data", result: val };
1981 } catch (e) {
1982 return { type: "error", result: e };
1983 }
1984 })();
1985 return Promise.race([handlerPromise, abortPromise]);
1986 };
1987 try {
1988 let handler = isAction ? match.route.action : match.route.loader;
1989 if (lazyHandlerPromise || lazyRoutePromise) {
1990 if (handler) {
1991 let handlerError;
1992 let [value] = await Promise.all([
1993 // If the handler throws, don't let it immediately bubble out,
1994 // since we need to let the lazy() execution finish so we know if this
1995 // route has a boundary that can handle the error
1996 runHandler(handler).catch((e) => {
1997 handlerError = e;
1998 }),
1999 // Ensure all lazy route promises are resolved before continuing
2000 lazyHandlerPromise,
2001 lazyRoutePromise
2002 ]);
2003 if (handlerError !== void 0) {
2004 throw handlerError;
2005 }
2006 result = value;
2007 } else {
2008 await lazyHandlerPromise;
2009 let handler2 = isAction ? match.route.action : match.route.loader;
2010 if (handler2) {
2011 [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]);
2012 } else if (type === "action") {
2013 let url = new URL(request.url);
2014 let pathname = url.pathname + url.search;
2015 throw getInternalRouterError(405, {
2016 method: request.method,
2017 pathname,
2018 routeId: match.route.id
2019 });
2020 } else {
2021 return { type: "data" /* data */, result: void 0 };
2022 }
2023 }
2024 } else if (!handler) {
2025 let url = new URL(request.url);
2026 let pathname = url.pathname + url.search;
2027 throw getInternalRouterError(404, {
2028 pathname
2029 });
2030 } else {
2031 result = await runHandler(handler);
2032 }
2033 } catch (e) {
2034 return { type: "error" /* error */, result: e };
2035 } finally {
2036 if (onReject) {
2037 request.signal.removeEventListener("abort", onReject);
2038 }
2039 }
2040 return result;
2041}
2042async function parseResponseBody(response) {
2043 let contentType = response.headers.get("Content-Type");
2044 if (contentType && /\bapplication\/json\b/.test(contentType)) {
2045 return response.body == null ? null : response.json();
2046 }
2047 return response.text();
2048}
2049async function convertDataStrategyResultToDataResult(dataStrategyResult) {
2050 let { result, type } = dataStrategyResult;
2051 if (isResponse(result)) {
2052 let data2;
2053 try {
2054 data2 = await parseResponseBody(result);
2055 } catch (e) {
2056 return { type: "error" /* error */, error: e };
2057 }
2058 if (type === "error" /* error */) {
2059 return {
2060 type: "error" /* error */,
2061 error: new ErrorResponseImpl(result.status, result.statusText, data2),
2062 statusCode: result.status,
2063 headers: result.headers
2064 };
2065 }
2066 return {
2067 type: "data" /* data */,
2068 data: data2,
2069 statusCode: result.status,
2070 headers: result.headers
2071 };
2072 }
2073 if (type === "error" /* error */) {
2074 if (isDataWithResponseInit(result)) {
2075 if (result.data instanceof Error) {
2076 return {
2077 type: "error" /* error */,
2078 error: result.data,
2079 statusCode: result.init?.status,
2080 headers: result.init?.headers ? new Headers(result.init.headers) : void 0
2081 };
2082 }
2083 return {
2084 type: "error" /* error */,
2085 error: dataWithResponseInitToErrorResponse(result),
2086 statusCode: isRouteErrorResponse(result) ? result.status : void 0,
2087 headers: result.init?.headers ? new Headers(result.init.headers) : void 0
2088 };
2089 }
2090 return {
2091 type: "error" /* error */,
2092 error: result,
2093 statusCode: isRouteErrorResponse(result) ? result.status : void 0
2094 };
2095 }
2096 if (isDataWithResponseInit(result)) {
2097 return {
2098 type: "data" /* data */,
2099 data: result.data,
2100 statusCode: result.init?.status,
2101 headers: result.init?.headers ? new Headers(result.init.headers) : void 0
2102 };
2103 }
2104 return { type: "data" /* data */, data: result };
2105}
2106function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) {
2107 let location = response.headers.get("Location");
2108 invariant(
2109 location,
2110 "Redirects returned/thrown from loaders/actions must have a Location header"
2111 );
2112 if (!isAbsoluteUrl(location)) {
2113 let trimmedMatches = matches.slice(
2114 0,
2115 matches.findIndex((m) => m.route.id === routeId) + 1
2116 );
2117 location = normalizeTo(
2118 new URL(request.url),
2119 trimmedMatches,
2120 basename,
2121 location
2122 );
2123 response.headers.set("Location", location);
2124 }
2125 return response;
2126}
2127function processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) {
2128 let loaderData = {};
2129 let errors = null;
2130 let statusCode;
2131 let foundError = false;
2132 let loaderHeaders = {};
2133 let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0;
2134 matches.forEach((match) => {
2135 if (!(match.route.id in results)) {
2136 return;
2137 }
2138 let id = match.route.id;
2139 let result = results[id];
2140 invariant(
2141 !isRedirectResult(result),
2142 "Cannot handle redirect results in processLoaderData"
2143 );
2144 if (isErrorResult(result)) {
2145 let error = result.error;
2146 if (pendingError !== void 0) {
2147 error = pendingError;
2148 pendingError = void 0;
2149 }
2150 errors = errors || {};
2151 if (skipLoaderErrorBubbling) {
2152 errors[id] = error;
2153 } else {
2154 let boundaryMatch = findNearestBoundary(matches, id);
2155 if (errors[boundaryMatch.route.id] == null) {
2156 errors[boundaryMatch.route.id] = error;
2157 }
2158 }
2159 if (!isStaticHandler) {
2160 loaderData[id] = ResetLoaderDataSymbol;
2161 }
2162 if (!foundError) {
2163 foundError = true;
2164 statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;
2165 }
2166 if (result.headers) {
2167 loaderHeaders[id] = result.headers;
2168 }
2169 } else {
2170 loaderData[id] = result.data;
2171 if (result.statusCode && result.statusCode !== 200 && !foundError) {
2172 statusCode = result.statusCode;
2173 }
2174 if (result.headers) {
2175 loaderHeaders[id] = result.headers;
2176 }
2177 }
2178 });
2179 if (pendingError !== void 0 && pendingActionResult) {
2180 errors = { [pendingActionResult[0]]: pendingError };
2181 if (pendingActionResult[2]) {
2182 loaderData[pendingActionResult[2]] = void 0;
2183 }
2184 }
2185 return {
2186 loaderData,
2187 errors,
2188 statusCode: statusCode || 200,
2189 loaderHeaders
2190 };
2191}
2192function findNearestBoundary(matches, routeId) {
2193 let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches];
2194 return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0];
2195}
2196function getShortCircuitMatches(routes) {
2197 let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === "/") || {
2198 id: `__shim-error-route__`
2199 };
2200 return {
2201 matches: [
2202 {
2203 params: {},
2204 pathname: "",
2205 pathnameBase: "",
2206 route
2207 }
2208 ],
2209 route
2210 };
2211}
2212function getInternalRouterError(status, {
2213 pathname,
2214 routeId,
2215 method,
2216 type,
2217 message
2218} = {}) {
2219 let statusText = "Unknown Server Error";
2220 let errorMessage = "Unknown @remix-run/router error";
2221 if (status === 400) {
2222 statusText = "Bad Request";
2223 if (method && pathname && routeId) {
2224 errorMessage = `You made a ${method} request to "${pathname}" but did not provide a \`loader\` for route "${routeId}", so there is no way to handle the request.`;
2225 } else if (type === "invalid-body") {
2226 errorMessage = "Unable to encode submission body";
2227 }
2228 } else if (status === 403) {
2229 statusText = "Forbidden";
2230 errorMessage = `Route "${routeId}" does not match URL "${pathname}"`;
2231 } else if (status === 404) {
2232 statusText = "Not Found";
2233 errorMessage = `No route matches URL "${pathname}"`;
2234 } else if (status === 405) {
2235 statusText = "Method Not Allowed";
2236 if (method && pathname && routeId) {
2237 errorMessage = `You made a ${method.toUpperCase()} request to "${pathname}" but did not provide an \`action\` for route "${routeId}", so there is no way to handle the request.`;
2238 } else if (method) {
2239 errorMessage = `Invalid request method "${method.toUpperCase()}"`;
2240 }
2241 }
2242 return new ErrorResponseImpl(
2243 status || 500,
2244 statusText,
2245 new Error(errorMessage),
2246 true
2247 );
2248}
2249function dataWithResponseInitToResponse(data2) {
2250 return Response.json(data2.data, data2.init ?? void 0);
2251}
2252function dataWithResponseInitToErrorResponse(data2) {
2253 return new ErrorResponseImpl(
2254 data2.init?.status ?? 500,
2255 data2.init?.statusText ?? "Internal Server Error",
2256 data2.data
2257 );
2258}
2259function isDataStrategyResult(result) {
2260 return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === "data" /* data */ || result.type === "error" /* error */);
2261}
2262function isRedirectDataStrategyResult(result) {
2263 return isResponse(result.result) && redirectStatusCodes.has(result.result.status);
2264}
2265function isErrorResult(result) {
2266 return result.type === "error" /* error */;
2267}
2268function isRedirectResult(result) {
2269 return (result && result.type) === "redirect" /* redirect */;
2270}
2271function isDataWithResponseInit(value) {
2272 return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit";
2273}
2274function isResponse(value) {
2275 return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
2276}
2277function isRedirectStatusCode(statusCode) {
2278 return redirectStatusCodes.has(statusCode);
2279}
2280function isRedirectResponse(result) {
2281 return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location");
2282}
2283function isValidMethod(method) {
2284 return validRequestMethods.has(method.toUpperCase());
2285}
2286function isMutationMethod(method) {
2287 return validMutationMethods.has(method.toUpperCase());
2288}
2289function hasNakedIndexQuery(search) {
2290 return new URLSearchParams(search).getAll("index").some((v) => v === "");
2291}
2292function getTargetMatch(matches, location) {
2293 let search = typeof location === "string" ? parsePath(location).search : location.search;
2294 if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) {
2295 return matches[matches.length - 1];
2296 }
2297 let pathMatches = getPathContributingMatches(matches);
2298 return pathMatches[pathMatches.length - 1];
2299}
2300
2301// lib/server-runtime/invariant.ts
2302function invariant2(value, message) {
2303 if (value === false || value === null || typeof value === "undefined") {
2304 console.error(
2305 "The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose"
2306 );
2307 throw new Error(message);
2308 }
2309}
2310
2311// lib/server-runtime/headers.ts
2312function getDocumentHeadersImpl(context, getRouteHeadersFn, _defaultHeaders) {
2313 let boundaryIdx = context.errors ? context.matches.findIndex((m) => context.errors[m.route.id]) : -1;
2314 let matches = boundaryIdx >= 0 ? context.matches.slice(0, boundaryIdx + 1) : context.matches;
2315 let errorHeaders;
2316 if (boundaryIdx >= 0) {
2317 let { actionHeaders, actionData, loaderHeaders, loaderData } = context;
2318 context.matches.slice(boundaryIdx).some((match) => {
2319 let id = match.route.id;
2320 if (actionHeaders[id] && (!actionData || !actionData.hasOwnProperty(id))) {
2321 errorHeaders = actionHeaders[id];
2322 } else if (loaderHeaders[id] && !loaderData.hasOwnProperty(id)) {
2323 errorHeaders = loaderHeaders[id];
2324 }
2325 return errorHeaders != null;
2326 });
2327 }
2328 const defaultHeaders = new Headers(_defaultHeaders);
2329 return matches.reduce((parentHeaders, match, idx) => {
2330 let { id } = match.route;
2331 let loaderHeaders = context.loaderHeaders[id] || new Headers();
2332 let actionHeaders = context.actionHeaders[id] || new Headers();
2333 let includeErrorHeaders = errorHeaders != null && idx === matches.length - 1;
2334 let includeErrorCookies = includeErrorHeaders && errorHeaders !== loaderHeaders && errorHeaders !== actionHeaders;
2335 let headersFn = getRouteHeadersFn(match);
2336 if (headersFn == null) {
2337 let headers2 = new Headers(parentHeaders);
2338 if (includeErrorCookies) {
2339 prependCookies(errorHeaders, headers2);
2340 }
2341 prependCookies(actionHeaders, headers2);
2342 prependCookies(loaderHeaders, headers2);
2343 return headers2;
2344 }
2345 let headers = new Headers(
2346 typeof headersFn === "function" ? headersFn({
2347 loaderHeaders,
2348 parentHeaders,
2349 actionHeaders,
2350 errorHeaders: includeErrorHeaders ? errorHeaders : void 0
2351 }) : headersFn
2352 );
2353 if (includeErrorCookies) {
2354 prependCookies(errorHeaders, headers);
2355 }
2356 prependCookies(actionHeaders, headers);
2357 prependCookies(loaderHeaders, headers);
2358 prependCookies(parentHeaders, headers);
2359 return headers;
2360 }, new Headers(defaultHeaders));
2361}
2362function prependCookies(parentHeaders, childHeaders) {
2363 let parentSetCookieString = parentHeaders.get("Set-Cookie");
2364 if (parentSetCookieString) {
2365 let cookies = splitCookiesString(parentSetCookieString);
2366 let childCookies = new Set(childHeaders.getSetCookie());
2367 cookies.forEach((cookie) => {
2368 if (!childCookies.has(cookie)) {
2369 childHeaders.append("Set-Cookie", cookie);
2370 }
2371 });
2372 }
2373}
2374var SINGLE_FETCH_REDIRECT_STATUS = 202;
2375var Outlet = Outlet$1;
2376var WithComponentProps = UNSAFE_WithComponentProps;
2377var WithErrorBoundaryProps = UNSAFE_WithErrorBoundaryProps;
2378var WithHydrateFallbackProps = UNSAFE_WithHydrateFallbackProps;
2379var globalVar = typeof globalThis !== "undefined" ? globalThis : global;
2380var ServerStorage = globalVar.___reactRouterServerStorage___ ?? (globalVar.___reactRouterServerStorage___ = new AsyncLocalStorage());
2381var redirect2 = (...args) => {
2382 const response = redirect(...args);
2383 const ctx = ServerStorage.getStore();
2384 if (ctx && ctx.runningAction) {
2385 ctx.redirect = response;
2386 }
2387 return response;
2388};
2389var redirectDocument2 = (...args) => {
2390 const response = redirectDocument(...args);
2391 const ctx = ServerStorage.getStore();
2392 if (ctx && ctx.runningAction) {
2393 ctx.redirect = response;
2394 }
2395 return response;
2396};
2397var replace2 = (...args) => {
2398 const response = replace(...args);
2399 const ctx = ServerStorage.getStore();
2400 if (ctx && ctx.runningAction) {
2401 ctx.redirect = response;
2402 }
2403 return response;
2404};
2405var cachedResolvePromise = (
2406 // @ts-expect-error - on 18 types, requires 19.
2407 React2.cache(async (resolve) => {
2408 return Promise.allSettled([resolve]).then((r) => r[0]);
2409 })
2410);
2411var Await = async ({
2412 children,
2413 resolve,
2414 errorElement
2415}) => {
2416 let promise = cachedResolvePromise(resolve);
2417 let resolved = await promise;
2418 if (resolved.status === "rejected" && !errorElement) {
2419 throw resolved.reason;
2420 }
2421 if (resolved.status === "rejected") {
2422 return React2.createElement(UNSAFE_AwaitContextProvider, {
2423 children: React2.createElement(React2.Fragment, null, errorElement),
2424 value: { _tracked: true, _error: resolved.reason }
2425 });
2426 }
2427 const toRender = typeof children === "function" ? children(resolved.value) : children;
2428 return React2.createElement(UNSAFE_AwaitContextProvider, {
2429 children: toRender,
2430 value: { _tracked: true, _data: resolved.value }
2431 });
2432};
2433async function matchRSCServerRequest({
2434 createTemporaryReferenceSet,
2435 basename,
2436 decodeReply,
2437 requestContext,
2438 loadServerAction,
2439 decodeAction,
2440 decodeFormState,
2441 onError,
2442 request,
2443 routes,
2444 generateResponse
2445}) {
2446 let requestUrl = new URL(request.url);
2447 const temporaryReferences = createTemporaryReferenceSet();
2448 if (isManifestRequest(requestUrl)) {
2449 let response2 = await generateManifestResponse(
2450 routes,
2451 basename,
2452 request,
2453 generateResponse,
2454 temporaryReferences
2455 );
2456 return response2;
2457 }
2458 let isDataRequest = isReactServerRequest(requestUrl);
2459 const url = new URL(request.url);
2460 let routerRequest = request;
2461 if (isDataRequest) {
2462 url.pathname = url.pathname.replace(/(_root)?\.rsc$/, "");
2463 routerRequest = new Request(url.toString(), {
2464 method: request.method,
2465 headers: request.headers,
2466 body: request.body,
2467 signal: request.signal,
2468 duplex: request.body ? "half" : void 0
2469 });
2470 }
2471 let matches = matchRoutes(routes, url.pathname, basename);
2472 if (matches) {
2473 await Promise.all(matches.map((m) => explodeLazyRoute(m.route)));
2474 }
2475 const leafMatch = matches?.[matches.length - 1];
2476 if (!isDataRequest && leafMatch && !leafMatch.route.Component && !leafMatch.route.ErrorBoundary) {
2477 return generateResourceResponse(
2478 routerRequest,
2479 routes,
2480 basename,
2481 leafMatch.route.id,
2482 requestContext,
2483 onError
2484 );
2485 }
2486 let response = await generateRenderResponse(
2487 routerRequest,
2488 routes,
2489 basename,
2490 isDataRequest,
2491 decodeReply,
2492 requestContext,
2493 loadServerAction,
2494 decodeAction,
2495 decodeFormState,
2496 onError,
2497 generateResponse,
2498 temporaryReferences
2499 );
2500 response.headers.set("X-Remix-Response", "yes");
2501 return response;
2502}
2503async function generateManifestResponse(routes, basename, request, generateResponse, temporaryReferences) {
2504 let url = new URL(request.url);
2505 let pathParam = url.searchParams.get("paths");
2506 let pathnames = pathParam ? pathParam.split(",").filter(Boolean) : [url.pathname.replace(/\.manifest$/, "")];
2507 let routeIds = /* @__PURE__ */ new Set();
2508 let matchedRoutes = pathnames.flatMap((pathname) => {
2509 let pathnameMatches = matchRoutes(routes, pathname, basename);
2510 return pathnameMatches?.map((m, i) => ({
2511 ...m.route,
2512 parentId: pathnameMatches[i - 1]?.route.id
2513 })) ?? [];
2514 }).filter((route) => {
2515 if (!routeIds.has(route.id)) {
2516 routeIds.add(route.id);
2517 return true;
2518 }
2519 return false;
2520 });
2521 let payload = {
2522 type: "manifest",
2523 patches: (await Promise.all([
2524 ...matchedRoutes.map((route) => getManifestRoute(route)),
2525 getAdditionalRoutePatches(
2526 pathnames,
2527 routes,
2528 basename,
2529 Array.from(routeIds)
2530 )
2531 ])).flat(1)
2532 };
2533 return generateResponse(
2534 {
2535 statusCode: 200,
2536 headers: new Headers({
2537 "Content-Type": "text/x-component",
2538 Vary: "Content-Type"
2539 }),
2540 payload
2541 },
2542 { temporaryReferences }
2543 );
2544}
2545function prependBasenameToRedirectResponse(response, basename = "/") {
2546 if (basename === "/") {
2547 return response;
2548 }
2549 let redirect3 = response.headers.get("Location");
2550 if (!redirect3 || isAbsoluteUrl(redirect3)) {
2551 return response;
2552 }
2553 response.headers.set(
2554 "Location",
2555 prependBasename({ basename, pathname: redirect3 })
2556 );
2557 return response;
2558}
2559async function processServerAction(request, basename, decodeReply, loadServerAction, decodeAction, decodeFormState, onError, temporaryReferences) {
2560 const getRevalidationRequest = () => new Request(request.url, {
2561 method: "GET",
2562 headers: request.headers,
2563 signal: request.signal
2564 });
2565 const isFormRequest = canDecodeWithFormData(
2566 request.headers.get("Content-Type")
2567 );
2568 const actionId = request.headers.get("rsc-action-id");
2569 if (actionId) {
2570 if (!decodeReply || !loadServerAction) {
2571 throw new Error(
2572 "Cannot handle enhanced server action without decodeReply and loadServerAction functions"
2573 );
2574 }
2575 const reply = isFormRequest ? await request.formData() : await request.text();
2576 const actionArgs = await decodeReply(reply, { temporaryReferences });
2577 const action = await loadServerAction(actionId);
2578 const serverAction = action.bind(null, ...actionArgs);
2579 let actionResult = Promise.resolve(serverAction());
2580 try {
2581 await actionResult;
2582 } catch (error) {
2583 if (isResponse(error)) {
2584 return error;
2585 }
2586 onError?.(error);
2587 }
2588 let maybeFormData = actionArgs.length === 1 ? actionArgs[0] : actionArgs[1];
2589 let formData = maybeFormData && typeof maybeFormData === "object" && maybeFormData instanceof FormData ? maybeFormData : null;
2590 let skipRevalidation = formData?.has("$SKIP_REVALIDATION") ?? false;
2591 return {
2592 actionResult,
2593 revalidationRequest: getRevalidationRequest(),
2594 skipRevalidation
2595 };
2596 } else if (isFormRequest) {
2597 const formData = await request.clone().formData();
2598 if (Array.from(formData.keys()).some((k) => k.startsWith("$ACTION_"))) {
2599 if (!decodeAction) {
2600 throw new Error(
2601 "Cannot handle form actions without a decodeAction function"
2602 );
2603 }
2604 const action = await decodeAction(formData);
2605 let formState = void 0;
2606 try {
2607 let result = await action();
2608 if (isRedirectResponse(result)) {
2609 result = prependBasenameToRedirectResponse(result, basename);
2610 }
2611 formState = decodeFormState?.(result, formData);
2612 } catch (error) {
2613 if (isRedirectResponse(error)) {
2614 return prependBasenameToRedirectResponse(error, basename);
2615 }
2616 if (isResponse(error)) {
2617 return error;
2618 }
2619 onError?.(error);
2620 }
2621 return {
2622 formState,
2623 revalidationRequest: getRevalidationRequest(),
2624 skipRevalidation: false
2625 };
2626 }
2627 }
2628}
2629async function generateResourceResponse(request, routes, basename, routeId, requestContext, onError) {
2630 try {
2631 const staticHandler = createStaticHandler(routes, {
2632 basename
2633 });
2634 let response = await staticHandler.queryRoute(request, {
2635 routeId,
2636 requestContext,
2637 async generateMiddlewareResponse(queryRoute) {
2638 try {
2639 let response2 = await queryRoute(request);
2640 return generateResourceResponse2(response2);
2641 } catch (error) {
2642 return generateErrorResponse(error);
2643 }
2644 }
2645 });
2646 return response;
2647 } catch (error) {
2648 return generateErrorResponse(error);
2649 }
2650 function generateErrorResponse(error) {
2651 let response;
2652 if (isResponse(error)) {
2653 response = error;
2654 } else if (isRouteErrorResponse(error)) {
2655 onError?.(error);
2656 const errorMessage = typeof error.data === "string" ? error.data : error.statusText;
2657 response = new Response(errorMessage, {
2658 status: error.status,
2659 statusText: error.statusText
2660 });
2661 } else {
2662 onError?.(error);
2663 response = new Response("Internal Server Error", { status: 500 });
2664 }
2665 return generateResourceResponse2(response);
2666 }
2667 function generateResourceResponse2(response) {
2668 const headers = new Headers(response.headers);
2669 headers.set("React-Router-Resource", "true");
2670 return new Response(response.body, {
2671 status: response.status,
2672 statusText: response.statusText,
2673 headers
2674 });
2675 }
2676}
2677async function generateRenderResponse(request, routes, basename, isDataRequest, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, generateResponse, temporaryReferences) {
2678 let statusCode = 200;
2679 let url = new URL(request.url);
2680 let isSubmission = isMutationMethod(request.method);
2681 let routeIdsToLoad = !isSubmission && url.searchParams.has("_routes") ? url.searchParams.get("_routes").split(",") : null;
2682 const staticHandler = createStaticHandler(routes, {
2683 basename,
2684 mapRouteProperties: (r) => ({
2685 hasErrorBoundary: r.ErrorBoundary != null
2686 })
2687 });
2688 let actionResult;
2689 const ctx = {
2690 runningAction: false
2691 };
2692 const result = await ServerStorage.run(
2693 ctx,
2694 () => staticHandler.query(request, {
2695 requestContext,
2696 skipLoaderErrorBubbling: isDataRequest,
2697 skipRevalidation: isSubmission,
2698 ...routeIdsToLoad ? { filterMatchesToLoad: (m) => routeIdsToLoad.includes(m.route.id) } : {},
2699 async generateMiddlewareResponse(query) {
2700 let formState;
2701 let skipRevalidation = false;
2702 if (request.method === "POST") {
2703 ctx.runningAction = true;
2704 let result2 = await processServerAction(
2705 request,
2706 basename,
2707 decodeReply,
2708 loadServerAction,
2709 decodeAction,
2710 decodeFormState,
2711 onError,
2712 temporaryReferences
2713 );
2714 ctx.runningAction = false;
2715 if (isResponse(result2)) {
2716 return generateRedirectResponse(
2717 result2,
2718 actionResult,
2719 basename,
2720 isDataRequest,
2721 generateResponse,
2722 temporaryReferences,
2723 ctx.redirect?.headers
2724 );
2725 }
2726 skipRevalidation = result2?.skipRevalidation ?? false;
2727 actionResult = result2?.actionResult;
2728 formState = result2?.formState;
2729 request = result2?.revalidationRequest ?? request;
2730 if (ctx.redirect) {
2731 return generateRedirectResponse(
2732 ctx.redirect,
2733 actionResult,
2734 basename,
2735 isDataRequest,
2736 generateResponse,
2737 temporaryReferences,
2738 void 0
2739 );
2740 }
2741 }
2742 let staticContext = await query(
2743 request,
2744 skipRevalidation ? {
2745 filterMatchesToLoad: () => false
2746 } : void 0
2747 );
2748 if (isResponse(staticContext)) {
2749 return generateRedirectResponse(
2750 staticContext,
2751 actionResult,
2752 basename,
2753 isDataRequest,
2754 generateResponse,
2755 temporaryReferences,
2756 ctx.redirect?.headers
2757 );
2758 }
2759 return generateStaticContextResponse(
2760 routes,
2761 basename,
2762 generateResponse,
2763 statusCode,
2764 routeIdsToLoad,
2765 isDataRequest,
2766 isSubmission,
2767 actionResult,
2768 formState,
2769 staticContext,
2770 temporaryReferences,
2771 skipRevalidation,
2772 ctx.redirect?.headers
2773 );
2774 }
2775 })
2776 );
2777 if (isRedirectResponse(result)) {
2778 return generateRedirectResponse(
2779 result,
2780 actionResult,
2781 basename,
2782 isDataRequest,
2783 generateResponse,
2784 temporaryReferences,
2785 ctx.redirect?.headers
2786 );
2787 }
2788 invariant2(isResponse(result), "Expected a response from query");
2789 return result;
2790}
2791function generateRedirectResponse(response, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, sideEffectRedirectHeaders) {
2792 let redirect3 = response.headers.get("Location");
2793 if (isDataRequest && basename) {
2794 redirect3 = stripBasename(redirect3, basename) || redirect3;
2795 }
2796 let payload = {
2797 type: "redirect",
2798 location: redirect3,
2799 reload: response.headers.get("X-Remix-Reload-Document") === "true",
2800 replace: response.headers.get("X-Remix-Replace") === "true",
2801 status: response.status,
2802 actionResult
2803 };
2804 let headers = new Headers(sideEffectRedirectHeaders);
2805 for (const [key, value] of response.headers.entries()) {
2806 headers.append(key, value);
2807 }
2808 headers.delete("Location");
2809 headers.delete("X-Remix-Reload-Document");
2810 headers.delete("X-Remix-Replace");
2811 headers.delete("Content-Length");
2812 headers.set("Content-Type", "text/x-component");
2813 headers.set("Vary", "Content-Type");
2814 return generateResponse(
2815 {
2816 statusCode: SINGLE_FETCH_REDIRECT_STATUS,
2817 headers,
2818 payload
2819 },
2820 { temporaryReferences }
2821 );
2822}
2823async function generateStaticContextResponse(routes, basename, generateResponse, statusCode, routeIdsToLoad, isDataRequest, isSubmission, actionResult, formState, staticContext, temporaryReferences, skipRevalidation, sideEffectRedirectHeaders) {
2824 statusCode = staticContext.statusCode ?? statusCode;
2825 if (staticContext.errors) {
2826 staticContext.errors = Object.fromEntries(
2827 Object.entries(staticContext.errors).map(([key, error]) => [
2828 key,
2829 isRouteErrorResponse(error) ? Object.fromEntries(Object.entries(error)) : error
2830 ])
2831 );
2832 }
2833 staticContext.matches.forEach((m) => {
2834 const routeHasNoLoaderData = staticContext.loaderData[m.route.id] === void 0;
2835 const routeHasError = Boolean(
2836 staticContext.errors && m.route.id in staticContext.errors
2837 );
2838 if (routeHasNoLoaderData && !routeHasError) {
2839 staticContext.loaderData[m.route.id] = null;
2840 }
2841 });
2842 let headers = getDocumentHeadersImpl(
2843 staticContext,
2844 (match) => match.route.headers,
2845 sideEffectRedirectHeaders
2846 );
2847 headers.delete("Content-Length");
2848 const baseRenderPayload = {
2849 type: "render",
2850 basename,
2851 actionData: staticContext.actionData,
2852 errors: staticContext.errors,
2853 loaderData: staticContext.loaderData,
2854 location: staticContext.location,
2855 formState
2856 };
2857 const renderPayloadPromise = () => getRenderPayload(
2858 baseRenderPayload,
2859 routes,
2860 basename,
2861 routeIdsToLoad,
2862 isDataRequest,
2863 staticContext
2864 );
2865 let payload;
2866 if (actionResult) {
2867 payload = {
2868 type: "action",
2869 actionResult,
2870 rerender: skipRevalidation ? void 0 : renderPayloadPromise()
2871 };
2872 } else if (isSubmission && isDataRequest) {
2873 payload = {
2874 ...baseRenderPayload,
2875 matches: [],
2876 patches: []
2877 };
2878 } else {
2879 payload = await renderPayloadPromise();
2880 }
2881 return generateResponse(
2882 {
2883 statusCode,
2884 headers,
2885 payload
2886 },
2887 { temporaryReferences }
2888 );
2889}
2890async function getRenderPayload(baseRenderPayload, routes, basename, routeIdsToLoad, isDataRequest, staticContext) {
2891 let deepestRenderedRouteIdx = staticContext.matches.length - 1;
2892 let parentIds = {};
2893 staticContext.matches.forEach((m, i) => {
2894 if (i > 0) {
2895 parentIds[m.route.id] = staticContext.matches[i - 1].route.id;
2896 }
2897 if (staticContext.errors && m.route.id in staticContext.errors && deepestRenderedRouteIdx > i) {
2898 deepestRenderedRouteIdx = i;
2899 }
2900 });
2901 let matchesPromise = Promise.all(
2902 staticContext.matches.map((match, i) => {
2903 let isBelowErrorBoundary = i > deepestRenderedRouteIdx;
2904 let parentId = parentIds[match.route.id];
2905 return getRSCRouteMatch({
2906 staticContext,
2907 match,
2908 routeIdsToLoad,
2909 isBelowErrorBoundary,
2910 parentId
2911 });
2912 })
2913 );
2914 let patchesPromise = getAdditionalRoutePatches(
2915 [staticContext.location.pathname],
2916 routes,
2917 basename,
2918 staticContext.matches.map((m) => m.route.id)
2919 );
2920 let [matches, patches] = await Promise.all([matchesPromise, patchesPromise]);
2921 return {
2922 ...baseRenderPayload,
2923 matches,
2924 patches
2925 };
2926}
2927async function getRSCRouteMatch({
2928 staticContext,
2929 match,
2930 isBelowErrorBoundary,
2931 routeIdsToLoad,
2932 parentId
2933}) {
2934 await explodeLazyRoute(match.route);
2935 const Layout = match.route.Layout || React2.Fragment;
2936 const Component = match.route.Component;
2937 const ErrorBoundary = match.route.ErrorBoundary;
2938 const HydrateFallback = match.route.HydrateFallback;
2939 const loaderData = staticContext.loaderData[match.route.id];
2940 const actionData = staticContext.actionData?.[match.route.id];
2941 const params = match.params;
2942 let element = void 0;
2943 let shouldLoadRoute = !routeIdsToLoad || routeIdsToLoad.includes(match.route.id);
2944 if (Component && shouldLoadRoute) {
2945 element = !isBelowErrorBoundary ? React2.createElement(
2946 Layout,
2947 null,
2948 isClientReference(Component) ? React2.createElement(WithComponentProps, {
2949 children: React2.createElement(Component)
2950 }) : React2.createElement(Component, {
2951 loaderData,
2952 actionData,
2953 params,
2954 matches: staticContext.matches.map(
2955 (match2) => convertRouteMatchToUiMatch(match2, staticContext.loaderData)
2956 )
2957 })
2958 ) : React2.createElement(Outlet);
2959 }
2960 let error = void 0;
2961 if (ErrorBoundary && staticContext.errors) {
2962 error = staticContext.errors[match.route.id];
2963 }
2964 const errorElement = ErrorBoundary ? React2.createElement(
2965 Layout,
2966 null,
2967 isClientReference(ErrorBoundary) ? React2.createElement(WithErrorBoundaryProps, {
2968 children: React2.createElement(ErrorBoundary)
2969 }) : React2.createElement(ErrorBoundary, {
2970 loaderData,
2971 actionData,
2972 params,
2973 error
2974 })
2975 ) : void 0;
2976 const hydrateFallbackElement = HydrateFallback ? React2.createElement(
2977 Layout,
2978 null,
2979 isClientReference(HydrateFallback) ? React2.createElement(WithHydrateFallbackProps, {
2980 children: React2.createElement(HydrateFallback)
2981 }) : React2.createElement(HydrateFallback, {
2982 loaderData,
2983 actionData,
2984 params
2985 })
2986 ) : void 0;
2987 return {
2988 clientAction: match.route.clientAction,
2989 clientLoader: match.route.clientLoader,
2990 element,
2991 errorElement,
2992 handle: match.route.handle,
2993 hasAction: !!match.route.action,
2994 hasComponent: !!Component,
2995 hasErrorBoundary: !!ErrorBoundary,
2996 hasLoader: !!match.route.loader,
2997 hydrateFallbackElement,
2998 id: match.route.id,
2999 index: match.route.index,
3000 links: match.route.links,
3001 meta: match.route.meta,
3002 params,
3003 parentId,
3004 path: match.route.path,
3005 pathname: match.pathname,
3006 pathnameBase: match.pathnameBase,
3007 shouldRevalidate: match.route.shouldRevalidate,
3008 // Add an unused client-only export (if present) so HMR can support
3009 // switching between server-first and client-only routes during development
3010 ...match.route.__ensureClientRouteModuleForHMR ? {
3011 __ensureClientRouteModuleForHMR: match.route.__ensureClientRouteModuleForHMR
3012 } : {}
3013 };
3014}
3015async function getManifestRoute(route) {
3016 await explodeLazyRoute(route);
3017 const Layout = route.Layout || React2.Fragment;
3018 const errorElement = route.ErrorBoundary ? React2.createElement(
3019 Layout,
3020 null,
3021 React2.createElement(route.ErrorBoundary)
3022 ) : void 0;
3023 return {
3024 clientAction: route.clientAction,
3025 clientLoader: route.clientLoader,
3026 handle: route.handle,
3027 hasAction: !!route.action,
3028 hasComponent: !!route.Component,
3029 hasErrorBoundary: !!route.ErrorBoundary,
3030 errorElement,
3031 hasLoader: !!route.loader,
3032 id: route.id,
3033 parentId: route.parentId,
3034 path: route.path,
3035 index: "index" in route ? route.index : void 0,
3036 links: route.links,
3037 meta: route.meta
3038 };
3039}
3040async function explodeLazyRoute(route) {
3041 if ("lazy" in route && route.lazy) {
3042 let {
3043 default: lazyDefaultExport,
3044 Component: lazyComponentExport,
3045 ...lazyProperties
3046 } = await route.lazy();
3047 let Component = lazyComponentExport || lazyDefaultExport;
3048 if (Component && !route.Component) {
3049 route.Component = Component;
3050 }
3051 for (let [k, v] of Object.entries(lazyProperties)) {
3052 if (k !== "id" && k !== "path" && k !== "index" && k !== "children" && route[k] == null) {
3053 route[k] = v;
3054 }
3055 }
3056 route.lazy = void 0;
3057 }
3058}
3059async function getAdditionalRoutePatches(pathnames, routes, basename, matchedRouteIds) {
3060 let patchRouteMatches = /* @__PURE__ */ new Map();
3061 let matchedPaths = /* @__PURE__ */ new Set();
3062 for (const pathname of pathnames) {
3063 let segments = pathname.split("/").filter(Boolean);
3064 let paths = ["/"];
3065 segments.pop();
3066 while (segments.length > 0) {
3067 paths.push(`/${segments.join("/")}`);
3068 segments.pop();
3069 }
3070 paths.forEach((path) => {
3071 if (matchedPaths.has(path)) {
3072 return;
3073 }
3074 matchedPaths.add(path);
3075 let matches = matchRoutes(routes, path, basename) || [];
3076 matches.forEach((m, i) => {
3077 if (patchRouteMatches.get(m.route.id)) {
3078 return;
3079 }
3080 patchRouteMatches.set(m.route.id, {
3081 ...m.route,
3082 parentId: matches[i - 1]?.route.id
3083 });
3084 });
3085 });
3086 }
3087 let patches = await Promise.all(
3088 [...patchRouteMatches.values()].filter((route) => !matchedRouteIds.some((id) => id === route.id)).map((route) => getManifestRoute(route))
3089 );
3090 return patches;
3091}
3092function isReactServerRequest(url) {
3093 return url.pathname.endsWith(".rsc");
3094}
3095function isManifestRequest(url) {
3096 return url.pathname.endsWith(".manifest");
3097}
3098function isClientReference(x) {
3099 try {
3100 return x.$$typeof === Symbol.for("react.client.reference");
3101 } catch {
3102 return false;
3103 }
3104}
3105function canDecodeWithFormData(contentType) {
3106 if (!contentType) return false;
3107 return contentType.match(/\bapplication\/x-www-form-urlencoded\b/) || contentType.match(/\bmultipart\/form-data\b/);
3108}
3109
3110// lib/href.ts
3111function href(path, ...args) {
3112 let params = args[0];
3113 let result = trimTrailingSplat(path).replace(
3114 /\/:([\w-]+)(\?)?/g,
3115 // same regex as in .\router\utils.ts: compilePath().
3116 (_, param, questionMark) => {
3117 const isRequired = questionMark === void 0;
3118 const value = params?.[param];
3119 if (isRequired && value === void 0) {
3120 throw new Error(
3121 `Path '${path}' requires param '${param}' but it was not provided`
3122 );
3123 }
3124 return value === void 0 ? "" : "/" + value;
3125 }
3126 );
3127 if (path.endsWith("*")) {
3128 const value = params?.["*"];
3129 if (value !== void 0) {
3130 result += "/" + value;
3131 }
3132 }
3133 return result || "/";
3134}
3135function trimTrailingSplat(path) {
3136 let i = path.length - 1;
3137 let char = path[i];
3138 if (char !== "*" && char !== "/") return path;
3139 i--;
3140 for (; i >= 0; i--) {
3141 if (path[i] !== "/") break;
3142 }
3143 return path.slice(0, i + 1);
3144}
3145
3146// lib/server-runtime/crypto.ts
3147var encoder = /* @__PURE__ */ new TextEncoder();
3148var sign = async (value, secret) => {
3149 let data2 = encoder.encode(value);
3150 let key = await createKey2(secret, ["sign"]);
3151 let signature = await crypto.subtle.sign("HMAC", key, data2);
3152 let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(
3153 /=+$/,
3154 ""
3155 );
3156 return value + "." + hash;
3157};
3158var unsign = async (cookie, secret) => {
3159 let index = cookie.lastIndexOf(".");
3160 let value = cookie.slice(0, index);
3161 let hash = cookie.slice(index + 1);
3162 let data2 = encoder.encode(value);
3163 let key = await createKey2(secret, ["verify"]);
3164 try {
3165 let signature = byteStringToUint8Array(atob(hash));
3166 let valid = await crypto.subtle.verify("HMAC", key, signature, data2);
3167 return valid ? value : false;
3168 } catch (error) {
3169 return false;
3170 }
3171};
3172var createKey2 = async (secret, usages) => crypto.subtle.importKey(
3173 "raw",
3174 encoder.encode(secret),
3175 { name: "HMAC", hash: "SHA-256" },
3176 false,
3177 usages
3178);
3179function byteStringToUint8Array(byteString) {
3180 let array = new Uint8Array(byteString.length);
3181 for (let i = 0; i < byteString.length; i++) {
3182 array[i] = byteString.charCodeAt(i);
3183 }
3184 return array;
3185}
3186
3187// lib/server-runtime/warnings.ts
3188var alreadyWarned = {};
3189function warnOnce(condition, message) {
3190 if (!condition && !alreadyWarned[message]) {
3191 alreadyWarned[message] = true;
3192 console.warn(message);
3193 }
3194}
3195
3196// lib/server-runtime/cookies.ts
3197var createCookie = (name, cookieOptions = {}) => {
3198 let { secrets = [], ...options } = {
3199 path: "/",
3200 sameSite: "lax",
3201 ...cookieOptions
3202 };
3203 warnOnceAboutExpiresCookie(name, options.expires);
3204 return {
3205 get name() {
3206 return name;
3207 },
3208 get isSigned() {
3209 return secrets.length > 0;
3210 },
3211 get expires() {
3212 return typeof options.maxAge !== "undefined" ? new Date(Date.now() + options.maxAge * 1e3) : options.expires;
3213 },
3214 async parse(cookieHeader, parseOptions) {
3215 if (!cookieHeader) return null;
3216 let cookies = parse(cookieHeader, { ...options, ...parseOptions });
3217 if (name in cookies) {
3218 let value = cookies[name];
3219 if (typeof value === "string" && value !== "") {
3220 let decoded = await decodeCookieValue(value, secrets);
3221 return decoded;
3222 } else {
3223 return "";
3224 }
3225 } else {
3226 return null;
3227 }
3228 },
3229 async serialize(value, serializeOptions) {
3230 return serialize(
3231 name,
3232 value === "" ? "" : await encodeCookieValue(value, secrets),
3233 {
3234 ...options,
3235 ...serializeOptions
3236 }
3237 );
3238 }
3239 };
3240};
3241var isCookie = (object) => {
3242 return object != null && typeof object.name === "string" && typeof object.isSigned === "boolean" && typeof object.parse === "function" && typeof object.serialize === "function";
3243};
3244async function encodeCookieValue(value, secrets) {
3245 let encoded = encodeData(value);
3246 if (secrets.length > 0) {
3247 encoded = await sign(encoded, secrets[0]);
3248 }
3249 return encoded;
3250}
3251async function decodeCookieValue(value, secrets) {
3252 if (secrets.length > 0) {
3253 for (let secret of secrets) {
3254 let unsignedValue = await unsign(value, secret);
3255 if (unsignedValue !== false) {
3256 return decodeData(unsignedValue);
3257 }
3258 }
3259 return null;
3260 }
3261 return decodeData(value);
3262}
3263function encodeData(value) {
3264 return btoa(myUnescape(encodeURIComponent(JSON.stringify(value))));
3265}
3266function decodeData(value) {
3267 try {
3268 return JSON.parse(decodeURIComponent(myEscape(atob(value))));
3269 } catch (error) {
3270 return {};
3271 }
3272}
3273function myEscape(value) {
3274 let str = value.toString();
3275 let result = "";
3276 let index = 0;
3277 let chr, code;
3278 while (index < str.length) {
3279 chr = str.charAt(index++);
3280 if (/[\w*+\-./@]/.exec(chr)) {
3281 result += chr;
3282 } else {
3283 code = chr.charCodeAt(0);
3284 if (code < 256) {
3285 result += "%" + hex(code, 2);
3286 } else {
3287 result += "%u" + hex(code, 4).toUpperCase();
3288 }
3289 }
3290 }
3291 return result;
3292}
3293function hex(code, length) {
3294 let result = code.toString(16);
3295 while (result.length < length) result = "0" + result;
3296 return result;
3297}
3298function myUnescape(value) {
3299 let str = value.toString();
3300 let result = "";
3301 let index = 0;
3302 let chr, part;
3303 while (index < str.length) {
3304 chr = str.charAt(index++);
3305 if (chr === "%") {
3306 if (str.charAt(index) === "u") {
3307 part = str.slice(index + 1, index + 5);
3308 if (/^[\da-f]{4}$/i.exec(part)) {
3309 result += String.fromCharCode(parseInt(part, 16));
3310 index += 5;
3311 continue;
3312 }
3313 } else {
3314 part = str.slice(index, index + 2);
3315 if (/^[\da-f]{2}$/i.exec(part)) {
3316 result += String.fromCharCode(parseInt(part, 16));
3317 index += 2;
3318 continue;
3319 }
3320 }
3321 }
3322 result += chr;
3323 }
3324 return result;
3325}
3326function warnOnceAboutExpiresCookie(name, expires) {
3327 warnOnce(
3328 !expires,
3329 `The "${name}" cookie has an "expires" property set. This will cause the expires value to not be updated when the session is committed. Instead, you should set the expires value when serializing the cookie. You can use \`commitSession(session, { expires })\` if using a session storage object, or \`cookie.serialize("value", { expires })\` if you're using the cookie directly.`
3330 );
3331}
3332
3333// lib/server-runtime/sessions.ts
3334function flash(name) {
3335 return `__flash_${name}__`;
3336}
3337var createSession = (initialData = {}, id = "") => {
3338 let map = new Map(Object.entries(initialData));
3339 return {
3340 get id() {
3341 return id;
3342 },
3343 get data() {
3344 return Object.fromEntries(map);
3345 },
3346 has(name) {
3347 return map.has(name) || map.has(flash(name));
3348 },
3349 get(name) {
3350 if (map.has(name)) return map.get(name);
3351 let flashName = flash(name);
3352 if (map.has(flashName)) {
3353 let value = map.get(flashName);
3354 map.delete(flashName);
3355 return value;
3356 }
3357 return void 0;
3358 },
3359 set(name, value) {
3360 map.set(name, value);
3361 },
3362 flash(name, value) {
3363 map.set(flash(name), value);
3364 },
3365 unset(name) {
3366 map.delete(name);
3367 }
3368 };
3369};
3370var isSession = (object) => {
3371 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";
3372};
3373function createSessionStorage({
3374 cookie: cookieArg,
3375 createData,
3376 readData,
3377 updateData,
3378 deleteData
3379}) {
3380 let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
3381 warnOnceAboutSigningSessionCookie(cookie);
3382 return {
3383 async getSession(cookieHeader, options) {
3384 let id = cookieHeader && await cookie.parse(cookieHeader, options);
3385 let data2 = id && await readData(id);
3386 return createSession(data2 || {}, id || "");
3387 },
3388 async commitSession(session, options) {
3389 let { id, data: data2 } = session;
3390 let expires = options?.maxAge != null ? new Date(Date.now() + options.maxAge * 1e3) : options?.expires != null ? options.expires : cookie.expires;
3391 if (id) {
3392 await updateData(id, data2, expires);
3393 } else {
3394 id = await createData(data2, expires);
3395 }
3396 return cookie.serialize(id, options);
3397 },
3398 async destroySession(session, options) {
3399 await deleteData(session.id);
3400 return cookie.serialize("", {
3401 ...options,
3402 maxAge: void 0,
3403 expires: /* @__PURE__ */ new Date(0)
3404 });
3405 }
3406 };
3407}
3408function warnOnceAboutSigningSessionCookie(cookie) {
3409 warnOnce(
3410 cookie.isSigned,
3411 `The "${cookie.name}" cookie is not signed, but session cookies should be signed to prevent tampering on the client before they are sent back to the server. See https://reactrouter.com/explanation/sessions-and-cookies#signing-cookies for more information.`
3412 );
3413}
3414
3415// lib/server-runtime/sessions/cookieStorage.ts
3416function createCookieSessionStorage({ cookie: cookieArg } = {}) {
3417 let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
3418 warnOnceAboutSigningSessionCookie(cookie);
3419 return {
3420 async getSession(cookieHeader, options) {
3421 return createSession(
3422 cookieHeader && await cookie.parse(cookieHeader, options) || {}
3423 );
3424 },
3425 async commitSession(session, options) {
3426 let serializedCookie = await cookie.serialize(session.data, options);
3427 if (serializedCookie.length > 4096) {
3428 throw new Error(
3429 "Cookie length will exceed browser maximum. Length: " + serializedCookie.length
3430 );
3431 }
3432 return serializedCookie;
3433 },
3434 async destroySession(_session, options) {
3435 return cookie.serialize("", {
3436 ...options,
3437 maxAge: void 0,
3438 expires: /* @__PURE__ */ new Date(0)
3439 });
3440 }
3441 };
3442}
3443
3444// lib/server-runtime/sessions/memoryStorage.ts
3445function createMemorySessionStorage({ cookie } = {}) {
3446 let map = /* @__PURE__ */ new Map();
3447 return createSessionStorage({
3448 cookie,
3449 async createData(data2, expires) {
3450 let id = Math.random().toString(36).substring(2, 10);
3451 map.set(id, { data: data2, expires });
3452 return id;
3453 },
3454 async readData(id) {
3455 if (map.has(id)) {
3456 let { data: data2, expires } = map.get(id);
3457 if (!expires || expires > /* @__PURE__ */ new Date()) {
3458 return data2;
3459 }
3460 if (expires) map.delete(id);
3461 }
3462 return null;
3463 },
3464 async updateData(id, data2, expires) {
3465 map.set(id, { data: data2, expires });
3466 },
3467 async deleteData(id) {
3468 map.delete(id);
3469 }
3470 });
3471}
3472
3473export { Await, RouterContextProvider, createContext, createCookie, createCookieSessionStorage, createMemorySessionStorage, createSession, createSessionStorage, createStaticHandler, data, href, isCookie, isRouteErrorResponse, isSession, matchRoutes, redirect2 as redirect, redirectDocument2 as redirectDocument, replace2 as replace, matchRSCServerRequest as unstable_matchRSCServerRequest };