UNPKG

116 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.13.1
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, unstable_mask) {
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 unstable_mask
56 };
57 return location;
58}
59function createPath({
60 pathname = "/",
61 search = "",
62 hash = ""
63}) {
64 if (search && search !== "?")
65 pathname += search.charAt(0) === "?" ? search : "?" + search;
66 if (hash && hash !== "#")
67 pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
68 return pathname;
69}
70function parsePath(path) {
71 let parsedPath = {};
72 if (path) {
73 let hashIndex = path.indexOf("#");
74 if (hashIndex >= 0) {
75 parsedPath.hash = path.substring(hashIndex);
76 path = path.substring(0, hashIndex);
77 }
78 let searchIndex = path.indexOf("?");
79 if (searchIndex >= 0) {
80 parsedPath.search = path.substring(searchIndex);
81 path = path.substring(0, searchIndex);
82 }
83 if (path) {
84 parsedPath.pathname = path;
85 }
86 }
87 return parsedPath;
88}
89
90// lib/router/instrumentation.ts
91var UninstrumentedSymbol = Symbol("Uninstrumented");
92function getRouteInstrumentationUpdates(fns, route) {
93 let aggregated = {
94 lazy: [],
95 "lazy.loader": [],
96 "lazy.action": [],
97 "lazy.middleware": [],
98 middleware: [],
99 loader: [],
100 action: []
101 };
102 fns.forEach(
103 (fn) => fn({
104 id: route.id,
105 index: route.index,
106 path: route.path,
107 instrument(i) {
108 let keys = Object.keys(aggregated);
109 for (let key of keys) {
110 if (i[key]) {
111 aggregated[key].push(i[key]);
112 }
113 }
114 }
115 })
116 );
117 let updates = {};
118 if (typeof route.lazy === "function" && aggregated.lazy.length > 0) {
119 let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0);
120 if (instrumented) {
121 updates.lazy = instrumented;
122 }
123 }
124 if (typeof route.lazy === "object") {
125 let lazyObject = route.lazy;
126 ["middleware", "loader", "action"].forEach((key) => {
127 let lazyFn = lazyObject[key];
128 let instrumentations = aggregated[`lazy.${key}`];
129 if (typeof lazyFn === "function" && instrumentations.length > 0) {
130 let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);
131 if (instrumented) {
132 updates.lazy = Object.assign(updates.lazy || {}, {
133 [key]: instrumented
134 });
135 }
136 }
137 });
138 }
139 ["loader", "action"].forEach((key) => {
140 let handler = route[key];
141 if (typeof handler === "function" && aggregated[key].length > 0) {
142 let original = handler[UninstrumentedSymbol] ?? handler;
143 let instrumented = wrapImpl(
144 aggregated[key],
145 original,
146 (...args) => getHandlerInfo(args[0])
147 );
148 if (instrumented) {
149 if (key === "loader" && original.hydrate === true) {
150 instrumented.hydrate = true;
151 }
152 instrumented[UninstrumentedSymbol] = original;
153 updates[key] = instrumented;
154 }
155 }
156 });
157 if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) {
158 updates.middleware = route.middleware.map((middleware) => {
159 let original = middleware[UninstrumentedSymbol] ?? middleware;
160 let instrumented = wrapImpl(
161 aggregated.middleware,
162 original,
163 (...args) => getHandlerInfo(args[0])
164 );
165 if (instrumented) {
166 instrumented[UninstrumentedSymbol] = original;
167 return instrumented;
168 }
169 return middleware;
170 });
171 }
172 return updates;
173}
174function wrapImpl(impls, handler, getInfo) {
175 if (impls.length === 0) {
176 return null;
177 }
178 return async (...args) => {
179 let result = await recurseRight(
180 impls,
181 getInfo(...args),
182 () => handler(...args),
183 impls.length - 1
184 );
185 if (result.type === "error") {
186 throw result.value;
187 }
188 return result.value;
189 };
190}
191async function recurseRight(impls, info, handler, index) {
192 let impl = impls[index];
193 let result;
194 if (!impl) {
195 try {
196 let value = await handler();
197 result = { type: "success", value };
198 } catch (e) {
199 result = { type: "error", value: e };
200 }
201 } else {
202 let handlerPromise = void 0;
203 let callHandler = async () => {
204 if (handlerPromise) {
205 console.error("You cannot call instrumented handlers more than once");
206 } else {
207 handlerPromise = recurseRight(impls, info, handler, index - 1);
208 }
209 result = await handlerPromise;
210 invariant(result, "Expected a result");
211 if (result.type === "error" && result.value instanceof Error) {
212 return { status: "error", error: result.value };
213 }
214 return { status: "success", error: void 0 };
215 };
216 try {
217 await impl(callHandler, info);
218 } catch (e) {
219 console.error("An instrumentation function threw an error:", e);
220 }
221 if (!handlerPromise) {
222 await callHandler();
223 }
224 await handlerPromise;
225 }
226 if (result) {
227 return result;
228 }
229 return {
230 type: "error",
231 value: new Error("No result assigned in instrumentation chain.")
232 };
233}
234function getHandlerInfo(args) {
235 let { request, context, params, unstable_pattern } = args;
236 return {
237 request: getReadonlyRequest(request),
238 params: { ...params },
239 unstable_pattern,
240 context: getReadonlyContext(context)
241 };
242}
243function getReadonlyRequest(request) {
244 return {
245 method: request.method,
246 url: request.url,
247 headers: {
248 get: (...args) => request.headers.get(...args)
249 }
250 };
251}
252function getReadonlyContext(context) {
253 if (isPlainObject(context)) {
254 let frozen = { ...context };
255 Object.freeze(frozen);
256 return frozen;
257 } else {
258 return {
259 get: (ctx) => context.get(ctx)
260 };
261 }
262}
263var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
264function isPlainObject(thing) {
265 if (thing === null || typeof thing !== "object") {
266 return false;
267 }
268 const proto = Object.getPrototypeOf(thing);
269 return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
270}
271
272// lib/router/utils.ts
273function createContext(defaultValue) {
274 return { defaultValue };
275}
276var _map;
277var RouterContextProvider = class {
278 /**
279 * Create a new `RouterContextProvider` instance
280 * @param init An optional initial context map to populate the provider with
281 */
282 constructor(init) {
283 __privateAdd(this, _map, /* @__PURE__ */ new Map());
284 if (init) {
285 for (let [context, value] of init) {
286 this.set(context, value);
287 }
288 }
289 }
290 /**
291 * Access a value from the context. If no value has been set for the context,
292 * it will return the context's `defaultValue` if provided, or throw an error
293 * if no `defaultValue` was set.
294 * @param context The context to get the value for
295 * @returns The value for the context, or the context's `defaultValue` if no
296 * value was set
297 */
298 get(context) {
299 if (__privateGet(this, _map).has(context)) {
300 return __privateGet(this, _map).get(context);
301 }
302 if (context.defaultValue !== void 0) {
303 return context.defaultValue;
304 }
305 throw new Error("No value found for context");
306 }
307 /**
308 * Set a value for the context. If the context already has a value set, this
309 * will overwrite it.
310 *
311 * @param context The context to set the value for
312 * @param value The value to set for the context
313 * @returns {void}
314 */
315 set(context, value) {
316 __privateGet(this, _map).set(context, value);
317 }
318};
319_map = new WeakMap();
320var unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([
321 "lazy",
322 "caseSensitive",
323 "path",
324 "id",
325 "index",
326 "children"
327]);
328function isUnsupportedLazyRouteObjectKey(key) {
329 return unsupportedLazyRouteObjectKeys.has(
330 key
331 );
332}
333var unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([
334 "lazy",
335 "caseSensitive",
336 "path",
337 "id",
338 "index",
339 "middleware",
340 "children"
341]);
342function isUnsupportedLazyRouteFunctionKey(key) {
343 return unsupportedLazyRouteFunctionKeys.has(
344 key
345 );
346}
347function isIndexRoute(route) {
348 return route.index === true;
349}
350function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath = [], manifest = {}, allowInPlaceMutations = false) {
351 return routes.map((route, index) => {
352 let treePath = [...parentPath, String(index)];
353 let id = typeof route.id === "string" ? route.id : treePath.join("-");
354 invariant(
355 route.index !== true || !route.children,
356 `Cannot specify children on an index route`
357 );
358 invariant(
359 allowInPlaceMutations || !manifest[id],
360 `Found a route id collision on id "${id}". Route id's must be globally unique within Data Router usages`
361 );
362 if (isIndexRoute(route)) {
363 let indexRoute = {
364 ...route,
365 id
366 };
367 manifest[id] = mergeRouteUpdates(
368 indexRoute,
369 mapRouteProperties(indexRoute)
370 );
371 return indexRoute;
372 } else {
373 let pathOrLayoutRoute = {
374 ...route,
375 id,
376 children: void 0
377 };
378 manifest[id] = mergeRouteUpdates(
379 pathOrLayoutRoute,
380 mapRouteProperties(pathOrLayoutRoute)
381 );
382 if (route.children) {
383 pathOrLayoutRoute.children = convertRoutesToDataRoutes(
384 route.children,
385 mapRouteProperties,
386 treePath,
387 manifest,
388 allowInPlaceMutations
389 );
390 }
391 return pathOrLayoutRoute;
392 }
393 });
394}
395function mergeRouteUpdates(route, updates) {
396 return Object.assign(route, {
397 ...updates,
398 ...typeof updates.lazy === "object" && updates.lazy != null ? {
399 lazy: {
400 ...route.lazy,
401 ...updates.lazy
402 }
403 } : {}
404 });
405}
406function matchRoutes(routes, locationArg, basename = "/") {
407 return matchRoutesImpl(routes, locationArg, basename, false);
408}
409function matchRoutesImpl(routes, locationArg, basename, allowPartial) {
410 let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
411 let pathname = stripBasename(location.pathname || "/", basename);
412 if (pathname == null) {
413 return null;
414 }
415 let branches = flattenRoutes(routes);
416 rankRouteBranches(branches);
417 let matches = null;
418 for (let i = 0; matches == null && i < branches.length; ++i) {
419 let decoded = decodePath(pathname);
420 matches = matchRouteBranch(
421 branches[i],
422 decoded,
423 allowPartial
424 );
425 }
426 return matches;
427}
428function convertRouteMatchToUiMatch(match, loaderData) {
429 let { route, pathname, params } = match;
430 return {
431 id: route.id,
432 pathname,
433 params,
434 data: loaderData[route.id],
435 loaderData: loaderData[route.id],
436 handle: route.handle
437 };
438}
439function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) {
440 let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => {
441 let meta = {
442 relativePath: relativePath === void 0 ? route.path || "" : relativePath,
443 caseSensitive: route.caseSensitive === true,
444 childrenIndex: index,
445 route
446 };
447 if (meta.relativePath.startsWith("/")) {
448 if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {
449 return;
450 }
451 invariant(
452 meta.relativePath.startsWith(parentPath),
453 `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.`
454 );
455 meta.relativePath = meta.relativePath.slice(parentPath.length);
456 }
457 let path = joinPaths([parentPath, meta.relativePath]);
458 let routesMeta = parentsMeta.concat(meta);
459 if (route.children && route.children.length > 0) {
460 invariant(
461 // Our types know better, but runtime JS may not!
462 // @ts-expect-error
463 route.index !== true,
464 `Index routes must not have child routes. Please remove all child routes from route path "${path}".`
465 );
466 flattenRoutes(
467 route.children,
468 branches,
469 routesMeta,
470 path,
471 hasParentOptionalSegments
472 );
473 }
474 if (route.path == null && !route.index) {
475 return;
476 }
477 branches.push({
478 path,
479 score: computeScore(path, route.index),
480 routesMeta
481 });
482 };
483 routes.forEach((route, index) => {
484 if (route.path === "" || !route.path?.includes("?")) {
485 flattenRoute(route, index);
486 } else {
487 for (let exploded of explodeOptionalSegments(route.path)) {
488 flattenRoute(route, index, true, exploded);
489 }
490 }
491 });
492 return branches;
493}
494function explodeOptionalSegments(path) {
495 let segments = path.split("/");
496 if (segments.length === 0) return [];
497 let [first, ...rest] = segments;
498 let isOptional = first.endsWith("?");
499 let required = first.replace(/\?$/, "");
500 if (rest.length === 0) {
501 return isOptional ? [required, ""] : [required];
502 }
503 let restExploded = explodeOptionalSegments(rest.join("/"));
504 let result = [];
505 result.push(
506 ...restExploded.map(
507 (subpath) => subpath === "" ? required : [required, subpath].join("/")
508 )
509 );
510 if (isOptional) {
511 result.push(...restExploded);
512 }
513 return result.map(
514 (exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded
515 );
516}
517function rankRouteBranches(branches) {
518 branches.sort(
519 (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(
520 a.routesMeta.map((meta) => meta.childrenIndex),
521 b.routesMeta.map((meta) => meta.childrenIndex)
522 )
523 );
524}
525var paramRe = /^:[\w-]+$/;
526var dynamicSegmentValue = 3;
527var indexRouteValue = 2;
528var emptySegmentValue = 1;
529var staticSegmentValue = 10;
530var splatPenalty = -2;
531var isSplat = (s) => s === "*";
532function computeScore(path, index) {
533 let segments = path.split("/");
534 let initialScore = segments.length;
535 if (segments.some(isSplat)) {
536 initialScore += splatPenalty;
537 }
538 if (index) {
539 initialScore += indexRouteValue;
540 }
541 return segments.filter((s) => !isSplat(s)).reduce(
542 (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue),
543 initialScore
544 );
545}
546function compareIndexes(a, b) {
547 let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
548 return siblings ? (
549 // If two routes are siblings, we should try to match the earlier sibling
550 // first. This allows people to have fine-grained control over the matching
551 // behavior by simply putting routes with identical paths in the order they
552 // want them tried.
553 a[a.length - 1] - b[b.length - 1]
554 ) : (
555 // Otherwise, it doesn't really make sense to rank non-siblings by index,
556 // so they sort equally.
557 0
558 );
559}
560function matchRouteBranch(branch, pathname, allowPartial = false) {
561 let { routesMeta } = branch;
562 let matchedParams = {};
563 let matchedPathname = "/";
564 let matches = [];
565 for (let i = 0; i < routesMeta.length; ++i) {
566 let meta = routesMeta[i];
567 let end = i === routesMeta.length - 1;
568 let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
569 let match = matchPath(
570 { path: meta.relativePath, caseSensitive: meta.caseSensitive, end },
571 remainingPathname
572 );
573 let route = meta.route;
574 if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {
575 match = matchPath(
576 {
577 path: meta.relativePath,
578 caseSensitive: meta.caseSensitive,
579 end: false
580 },
581 remainingPathname
582 );
583 }
584 if (!match) {
585 return null;
586 }
587 Object.assign(matchedParams, match.params);
588 matches.push({
589 // TODO: Can this as be avoided?
590 params: matchedParams,
591 pathname: joinPaths([matchedPathname, match.pathname]),
592 pathnameBase: normalizePathname(
593 joinPaths([matchedPathname, match.pathnameBase])
594 ),
595 route
596 });
597 if (match.pathnameBase !== "/") {
598 matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
599 }
600 }
601 return matches;
602}
603function matchPath(pattern, pathname) {
604 if (typeof pattern === "string") {
605 pattern = { path: pattern, caseSensitive: false, end: true };
606 }
607 let [matcher, compiledParams] = compilePath(
608 pattern.path,
609 pattern.caseSensitive,
610 pattern.end
611 );
612 let match = pathname.match(matcher);
613 if (!match) return null;
614 let matchedPathname = match[0];
615 let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
616 let captureGroups = match.slice(1);
617 let params = compiledParams.reduce(
618 (memo, { paramName, isOptional }, index) => {
619 if (paramName === "*") {
620 let splatValue = captureGroups[index] || "";
621 pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
622 }
623 const value = captureGroups[index];
624 if (isOptional && !value) {
625 memo[paramName] = void 0;
626 } else {
627 memo[paramName] = (value || "").replace(/%2F/g, "/");
628 }
629 return memo;
630 },
631 {}
632 );
633 return {
634 params,
635 pathname: matchedPathname,
636 pathnameBase,
637 pattern
638 };
639}
640function compilePath(path, caseSensitive = false, end = true) {
641 warning(
642 path === "*" || !path.endsWith("*") || path.endsWith("/*"),
643 `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(/\*$/, "/*")}".`
644 );
645 let params = [];
646 let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(
647 /\/:([\w-]+)(\?)?/g,
648 (match, paramName, isOptional, index, str) => {
649 params.push({ paramName, isOptional: isOptional != null });
650 if (isOptional) {
651 let nextChar = str.charAt(index + match.length);
652 if (nextChar && nextChar !== "/") {
653 return "/([^\\/]*)";
654 }
655 return "(?:/([^\\/]*))?";
656 }
657 return "/([^\\/]+)";
658 }
659 ).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2");
660 if (path.endsWith("*")) {
661 params.push({ paramName: "*" });
662 regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
663 } else if (end) {
664 regexpSource += "\\/*$";
665 } else if (path !== "" && path !== "/") {
666 regexpSource += "(?:(?=\\/|$))";
667 } else ;
668 let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
669 return [matcher, params];
670}
671function decodePath(value) {
672 try {
673 return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
674 } catch (error) {
675 warning(
676 false,
677 `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}).`
678 );
679 return value;
680 }
681}
682function stripBasename(pathname, basename) {
683 if (basename === "/") return pathname;
684 if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
685 return null;
686 }
687 let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
688 let nextChar = pathname.charAt(startIndex);
689 if (nextChar && nextChar !== "/") {
690 return null;
691 }
692 return pathname.slice(startIndex) || "/";
693}
694function prependBasename({
695 basename,
696 pathname
697}) {
698 return pathname === "/" ? basename : joinPaths([basename, pathname]);
699}
700var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
701var isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);
702function resolvePath(to, fromPathname = "/") {
703 let {
704 pathname: toPathname,
705 search = "",
706 hash = ""
707 } = typeof to === "string" ? parsePath(to) : to;
708 let pathname;
709 if (toPathname) {
710 toPathname = toPathname.replace(/\/\/+/g, "/");
711 if (toPathname.startsWith("/")) {
712 pathname = resolvePathname(toPathname.substring(1), "/");
713 } else {
714 pathname = resolvePathname(toPathname, fromPathname);
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, callSiteDefaultShouldRevalidate) {
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;
2375
2376// lib/actions.ts
2377function throwIfPotentialCSRFAttack(headers, allowedActionOrigins) {
2378 let originHeader = headers.get("origin");
2379 let originDomain = null;
2380 try {
2381 originDomain = typeof originHeader === "string" && originHeader !== "null" ? new URL(originHeader).host : originHeader;
2382 } catch {
2383 throw new Error(
2384 `\`origin\` header is not a valid URL. Aborting the action.`
2385 );
2386 }
2387 let host = parseHostHeader(headers);
2388 if (originDomain && (!host || originDomain !== host.value)) {
2389 if (!isAllowedOrigin(originDomain, allowedActionOrigins)) {
2390 if (host) {
2391 throw new Error(
2392 `${host.type} header does not match \`origin\` header from a forwarded action request. Aborting the action.`
2393 );
2394 } else {
2395 throw new Error(
2396 "`x-forwarded-host` or `host` headers are not provided. One of these is needed to compare the `origin` header from a forwarded action request. Aborting the action."
2397 );
2398 }
2399 }
2400 }
2401}
2402function matchWildcardDomain(domain, pattern) {
2403 const domainParts = domain.split(".");
2404 const patternParts = pattern.split(".");
2405 if (patternParts.length < 1) {
2406 return false;
2407 }
2408 if (domainParts.length < patternParts.length) {
2409 return false;
2410 }
2411 while (patternParts.length) {
2412 const patternPart = patternParts.pop();
2413 const domainPart = domainParts.pop();
2414 switch (patternPart) {
2415 case "": {
2416 return false;
2417 }
2418 case "*": {
2419 if (domainPart) {
2420 continue;
2421 } else {
2422 return false;
2423 }
2424 }
2425 case "**": {
2426 if (patternParts.length > 0) {
2427 return false;
2428 }
2429 return domainPart !== void 0;
2430 }
2431 case void 0:
2432 default: {
2433 if (domainPart !== patternPart) {
2434 return false;
2435 }
2436 }
2437 }
2438 }
2439 return domainParts.length === 0;
2440}
2441function isAllowedOrigin(originDomain, allowedActionOrigins = []) {
2442 return allowedActionOrigins.some(
2443 (allowedOrigin) => allowedOrigin && (allowedOrigin === originDomain || matchWildcardDomain(originDomain, allowedOrigin))
2444 );
2445}
2446function parseHostHeader(headers) {
2447 let forwardedHostHeader = headers.get("x-forwarded-host");
2448 let forwardedHostValue = forwardedHostHeader?.split(",")[0]?.trim();
2449 let hostHeader = headers.get("host");
2450 return forwardedHostValue ? {
2451 type: "x-forwarded-host",
2452 value: forwardedHostValue
2453 } : hostHeader ? {
2454 type: "host",
2455 value: hostHeader
2456 } : void 0;
2457}
2458
2459// lib/errors.ts
2460var ERROR_DIGEST_BASE = "REACT_ROUTER_ERROR";
2461var ERROR_DIGEST_REDIRECT = "REDIRECT";
2462var ERROR_DIGEST_ROUTE_ERROR_RESPONSE = "ROUTE_ERROR_RESPONSE";
2463function createRedirectErrorDigest(response) {
2464 return `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:${JSON.stringify({
2465 status: response.status,
2466 statusText: response.statusText,
2467 location: response.headers.get("Location"),
2468 reloadDocument: response.headers.get("X-Remix-Reload-Document") === "true",
2469 replace: response.headers.get("X-Remix-Replace") === "true"
2470 })}`;
2471}
2472function createRouteErrorResponseDigest(response) {
2473 let status = 500;
2474 let statusText = "";
2475 let data2;
2476 if (isDataWithResponseInit(response)) {
2477 status = response.init?.status ?? status;
2478 statusText = response.init?.statusText ?? statusText;
2479 data2 = response.data;
2480 } else {
2481 status = response.status;
2482 statusText = response.statusText;
2483 data2 = void 0;
2484 }
2485 return `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:${JSON.stringify(
2486 {
2487 status,
2488 statusText,
2489 data: data2
2490 }
2491 )}`;
2492}
2493
2494// lib/rsc/server.rsc.ts
2495var Outlet = Outlet$1;
2496var WithComponentProps = UNSAFE_WithComponentProps;
2497var WithErrorBoundaryProps = UNSAFE_WithErrorBoundaryProps;
2498var WithHydrateFallbackProps = UNSAFE_WithHydrateFallbackProps;
2499var globalVar = typeof globalThis !== "undefined" ? globalThis : global;
2500var ServerStorage = globalVar.___reactRouterServerStorage___ ?? (globalVar.___reactRouterServerStorage___ = new AsyncLocalStorage());
2501function getRequest() {
2502 const ctx = ServerStorage.getStore();
2503 if (!ctx)
2504 throw new Error(
2505 "getRequest must be called from within a React Server render context"
2506 );
2507 return ctx.request;
2508}
2509var redirect2 = (...args) => {
2510 const response = redirect(...args);
2511 const ctx = ServerStorage.getStore();
2512 if (ctx && ctx.runningAction) {
2513 ctx.redirect = response;
2514 }
2515 return response;
2516};
2517var redirectDocument2 = (...args) => {
2518 const response = redirectDocument(...args);
2519 const ctx = ServerStorage.getStore();
2520 if (ctx && ctx.runningAction) {
2521 ctx.redirect = response;
2522 }
2523 return response;
2524};
2525var replace2 = (...args) => {
2526 const response = replace(...args);
2527 const ctx = ServerStorage.getStore();
2528 if (ctx && ctx.runningAction) {
2529 ctx.redirect = response;
2530 }
2531 return response;
2532};
2533var cachedResolvePromise = (
2534 // @ts-expect-error - on 18 types, requires 19.
2535 React2.cache(async (resolve) => {
2536 return Promise.allSettled([resolve]).then((r) => r[0]);
2537 })
2538);
2539var Await = async ({
2540 children,
2541 resolve,
2542 errorElement
2543}) => {
2544 let promise = cachedResolvePromise(resolve);
2545 let resolved = await promise;
2546 if (resolved.status === "rejected" && !errorElement) {
2547 throw resolved.reason;
2548 }
2549 if (resolved.status === "rejected") {
2550 return React2.createElement(UNSAFE_AwaitContextProvider, {
2551 children: React2.createElement(React2.Fragment, null, errorElement),
2552 value: { _tracked: true, _error: resolved.reason }
2553 });
2554 }
2555 const toRender = typeof children === "function" ? children(resolved.value) : children;
2556 return React2.createElement(UNSAFE_AwaitContextProvider, {
2557 children: toRender,
2558 value: { _tracked: true, _data: resolved.value }
2559 });
2560};
2561async function matchRSCServerRequest({
2562 allowedActionOrigins,
2563 createTemporaryReferenceSet,
2564 basename,
2565 decodeReply,
2566 requestContext,
2567 loadServerAction,
2568 decodeAction,
2569 decodeFormState,
2570 onError,
2571 request,
2572 routes,
2573 generateResponse
2574}) {
2575 let url = new URL(request.url);
2576 basename = basename || "/";
2577 let normalizedPath = url.pathname;
2578 if (url.pathname.endsWith("/_.rsc")) {
2579 normalizedPath = url.pathname.replace(/_\.rsc$/, "");
2580 } else if (url.pathname.endsWith(".rsc")) {
2581 normalizedPath = url.pathname.replace(/\.rsc$/, "");
2582 }
2583 if (stripBasename(normalizedPath, basename) !== "/" && normalizedPath.endsWith("/")) {
2584 normalizedPath = normalizedPath.slice(0, -1);
2585 }
2586 url.pathname = normalizedPath;
2587 basename = basename.length > normalizedPath.length ? normalizedPath : basename;
2588 let routerRequest = new Request(url.toString(), {
2589 method: request.method,
2590 headers: request.headers,
2591 body: request.body,
2592 signal: request.signal,
2593 duplex: request.body ? "half" : void 0
2594 });
2595 const temporaryReferences = createTemporaryReferenceSet();
2596 const requestUrl = new URL(request.url);
2597 if (isManifestRequest(requestUrl)) {
2598 let response2 = await generateManifestResponse(
2599 routes,
2600 basename,
2601 request,
2602 generateResponse,
2603 temporaryReferences
2604 );
2605 return response2;
2606 }
2607 let isDataRequest = isReactServerRequest(requestUrl);
2608 let matches = matchRoutes(routes, url.pathname, basename);
2609 if (matches) {
2610 await Promise.all(matches.map((m) => explodeLazyRoute(m.route)));
2611 }
2612 const leafMatch = matches?.[matches.length - 1];
2613 if (!isDataRequest && leafMatch && !leafMatch.route.Component && !leafMatch.route.ErrorBoundary) {
2614 return generateResourceResponse(
2615 routerRequest,
2616 routes,
2617 basename,
2618 leafMatch.route.id,
2619 requestContext,
2620 onError
2621 );
2622 }
2623 let response = await generateRenderResponse(
2624 routerRequest,
2625 routes,
2626 basename,
2627 isDataRequest,
2628 decodeReply,
2629 requestContext,
2630 loadServerAction,
2631 decodeAction,
2632 decodeFormState,
2633 onError,
2634 generateResponse,
2635 temporaryReferences,
2636 allowedActionOrigins
2637 );
2638 response.headers.set("X-Remix-Response", "yes");
2639 return response;
2640}
2641async function generateManifestResponse(routes, basename, request, generateResponse, temporaryReferences) {
2642 let url = new URL(request.url);
2643 let pathParam = url.searchParams.get("paths");
2644 let pathnames = pathParam ? pathParam.split(",").filter(Boolean) : [url.pathname.replace(/\.manifest$/, "")];
2645 let routeIds = /* @__PURE__ */ new Set();
2646 let matchedRoutes = pathnames.flatMap((pathname) => {
2647 let pathnameMatches = matchRoutes(routes, pathname, basename);
2648 return pathnameMatches?.map((m, i) => ({
2649 ...m.route,
2650 parentId: pathnameMatches[i - 1]?.route.id
2651 })) ?? [];
2652 }).filter((route) => {
2653 if (!routeIds.has(route.id)) {
2654 routeIds.add(route.id);
2655 return true;
2656 }
2657 return false;
2658 });
2659 let payload = {
2660 type: "manifest",
2661 patches: (await Promise.all([
2662 ...matchedRoutes.map((route) => getManifestRoute(route)),
2663 getAdditionalRoutePatches(
2664 pathnames,
2665 routes,
2666 basename,
2667 Array.from(routeIds)
2668 )
2669 ])).flat(1)
2670 };
2671 return generateResponse(
2672 {
2673 statusCode: 200,
2674 headers: new Headers({
2675 "Content-Type": "text/x-component",
2676 Vary: "Content-Type"
2677 }),
2678 payload
2679 },
2680 { temporaryReferences, onError: defaultOnError }
2681 );
2682}
2683function prependBasenameToRedirectResponse(response, basename = "/") {
2684 if (basename === "/") {
2685 return response;
2686 }
2687 let redirect3 = response.headers.get("Location");
2688 if (!redirect3 || isAbsoluteUrl(redirect3)) {
2689 return response;
2690 }
2691 response.headers.set(
2692 "Location",
2693 prependBasename({ basename, pathname: redirect3 })
2694 );
2695 return response;
2696}
2697async function processServerAction(request, basename, decodeReply, loadServerAction, decodeAction, decodeFormState, onError, temporaryReferences) {
2698 const getRevalidationRequest = () => new Request(request.url, {
2699 method: "GET",
2700 headers: request.headers,
2701 signal: request.signal
2702 });
2703 const isFormRequest = canDecodeWithFormData(
2704 request.headers.get("Content-Type")
2705 );
2706 const actionId = request.headers.get("rsc-action-id");
2707 if (actionId) {
2708 if (!decodeReply || !loadServerAction) {
2709 throw new Error(
2710 "Cannot handle enhanced server action without decodeReply and loadServerAction functions"
2711 );
2712 }
2713 const reply = isFormRequest ? await request.formData() : await request.text();
2714 const actionArgs = await decodeReply(reply, { temporaryReferences });
2715 const action = await loadServerAction(actionId);
2716 const serverAction = action.bind(null, ...actionArgs);
2717 let actionResult = Promise.resolve(serverAction());
2718 try {
2719 await actionResult;
2720 } catch (error) {
2721 if (isResponse(error)) {
2722 return error;
2723 }
2724 onError?.(error);
2725 }
2726 let maybeFormData = actionArgs.length === 1 ? actionArgs[0] : actionArgs[1];
2727 let formData = maybeFormData && typeof maybeFormData === "object" && maybeFormData instanceof FormData ? maybeFormData : null;
2728 let skipRevalidation = formData?.has("$SKIP_REVALIDATION") ?? false;
2729 return {
2730 actionResult,
2731 revalidationRequest: getRevalidationRequest(),
2732 skipRevalidation
2733 };
2734 } else if (isFormRequest) {
2735 const formData = await request.clone().formData();
2736 if (Array.from(formData.keys()).some((k) => k.startsWith("$ACTION_"))) {
2737 if (!decodeAction) {
2738 throw new Error(
2739 "Cannot handle form actions without a decodeAction function"
2740 );
2741 }
2742 const action = await decodeAction(formData);
2743 let formState = void 0;
2744 try {
2745 let result = await action();
2746 if (isRedirectResponse(result)) {
2747 result = prependBasenameToRedirectResponse(result, basename);
2748 }
2749 formState = decodeFormState?.(result, formData);
2750 } catch (error) {
2751 if (isRedirectResponse(error)) {
2752 return prependBasenameToRedirectResponse(error, basename);
2753 }
2754 if (isResponse(error)) {
2755 return error;
2756 }
2757 onError?.(error);
2758 }
2759 return {
2760 formState,
2761 revalidationRequest: getRevalidationRequest(),
2762 skipRevalidation: false
2763 };
2764 }
2765 }
2766}
2767async function generateResourceResponse(request, routes, basename, routeId, requestContext, onError) {
2768 try {
2769 const staticHandler = createStaticHandler(routes, {
2770 basename
2771 });
2772 let response = await staticHandler.queryRoute(request, {
2773 routeId,
2774 requestContext,
2775 async generateMiddlewareResponse(queryRoute) {
2776 try {
2777 let response2 = await queryRoute(request);
2778 return generateResourceResponse2(response2);
2779 } catch (error) {
2780 return generateErrorResponse(error);
2781 }
2782 }
2783 });
2784 return response;
2785 } catch (error) {
2786 return generateErrorResponse(error);
2787 }
2788 function generateErrorResponse(error) {
2789 let response;
2790 if (isResponse(error)) {
2791 response = error;
2792 } else if (isRouteErrorResponse(error)) {
2793 onError?.(error);
2794 const errorMessage = typeof error.data === "string" ? error.data : error.statusText;
2795 response = new Response(errorMessage, {
2796 status: error.status,
2797 statusText: error.statusText
2798 });
2799 } else {
2800 onError?.(error);
2801 response = new Response("Internal Server Error", { status: 500 });
2802 }
2803 return generateResourceResponse2(response);
2804 }
2805 function generateResourceResponse2(response) {
2806 const headers = new Headers(response.headers);
2807 headers.set("React-Router-Resource", "true");
2808 return new Response(response.body, {
2809 status: response.status,
2810 statusText: response.statusText,
2811 headers
2812 });
2813 }
2814}
2815async function generateRenderResponse(request, routes, basename, isDataRequest, decodeReply, requestContext, loadServerAction, decodeAction, decodeFormState, onError, generateResponse, temporaryReferences, allowedActionOrigins) {
2816 let statusCode = 200;
2817 let url = new URL(request.url);
2818 let isSubmission = isMutationMethod(request.method);
2819 let routeIdsToLoad = !isSubmission && url.searchParams.has("_routes") ? url.searchParams.get("_routes").split(",") : null;
2820 const staticHandler = createStaticHandler(routes, {
2821 basename,
2822 mapRouteProperties: (r) => ({
2823 hasErrorBoundary: r.ErrorBoundary != null
2824 })
2825 });
2826 let actionResult;
2827 const ctx = {
2828 request,
2829 runningAction: false
2830 };
2831 const result = await ServerStorage.run(
2832 ctx,
2833 () => staticHandler.query(request, {
2834 requestContext,
2835 skipLoaderErrorBubbling: isDataRequest,
2836 skipRevalidation: isSubmission,
2837 ...routeIdsToLoad ? { filterMatchesToLoad: (m) => routeIdsToLoad.includes(m.route.id) } : {},
2838 async generateMiddlewareResponse(query) {
2839 let formState;
2840 let skipRevalidation = false;
2841 let potentialCSRFAttackError;
2842 if (request.method === "POST") {
2843 try {
2844 throwIfPotentialCSRFAttack(request.headers, allowedActionOrigins);
2845 ctx.runningAction = true;
2846 let result2 = await processServerAction(
2847 request,
2848 basename,
2849 decodeReply,
2850 loadServerAction,
2851 decodeAction,
2852 decodeFormState,
2853 onError,
2854 temporaryReferences
2855 ).finally(() => {
2856 ctx.runningAction = false;
2857 });
2858 if (isResponse(result2)) {
2859 return generateRedirectResponse(
2860 result2,
2861 actionResult,
2862 basename,
2863 isDataRequest,
2864 generateResponse,
2865 temporaryReferences,
2866 ctx.redirect?.headers
2867 );
2868 }
2869 skipRevalidation = result2?.skipRevalidation ?? false;
2870 actionResult = result2?.actionResult;
2871 formState = result2?.formState;
2872 request = result2?.revalidationRequest ?? request;
2873 if (ctx.redirect) {
2874 return generateRedirectResponse(
2875 ctx.redirect,
2876 actionResult,
2877 basename,
2878 isDataRequest,
2879 generateResponse,
2880 temporaryReferences,
2881 void 0
2882 );
2883 }
2884 } catch (error) {
2885 potentialCSRFAttackError = error;
2886 }
2887 }
2888 let staticContext = await query(
2889 request,
2890 skipRevalidation || !!potentialCSRFAttackError ? {
2891 filterMatchesToLoad: () => false
2892 } : void 0
2893 );
2894 if (isResponse(staticContext)) {
2895 return generateRedirectResponse(
2896 staticContext,
2897 actionResult,
2898 basename,
2899 isDataRequest,
2900 generateResponse,
2901 temporaryReferences,
2902 ctx.redirect?.headers
2903 );
2904 }
2905 if (potentialCSRFAttackError) {
2906 staticContext.errors ?? (staticContext.errors = {});
2907 staticContext.errors[staticContext.matches[0].route.id] = potentialCSRFAttackError;
2908 staticContext.statusCode = 400;
2909 }
2910 return generateStaticContextResponse(
2911 routes,
2912 basename,
2913 generateResponse,
2914 statusCode,
2915 routeIdsToLoad,
2916 isDataRequest,
2917 isSubmission,
2918 actionResult,
2919 formState,
2920 staticContext,
2921 temporaryReferences,
2922 skipRevalidation,
2923 ctx.redirect?.headers
2924 );
2925 }
2926 })
2927 );
2928 if (isRedirectResponse(result)) {
2929 return generateRedirectResponse(
2930 result,
2931 actionResult,
2932 basename,
2933 isDataRequest,
2934 generateResponse,
2935 temporaryReferences,
2936 ctx.redirect?.headers
2937 );
2938 }
2939 invariant2(isResponse(result), "Expected a response from query");
2940 return result;
2941}
2942function generateRedirectResponse(response, actionResult, basename, isDataRequest, generateResponse, temporaryReferences, sideEffectRedirectHeaders) {
2943 let redirect3 = response.headers.get("Location");
2944 if (isDataRequest && basename) {
2945 redirect3 = stripBasename(redirect3, basename) || redirect3;
2946 }
2947 let payload = {
2948 type: "redirect",
2949 location: redirect3,
2950 reload: response.headers.get("X-Remix-Reload-Document") === "true",
2951 replace: response.headers.get("X-Remix-Replace") === "true",
2952 status: response.status,
2953 actionResult
2954 };
2955 let headers = new Headers(sideEffectRedirectHeaders);
2956 for (const [key, value] of response.headers.entries()) {
2957 headers.append(key, value);
2958 }
2959 headers.delete("Location");
2960 headers.delete("X-Remix-Reload-Document");
2961 headers.delete("X-Remix-Replace");
2962 headers.delete("Content-Length");
2963 headers.set("Content-Type", "text/x-component");
2964 headers.set("Vary", "Content-Type");
2965 return generateResponse(
2966 {
2967 statusCode: SINGLE_FETCH_REDIRECT_STATUS,
2968 headers,
2969 payload
2970 },
2971 { temporaryReferences, onError: defaultOnError }
2972 );
2973}
2974async function generateStaticContextResponse(routes, basename, generateResponse, statusCode, routeIdsToLoad, isDataRequest, isSubmission, actionResult, formState, staticContext, temporaryReferences, skipRevalidation, sideEffectRedirectHeaders) {
2975 statusCode = staticContext.statusCode ?? statusCode;
2976 if (staticContext.errors) {
2977 staticContext.errors = Object.fromEntries(
2978 Object.entries(staticContext.errors).map(([key, error]) => [
2979 key,
2980 isRouteErrorResponse(error) ? Object.fromEntries(Object.entries(error)) : error
2981 ])
2982 );
2983 }
2984 staticContext.matches.forEach((m) => {
2985 const routeHasNoLoaderData = staticContext.loaderData[m.route.id] === void 0;
2986 const routeHasError = Boolean(
2987 staticContext.errors && m.route.id in staticContext.errors
2988 );
2989 if (routeHasNoLoaderData && !routeHasError) {
2990 staticContext.loaderData[m.route.id] = null;
2991 }
2992 });
2993 let headers = getDocumentHeadersImpl(
2994 staticContext,
2995 (match) => match.route.headers,
2996 sideEffectRedirectHeaders
2997 );
2998 headers.delete("Content-Length");
2999 const baseRenderPayload = {
3000 type: "render",
3001 basename: staticContext.basename,
3002 actionData: staticContext.actionData,
3003 errors: staticContext.errors,
3004 loaderData: staticContext.loaderData,
3005 location: staticContext.location,
3006 formState
3007 };
3008 const renderPayloadPromise = () => getRenderPayload(
3009 baseRenderPayload,
3010 routes,
3011 basename,
3012 routeIdsToLoad,
3013 isDataRequest,
3014 staticContext
3015 );
3016 let payload;
3017 if (actionResult) {
3018 payload = {
3019 type: "action",
3020 actionResult,
3021 rerender: skipRevalidation ? void 0 : renderPayloadPromise()
3022 };
3023 } else if (isSubmission && isDataRequest) {
3024 payload = {
3025 ...baseRenderPayload,
3026 matches: [],
3027 patches: []
3028 };
3029 } else {
3030 payload = await renderPayloadPromise();
3031 }
3032 return generateResponse(
3033 {
3034 statusCode,
3035 headers,
3036 payload
3037 },
3038 { temporaryReferences, onError: defaultOnError }
3039 );
3040}
3041async function getRenderPayload(baseRenderPayload, routes, basename, routeIdsToLoad, isDataRequest, staticContext) {
3042 let deepestRenderedRouteIdx = staticContext.matches.length - 1;
3043 let parentIds = {};
3044 staticContext.matches.forEach((m, i) => {
3045 if (i > 0) {
3046 parentIds[m.route.id] = staticContext.matches[i - 1].route.id;
3047 }
3048 if (staticContext.errors && m.route.id in staticContext.errors && deepestRenderedRouteIdx > i) {
3049 deepestRenderedRouteIdx = i;
3050 }
3051 });
3052 let matchesPromise = Promise.all(
3053 staticContext.matches.map((match, i) => {
3054 let isBelowErrorBoundary = i > deepestRenderedRouteIdx;
3055 let parentId = parentIds[match.route.id];
3056 return getRSCRouteMatch({
3057 staticContext,
3058 match,
3059 routeIdsToLoad,
3060 isBelowErrorBoundary,
3061 parentId
3062 });
3063 })
3064 );
3065 let patchesPromise = getAdditionalRoutePatches(
3066 [staticContext.location.pathname],
3067 routes,
3068 basename,
3069 staticContext.matches.map((m) => m.route.id)
3070 );
3071 let [matches, patches] = await Promise.all([matchesPromise, patchesPromise]);
3072 return {
3073 ...baseRenderPayload,
3074 matches,
3075 patches
3076 };
3077}
3078async function getRSCRouteMatch({
3079 staticContext,
3080 match,
3081 isBelowErrorBoundary,
3082 routeIdsToLoad,
3083 parentId
3084}) {
3085 await explodeLazyRoute(match.route);
3086 const Layout = match.route.Layout || React2.Fragment;
3087 const Component = match.route.Component;
3088 const ErrorBoundary = match.route.ErrorBoundary;
3089 const HydrateFallback = match.route.HydrateFallback;
3090 const loaderData = staticContext.loaderData[match.route.id];
3091 const actionData = staticContext.actionData?.[match.route.id];
3092 const params = match.params;
3093 let element = void 0;
3094 let shouldLoadRoute = !routeIdsToLoad || routeIdsToLoad.includes(match.route.id);
3095 if (Component && shouldLoadRoute) {
3096 element = !isBelowErrorBoundary ? React2.createElement(
3097 Layout,
3098 null,
3099 isClientReference(Component) ? React2.createElement(WithComponentProps, {
3100 children: React2.createElement(Component)
3101 }) : React2.createElement(Component, {
3102 loaderData,
3103 actionData,
3104 params,
3105 matches: staticContext.matches.map(
3106 (match2) => convertRouteMatchToUiMatch(match2, staticContext.loaderData)
3107 )
3108 })
3109 ) : React2.createElement(Outlet);
3110 }
3111 let error = void 0;
3112 if (ErrorBoundary && staticContext.errors) {
3113 error = staticContext.errors[match.route.id];
3114 }
3115 const errorElement = ErrorBoundary ? React2.createElement(
3116 Layout,
3117 null,
3118 isClientReference(ErrorBoundary) ? React2.createElement(WithErrorBoundaryProps, {
3119 children: React2.createElement(ErrorBoundary)
3120 }) : React2.createElement(ErrorBoundary, {
3121 loaderData,
3122 actionData,
3123 params,
3124 error
3125 })
3126 ) : void 0;
3127 const hydrateFallbackElement = HydrateFallback ? React2.createElement(
3128 Layout,
3129 null,
3130 isClientReference(HydrateFallback) ? React2.createElement(WithHydrateFallbackProps, {
3131 children: React2.createElement(HydrateFallback)
3132 }) : React2.createElement(HydrateFallback, {
3133 loaderData,
3134 actionData,
3135 params
3136 })
3137 ) : void 0;
3138 return {
3139 clientAction: match.route.clientAction,
3140 clientLoader: match.route.clientLoader,
3141 element,
3142 errorElement,
3143 handle: match.route.handle,
3144 hasAction: !!match.route.action,
3145 hasComponent: !!Component,
3146 hasErrorBoundary: !!ErrorBoundary,
3147 hasLoader: !!match.route.loader,
3148 hydrateFallbackElement,
3149 id: match.route.id,
3150 index: match.route.index,
3151 links: match.route.links,
3152 meta: match.route.meta,
3153 params,
3154 parentId,
3155 path: match.route.path,
3156 pathname: match.pathname,
3157 pathnameBase: match.pathnameBase,
3158 shouldRevalidate: match.route.shouldRevalidate,
3159 // Add an unused client-only export (if present) so HMR can support
3160 // switching between server-first and client-only routes during development
3161 ...match.route.__ensureClientRouteModuleForHMR ? {
3162 __ensureClientRouteModuleForHMR: match.route.__ensureClientRouteModuleForHMR
3163 } : {}
3164 };
3165}
3166async function getManifestRoute(route) {
3167 await explodeLazyRoute(route);
3168 const Layout = route.Layout || React2.Fragment;
3169 const errorElement = route.ErrorBoundary ? React2.createElement(
3170 Layout,
3171 null,
3172 React2.createElement(route.ErrorBoundary)
3173 ) : void 0;
3174 return {
3175 clientAction: route.clientAction,
3176 clientLoader: route.clientLoader,
3177 handle: route.handle,
3178 hasAction: !!route.action,
3179 hasComponent: !!route.Component,
3180 hasErrorBoundary: !!route.ErrorBoundary,
3181 errorElement,
3182 hasLoader: !!route.loader,
3183 id: route.id,
3184 parentId: route.parentId,
3185 path: route.path,
3186 index: "index" in route ? route.index : void 0,
3187 links: route.links,
3188 meta: route.meta
3189 };
3190}
3191async function explodeLazyRoute(route) {
3192 if ("lazy" in route && route.lazy) {
3193 let {
3194 default: lazyDefaultExport,
3195 Component: lazyComponentExport,
3196 ...lazyProperties
3197 } = await route.lazy();
3198 let Component = lazyComponentExport || lazyDefaultExport;
3199 if (Component && !route.Component) {
3200 route.Component = Component;
3201 }
3202 for (let [k, v] of Object.entries(lazyProperties)) {
3203 if (k !== "id" && k !== "path" && k !== "index" && k !== "children" && route[k] == null) {
3204 route[k] = v;
3205 }
3206 }
3207 route.lazy = void 0;
3208 }
3209}
3210async function getAdditionalRoutePatches(pathnames, routes, basename, matchedRouteIds) {
3211 let patchRouteMatches = /* @__PURE__ */ new Map();
3212 let matchedPaths = /* @__PURE__ */ new Set();
3213 for (const pathname of pathnames) {
3214 let segments = pathname.split("/").filter(Boolean);
3215 let paths = ["/"];
3216 segments.pop();
3217 while (segments.length > 0) {
3218 paths.push(`/${segments.join("/")}`);
3219 segments.pop();
3220 }
3221 paths.forEach((path) => {
3222 if (matchedPaths.has(path)) {
3223 return;
3224 }
3225 matchedPaths.add(path);
3226 let matches = matchRoutes(routes, path, basename) || [];
3227 matches.forEach((m, i) => {
3228 if (patchRouteMatches.get(m.route.id)) {
3229 return;
3230 }
3231 patchRouteMatches.set(m.route.id, {
3232 ...m.route,
3233 parentId: matches[i - 1]?.route.id
3234 });
3235 });
3236 });
3237 }
3238 let patches = await Promise.all(
3239 [...patchRouteMatches.values()].filter((route) => !matchedRouteIds.some((id) => id === route.id)).map((route) => getManifestRoute(route))
3240 );
3241 return patches;
3242}
3243function isReactServerRequest(url) {
3244 return url.pathname.endsWith(".rsc");
3245}
3246function isManifestRequest(url) {
3247 return url.pathname.endsWith(".manifest");
3248}
3249function defaultOnError(error) {
3250 if (isRedirectResponse(error)) {
3251 return createRedirectErrorDigest(error);
3252 }
3253 if (isResponse(error) || isDataWithResponseInit(error)) {
3254 return createRouteErrorResponseDigest(error);
3255 }
3256}
3257function isClientReference(x) {
3258 try {
3259 return x.$$typeof === Symbol.for("react.client.reference");
3260 } catch {
3261 return false;
3262 }
3263}
3264function canDecodeWithFormData(contentType) {
3265 if (!contentType) return false;
3266 return contentType.match(/\bapplication\/x-www-form-urlencoded\b/) || contentType.match(/\bmultipart\/form-data\b/);
3267}
3268
3269// lib/href.ts
3270function href(path, ...args) {
3271 let params = args[0];
3272 let result = trimTrailingSplat(path).replace(
3273 /\/:([\w-]+)(\?)?/g,
3274 // same regex as in .\router\utils.ts: compilePath().
3275 (_, param, questionMark) => {
3276 const isRequired = questionMark === void 0;
3277 const value = params?.[param];
3278 if (isRequired && value === void 0) {
3279 throw new Error(
3280 `Path '${path}' requires param '${param}' but it was not provided`
3281 );
3282 }
3283 return value === void 0 ? "" : "/" + value;
3284 }
3285 );
3286 if (path.endsWith("*")) {
3287 const value = params?.["*"];
3288 if (value !== void 0) {
3289 result += "/" + value;
3290 }
3291 }
3292 return result || "/";
3293}
3294function trimTrailingSplat(path) {
3295 let i = path.length - 1;
3296 let char = path[i];
3297 if (char !== "*" && char !== "/") return path;
3298 i--;
3299 for (; i >= 0; i--) {
3300 if (path[i] !== "/") break;
3301 }
3302 return path.slice(0, i + 1);
3303}
3304
3305// lib/server-runtime/crypto.ts
3306var encoder = /* @__PURE__ */ new TextEncoder();
3307var sign = async (value, secret) => {
3308 let data2 = encoder.encode(value);
3309 let key = await createKey2(secret, ["sign"]);
3310 let signature = await crypto.subtle.sign("HMAC", key, data2);
3311 let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(
3312 /=+$/,
3313 ""
3314 );
3315 return value + "." + hash;
3316};
3317var unsign = async (cookie, secret) => {
3318 let index = cookie.lastIndexOf(".");
3319 let value = cookie.slice(0, index);
3320 let hash = cookie.slice(index + 1);
3321 let data2 = encoder.encode(value);
3322 let key = await createKey2(secret, ["verify"]);
3323 try {
3324 let signature = byteStringToUint8Array(atob(hash));
3325 let valid = await crypto.subtle.verify("HMAC", key, signature, data2);
3326 return valid ? value : false;
3327 } catch (error) {
3328 return false;
3329 }
3330};
3331var createKey2 = async (secret, usages) => crypto.subtle.importKey(
3332 "raw",
3333 encoder.encode(secret),
3334 { name: "HMAC", hash: "SHA-256" },
3335 false,
3336 usages
3337);
3338function byteStringToUint8Array(byteString) {
3339 let array = new Uint8Array(byteString.length);
3340 for (let i = 0; i < byteString.length; i++) {
3341 array[i] = byteString.charCodeAt(i);
3342 }
3343 return array;
3344}
3345
3346// lib/server-runtime/warnings.ts
3347var alreadyWarned = {};
3348function warnOnce(condition, message) {
3349 if (!condition && !alreadyWarned[message]) {
3350 alreadyWarned[message] = true;
3351 console.warn(message);
3352 }
3353}
3354
3355// lib/server-runtime/cookies.ts
3356var createCookie = (name, cookieOptions = {}) => {
3357 let { secrets = [], ...options } = {
3358 path: "/",
3359 sameSite: "lax",
3360 ...cookieOptions
3361 };
3362 warnOnceAboutExpiresCookie(name, options.expires);
3363 return {
3364 get name() {
3365 return name;
3366 },
3367 get isSigned() {
3368 return secrets.length > 0;
3369 },
3370 get expires() {
3371 return typeof options.maxAge !== "undefined" ? new Date(Date.now() + options.maxAge * 1e3) : options.expires;
3372 },
3373 async parse(cookieHeader, parseOptions) {
3374 if (!cookieHeader) return null;
3375 let cookies = parse(cookieHeader, { ...options, ...parseOptions });
3376 if (name in cookies) {
3377 let value = cookies[name];
3378 if (typeof value === "string" && value !== "") {
3379 let decoded = await decodeCookieValue(value, secrets);
3380 return decoded;
3381 } else {
3382 return "";
3383 }
3384 } else {
3385 return null;
3386 }
3387 },
3388 async serialize(value, serializeOptions) {
3389 return serialize(
3390 name,
3391 value === "" ? "" : await encodeCookieValue(value, secrets),
3392 {
3393 ...options,
3394 ...serializeOptions
3395 }
3396 );
3397 }
3398 };
3399};
3400var isCookie = (object) => {
3401 return object != null && typeof object.name === "string" && typeof object.isSigned === "boolean" && typeof object.parse === "function" && typeof object.serialize === "function";
3402};
3403async function encodeCookieValue(value, secrets) {
3404 let encoded = encodeData(value);
3405 if (secrets.length > 0) {
3406 encoded = await sign(encoded, secrets[0]);
3407 }
3408 return encoded;
3409}
3410async function decodeCookieValue(value, secrets) {
3411 if (secrets.length > 0) {
3412 for (let secret of secrets) {
3413 let unsignedValue = await unsign(value, secret);
3414 if (unsignedValue !== false) {
3415 return decodeData(unsignedValue);
3416 }
3417 }
3418 return null;
3419 }
3420 return decodeData(value);
3421}
3422function encodeData(value) {
3423 return btoa(myUnescape(encodeURIComponent(JSON.stringify(value))));
3424}
3425function decodeData(value) {
3426 try {
3427 return JSON.parse(decodeURIComponent(myEscape(atob(value))));
3428 } catch (error) {
3429 return {};
3430 }
3431}
3432function myEscape(value) {
3433 let str = value.toString();
3434 let result = "";
3435 let index = 0;
3436 let chr, code;
3437 while (index < str.length) {
3438 chr = str.charAt(index++);
3439 if (/[\w*+\-./@]/.exec(chr)) {
3440 result += chr;
3441 } else {
3442 code = chr.charCodeAt(0);
3443 if (code < 256) {
3444 result += "%" + hex(code, 2);
3445 } else {
3446 result += "%u" + hex(code, 4).toUpperCase();
3447 }
3448 }
3449 }
3450 return result;
3451}
3452function hex(code, length) {
3453 let result = code.toString(16);
3454 while (result.length < length) result = "0" + result;
3455 return result;
3456}
3457function myUnescape(value) {
3458 let str = value.toString();
3459 let result = "";
3460 let index = 0;
3461 let chr, part;
3462 while (index < str.length) {
3463 chr = str.charAt(index++);
3464 if (chr === "%") {
3465 if (str.charAt(index) === "u") {
3466 part = str.slice(index + 1, index + 5);
3467 if (/^[\da-f]{4}$/i.exec(part)) {
3468 result += String.fromCharCode(parseInt(part, 16));
3469 index += 5;
3470 continue;
3471 }
3472 } else {
3473 part = str.slice(index, index + 2);
3474 if (/^[\da-f]{2}$/i.exec(part)) {
3475 result += String.fromCharCode(parseInt(part, 16));
3476 index += 2;
3477 continue;
3478 }
3479 }
3480 }
3481 result += chr;
3482 }
3483 return result;
3484}
3485function warnOnceAboutExpiresCookie(name, expires) {
3486 warnOnce(
3487 !expires,
3488 `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.`
3489 );
3490}
3491
3492// lib/server-runtime/sessions.ts
3493function flash(name) {
3494 return `__flash_${name}__`;
3495}
3496var createSession = (initialData = {}, id = "") => {
3497 let map = new Map(Object.entries(initialData));
3498 return {
3499 get id() {
3500 return id;
3501 },
3502 get data() {
3503 return Object.fromEntries(map);
3504 },
3505 has(name) {
3506 return map.has(name) || map.has(flash(name));
3507 },
3508 get(name) {
3509 if (map.has(name)) return map.get(name);
3510 let flashName = flash(name);
3511 if (map.has(flashName)) {
3512 let value = map.get(flashName);
3513 map.delete(flashName);
3514 return value;
3515 }
3516 return void 0;
3517 },
3518 set(name, value) {
3519 map.set(name, value);
3520 },
3521 flash(name, value) {
3522 map.set(flash(name), value);
3523 },
3524 unset(name) {
3525 map.delete(name);
3526 }
3527 };
3528};
3529var isSession = (object) => {
3530 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";
3531};
3532function createSessionStorage({
3533 cookie: cookieArg,
3534 createData,
3535 readData,
3536 updateData,
3537 deleteData
3538}) {
3539 let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
3540 warnOnceAboutSigningSessionCookie(cookie);
3541 return {
3542 async getSession(cookieHeader, options) {
3543 let id = cookieHeader && await cookie.parse(cookieHeader, options);
3544 let data2 = id && await readData(id);
3545 return createSession(data2 || {}, id || "");
3546 },
3547 async commitSession(session, options) {
3548 let { id, data: data2 } = session;
3549 let expires = options?.maxAge != null ? new Date(Date.now() + options.maxAge * 1e3) : options?.expires != null ? options.expires : cookie.expires;
3550 if (id) {
3551 await updateData(id, data2, expires);
3552 } else {
3553 id = await createData(data2, expires);
3554 }
3555 return cookie.serialize(id, options);
3556 },
3557 async destroySession(session, options) {
3558 await deleteData(session.id);
3559 return cookie.serialize("", {
3560 ...options,
3561 maxAge: void 0,
3562 expires: /* @__PURE__ */ new Date(0)
3563 });
3564 }
3565 };
3566}
3567function warnOnceAboutSigningSessionCookie(cookie) {
3568 warnOnce(
3569 cookie.isSigned,
3570 `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.`
3571 );
3572}
3573
3574// lib/server-runtime/sessions/cookieStorage.ts
3575function createCookieSessionStorage({ cookie: cookieArg } = {}) {
3576 let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
3577 warnOnceAboutSigningSessionCookie(cookie);
3578 return {
3579 async getSession(cookieHeader, options) {
3580 return createSession(
3581 cookieHeader && await cookie.parse(cookieHeader, options) || {}
3582 );
3583 },
3584 async commitSession(session, options) {
3585 let serializedCookie = await cookie.serialize(session.data, options);
3586 if (serializedCookie.length > 4096) {
3587 throw new Error(
3588 "Cookie length will exceed browser maximum. Length: " + serializedCookie.length
3589 );
3590 }
3591 return serializedCookie;
3592 },
3593 async destroySession(_session, options) {
3594 return cookie.serialize("", {
3595 ...options,
3596 maxAge: void 0,
3597 expires: /* @__PURE__ */ new Date(0)
3598 });
3599 }
3600 };
3601}
3602
3603// lib/server-runtime/sessions/memoryStorage.ts
3604function createMemorySessionStorage({ cookie } = {}) {
3605 let map = /* @__PURE__ */ new Map();
3606 return createSessionStorage({
3607 cookie,
3608 async createData(data2, expires) {
3609 let id = Math.random().toString(36).substring(2, 10);
3610 map.set(id, { data: data2, expires });
3611 return id;
3612 },
3613 async readData(id) {
3614 if (map.has(id)) {
3615 let { data: data2, expires } = map.get(id);
3616 if (!expires || expires > /* @__PURE__ */ new Date()) {
3617 return data2;
3618 }
3619 if (expires) map.delete(id);
3620 }
3621 return null;
3622 },
3623 async updateData(id, data2, expires) {
3624 map.set(id, { data: data2, expires });
3625 },
3626 async deleteData(id) {
3627 map.delete(id);
3628 }
3629 });
3630}
3631
3632export { Await, RouterContextProvider, createContext, createCookie, createCookieSessionStorage, createMemorySessionStorage, createSession, createSessionStorage, createStaticHandler, data, href, isCookie, isRouteErrorResponse, isSession, matchRoutes, redirect2 as redirect, redirectDocument2 as redirectDocument, replace2 as replace, getRequest as unstable_getRequest, matchRSCServerRequest as unstable_matchRSCServerRequest };