UNPKG

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