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