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