UNPKG

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