react-router 7.18.0 → 8.0.0-pre.1

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