UNPKG

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