UNPKG

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