expo-router 2.0.0 → 3.0.0

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 (383) hide show
  1. package/README.md +1 -1
  2. package/{_ctx.android.tsx → _ctx.android.js} +1 -2
  3. package/_ctx.d.ts +3 -0
  4. package/{_ctx.ios.tsx → _ctx.ios.js} +1 -2
  5. package/_ctx.js +1 -0
  6. package/{_ctx.web.tsx → _ctx.web.js} +1 -2
  7. package/_error.js +2 -4
  8. package/app.plugin.js +1 -1
  9. package/babel.js +44 -55
  10. package/build/ExpoRoot.d.ts +2 -2
  11. package/build/ExpoRoot.d.ts.map +1 -1
  12. package/build/ExpoRoot.js +79 -0
  13. package/build/ExpoRoot.js.map +1 -0
  14. package/build/LocationProvider.d.ts +2 -2
  15. package/build/LocationProvider.d.ts.map +1 -1
  16. package/build/LocationProvider.js +30 -0
  17. package/build/LocationProvider.js.map +1 -0
  18. package/build/Route.d.ts +3 -3
  19. package/build/Route.d.ts.map +1 -1
  20. package/build/Route.js +68 -0
  21. package/build/Route.js.map +1 -0
  22. package/build/exports.d.ts +12 -12
  23. package/build/exports.js +17 -0
  24. package/build/exports.js.map +1 -0
  25. package/build/fork/NavigationContainer.d.ts +1 -1
  26. package/build/fork/NavigationContainer.js +4 -0
  27. package/build/fork/NavigationContainer.js.map +1 -0
  28. package/build/fork/NavigationContainer.native.d.ts +3 -3
  29. package/build/fork/NavigationContainer.native.d.ts.map +1 -1
  30. package/build/fork/NavigationContainer.native.js +81 -0
  31. package/build/fork/NavigationContainer.native.js.map +1 -0
  32. package/build/fork/expo/createRoot.d.ts +1 -1
  33. package/build/fork/expo/createRoot.js +2 -0
  34. package/build/fork/expo/createRoot.js.map +1 -0
  35. package/{src/fork/expo/createRoot.native.tsx → build/fork/expo/createRoot.native.js} +3 -2
  36. package/build/fork/expo/createRoot.native.js.map +1 -0
  37. package/build/fork/expo/registerRootComponent.d.ts +3 -3
  38. package/build/fork/expo/registerRootComponent.js +51 -0
  39. package/build/fork/expo/registerRootComponent.js.map +1 -0
  40. package/build/fork/extractPathFromURL.d.ts.map +1 -1
  41. package/build/fork/extractPathFromURL.js +76 -0
  42. package/build/fork/extractPathFromURL.js.map +1 -0
  43. package/build/fork/findFocusedRoute.d.ts +1 -1
  44. package/build/fork/findFocusedRoute.js +10 -0
  45. package/build/fork/findFocusedRoute.js.map +1 -0
  46. package/build/fork/getPathFromState.d.ts +3 -3
  47. package/build/fork/getPathFromState.d.ts.map +1 -1
  48. package/build/fork/getPathFromState.js +419 -0
  49. package/build/fork/getPathFromState.js.map +1 -0
  50. package/build/fork/getStateFromPath.d.ts +3 -3
  51. package/build/fork/getStateFromPath.d.ts.map +1 -1
  52. package/build/fork/getStateFromPath.js +503 -0
  53. package/build/fork/getStateFromPath.js.map +1 -0
  54. package/build/fork/useLinking.d.ts.map +1 -1
  55. package/build/fork/useLinking.js +3 -0
  56. package/build/fork/useLinking.js.map +1 -0
  57. package/build/fork/useLinking.native.d.ts +3 -3
  58. package/build/fork/useLinking.native.d.ts.map +1 -1
  59. package/build/fork/useLinking.native.js +154 -0
  60. package/build/fork/useLinking.native.js.map +1 -0
  61. package/build/fork/validatePathConfig.d.ts.map +1 -1
  62. package/build/fork/validatePathConfig.js +19 -0
  63. package/build/fork/validatePathConfig.js.map +1 -0
  64. package/build/getDevServer/index.js +30 -0
  65. package/build/getDevServer/index.js.map +1 -0
  66. package/build/getDevServer/index.native.js +2 -0
  67. package/build/getDevServer/index.native.js.map +1 -0
  68. package/build/getLinkingConfig.d.ts +4 -4
  69. package/build/getLinkingConfig.d.ts.map +1 -1
  70. package/build/getLinkingConfig.js +43 -0
  71. package/build/getLinkingConfig.js.map +1 -0
  72. package/build/getReactNavigationConfig.d.ts +1 -1
  73. package/build/getReactNavigationConfig.d.ts.map +1 -1
  74. package/build/getReactNavigationConfig.js +69 -0
  75. package/build/getReactNavigationConfig.js.map +1 -0
  76. package/build/getRoutes.d.ts +4 -4
  77. package/build/getRoutes.d.ts.map +1 -1
  78. package/build/getRoutes.js +378 -0
  79. package/build/getRoutes.js.map +1 -0
  80. package/build/global-state/router-store.d.ts +15 -16
  81. package/build/global-state/router-store.d.ts.map +1 -1
  82. package/build/global-state/router-store.js +179 -0
  83. package/build/global-state/router-store.js.map +1 -0
  84. package/build/global-state/routing.d.ts +6 -6
  85. package/build/global-state/routing.d.ts.map +1 -1
  86. package/build/global-state/routing.js +149 -0
  87. package/build/global-state/routing.js.map +1 -0
  88. package/build/global-state/sort-routes.d.ts +1 -1
  89. package/build/global-state/sort-routes.d.ts.map +1 -1
  90. package/build/global-state/sort-routes.js +8 -0
  91. package/build/global-state/sort-routes.js.map +1 -0
  92. package/build/head/ExpoHead.android.d.ts +10 -0
  93. package/build/head/ExpoHead.android.d.ts.map +1 -0
  94. package/build/head/ExpoHead.android.js +6 -0
  95. package/build/head/ExpoHead.android.js.map +1 -0
  96. package/build/head/ExpoHead.d.ts +8 -0
  97. package/build/head/ExpoHead.d.ts.map +1 -0
  98. package/build/head/ExpoHead.ios.d.ts +7 -0
  99. package/build/head/ExpoHead.ios.d.ts.map +1 -0
  100. package/build/head/ExpoHead.ios.js +242 -0
  101. package/build/head/ExpoHead.ios.js.map +1 -0
  102. package/build/head/ExpoHead.js +7 -0
  103. package/build/head/ExpoHead.js.map +1 -0
  104. package/build/head/ExpoHeadModule.d.ts +33 -0
  105. package/build/head/ExpoHeadModule.d.ts.map +1 -0
  106. package/build/head/ExpoHeadModule.js +4 -0
  107. package/build/head/ExpoHeadModule.js.map +1 -0
  108. package/build/head/ExpoHeadModule.native.d.ts +3 -0
  109. package/build/head/ExpoHeadModule.native.d.ts.map +1 -0
  110. package/build/head/ExpoHeadModule.native.js +10 -0
  111. package/build/head/ExpoHeadModule.native.js.map +1 -0
  112. package/build/head/index.d.ts +2 -0
  113. package/build/head/index.d.ts.map +1 -0
  114. package/build/head/index.js +2 -0
  115. package/build/head/index.js.map +1 -0
  116. package/build/head/url.d.ts +2 -0
  117. package/build/head/url.d.ts.map +1 -0
  118. package/build/head/url.js +64 -0
  119. package/build/head/url.js.map +1 -0
  120. package/build/hooks.d.ts +1 -1
  121. package/build/hooks.d.ts.map +1 -1
  122. package/{src/hooks.ts → build/hooks.js} +34 -66
  123. package/build/hooks.js.map +1 -0
  124. package/build/imperative-api.d.ts +1 -1
  125. package/build/imperative-api.js +9 -0
  126. package/build/imperative-api.js.map +1 -0
  127. package/{src/import-mode/index.android.ts → build/import-mode/index.android.js} +1 -0
  128. package/build/import-mode/index.android.js.map +1 -0
  129. package/{src/import-mode/index.ios.ts → build/import-mode/index.ios.js} +1 -0
  130. package/build/import-mode/index.ios.js.map +1 -0
  131. package/build/import-mode/index.js +2 -0
  132. package/build/import-mode/index.js.map +1 -0
  133. package/{src/import-mode/index.web.ts → build/import-mode/index.web.js} +1 -0
  134. package/build/import-mode/index.web.js.map +1 -0
  135. package/build/index.d.ts +3 -3
  136. package/build/index.js +4 -0
  137. package/build/index.js.map +1 -0
  138. package/build/layouts/Drawer.d.ts +1 -1
  139. package/build/layouts/Drawer.d.ts.map +1 -1
  140. package/build/layouts/Drawer.js +6 -0
  141. package/build/layouts/Drawer.js.map +1 -0
  142. package/build/layouts/Stack.d.ts +1 -1
  143. package/build/layouts/Stack.d.ts.map +1 -1
  144. package/build/layouts/Stack.js +6 -0
  145. package/build/layouts/Stack.js.map +1 -0
  146. package/build/layouts/Tabs.d.ts +4 -4
  147. package/build/layouts/Tabs.d.ts.map +1 -1
  148. package/build/layouts/Tabs.js +34 -0
  149. package/build/layouts/Tabs.js.map +1 -0
  150. package/build/layouts/withLayoutContext.d.ts +4 -4
  151. package/build/layouts/withLayoutContext.d.ts.map +1 -1
  152. package/build/layouts/withLayoutContext.js +65 -0
  153. package/build/layouts/withLayoutContext.js.map +1 -0
  154. package/build/link/Link.d.ts +5 -5
  155. package/build/link/Link.d.ts.map +1 -1
  156. package/build/link/Link.js +63 -0
  157. package/build/link/Link.js.map +1 -0
  158. package/build/link/href.d.ts.map +1 -1
  159. package/build/link/href.js +46 -0
  160. package/build/link/href.js.map +1 -0
  161. package/build/link/linking.d.ts +2 -2
  162. package/build/link/linking.d.ts.map +1 -1
  163. package/build/link/linking.js +86 -0
  164. package/build/link/linking.js.map +1 -0
  165. package/build/link/path.d.ts.map +1 -1
  166. package/build/link/path.js +143 -0
  167. package/build/link/path.js.map +1 -0
  168. package/build/link/stateOperations.d.ts +3 -3
  169. package/build/link/stateOperations.js +91 -0
  170. package/build/link/stateOperations.js.map +1 -0
  171. package/build/link/useLinkToPathProps.d.ts +2 -2
  172. package/build/link/useLinkToPathProps.d.ts.map +1 -1
  173. package/build/link/useLinkToPathProps.js +45 -0
  174. package/build/link/useLinkToPathProps.js.map +1 -0
  175. package/build/link/useLoadedNavigation.d.ts +1 -1
  176. package/build/link/useLoadedNavigation.js +46 -0
  177. package/build/link/useLoadedNavigation.js.map +1 -0
  178. package/build/loadStaticParamsAsync.d.ts +1 -1
  179. package/build/loadStaticParamsAsync.d.ts.map +1 -1
  180. package/build/loadStaticParamsAsync.js +117 -0
  181. package/build/loadStaticParamsAsync.js.map +1 -0
  182. package/build/matchers.js +49 -0
  183. package/build/matchers.js.map +1 -0
  184. package/build/onboard/Tutorial.d.ts.map +1 -1
  185. package/build/onboard/Tutorial.js +155 -0
  186. package/build/onboard/Tutorial.js.map +1 -0
  187. package/{src/onboard/createEntryFile.ts → build/onboard/createEntryFile.js} +19 -22
  188. package/build/onboard/createEntryFile.js.map +1 -0
  189. package/build/primitives.js +5 -0
  190. package/build/primitives.js.map +1 -0
  191. package/build/qualified-entry.d.ts +3 -0
  192. package/build/qualified-entry.d.ts.map +1 -0
  193. package/{_app.tsx → build/qualified-entry.js} +7 -10
  194. package/build/qualified-entry.js.map +1 -0
  195. package/build/renderRootComponent.d.ts +1 -1
  196. package/build/renderRootComponent.d.ts.map +1 -1
  197. package/build/renderRootComponent.js +72 -0
  198. package/build/renderRootComponent.js.map +1 -0
  199. package/build/static/getRootComponent.d.ts.map +1 -1
  200. package/build/static/getRootComponent.js +22 -0
  201. package/build/static/getRootComponent.js.map +1 -0
  202. package/build/static/html.d.ts +1 -1
  203. package/build/static/html.js +25 -0
  204. package/build/static/html.js.map +1 -0
  205. package/build/static/renderStaticContent.d.ts +6 -1
  206. package/build/static/renderStaticContent.d.ts.map +1 -1
  207. package/build/static/renderStaticContent.js +85 -0
  208. package/build/static/renderStaticContent.js.map +1 -0
  209. package/build/testing-library/context-stubs.d.ts +1 -1
  210. package/build/testing-library/context-stubs.d.ts.map +1 -1
  211. package/build/testing-library/context-stubs.js +30 -0
  212. package/build/testing-library/context-stubs.js.map +1 -0
  213. package/build/testing-library/expect.js +14 -0
  214. package/build/testing-library/expect.js.map +1 -0
  215. package/build/testing-library/index.d.ts +4 -4
  216. package/build/testing-library/index.d.ts.map +1 -1
  217. package/build/testing-library/index.js +57 -0
  218. package/build/testing-library/index.js.map +1 -0
  219. package/build/testing-library/mocks.d.ts +1 -1
  220. package/build/testing-library/mocks.js +33 -0
  221. package/build/testing-library/mocks.js.map +1 -0
  222. package/build/testing-library/require-context-ponyfill.d.ts +1 -1
  223. package/build/testing-library/require-context-ponyfill.js +29 -0
  224. package/build/testing-library/require-context-ponyfill.js.map +1 -0
  225. package/build/types.d.ts +1 -1
  226. package/build/types.d.ts.map +1 -1
  227. package/build/types.js +2 -0
  228. package/build/types.js.map +1 -0
  229. package/build/useDeprecated.d.ts +3 -0
  230. package/build/useDeprecated.d.ts.map +1 -0
  231. package/build/useDeprecated.js +23 -0
  232. package/build/useDeprecated.js.map +1 -0
  233. package/build/useFocusEffect.d.ts.map +1 -1
  234. package/build/useFocusEffect.js +98 -0
  235. package/build/useFocusEffect.js.map +1 -0
  236. package/build/useNavigation.d.ts +1 -1
  237. package/build/useNavigation.d.ts.map +1 -1
  238. package/build/useNavigation.js +63 -0
  239. package/build/useNavigation.js.map +1 -0
  240. package/build/useScreens.d.ts +4 -4
  241. package/build/useScreens.d.ts.map +1 -1
  242. package/build/useScreens.js +183 -0
  243. package/build/useScreens.js.map +1 -0
  244. package/build/utils/mockState.d.ts +1 -1
  245. package/build/utils/mockState.d.ts.map +1 -1
  246. package/build/utils/mockState.js +24 -0
  247. package/build/utils/mockState.js.map +1 -0
  248. package/{src/utils/url.ts → build/utils/url.js} +3 -2
  249. package/build/utils/url.js.map +1 -0
  250. package/build/views/EmptyRoute.js +9 -0
  251. package/build/views/EmptyRoute.js.map +1 -0
  252. package/build/views/ErrorBoundary.d.ts +1 -1
  253. package/build/views/ErrorBoundary.d.ts.map +1 -1
  254. package/build/views/ErrorBoundary.js +124 -0
  255. package/build/views/ErrorBoundary.js.map +1 -0
  256. package/build/views/Navigator.d.ts +11 -11
  257. package/build/views/Navigator.d.ts.map +1 -1
  258. package/build/views/Navigator.js +87 -0
  259. package/build/views/Navigator.js.map +1 -0
  260. package/build/views/Screen.d.ts.map +1 -1
  261. package/build/views/Screen.js +30 -0
  262. package/build/views/Screen.js.map +1 -0
  263. package/build/views/Sitemap.d.ts +1 -1
  264. package/build/views/Sitemap.d.ts.map +1 -1
  265. package/build/views/Sitemap.js +156 -0
  266. package/build/views/Sitemap.js.map +1 -0
  267. package/build/views/Splash.d.ts.map +1 -1
  268. package/build/views/Splash.js +109 -0
  269. package/build/views/Splash.js.map +1 -0
  270. package/build/views/SuspenseFallback.d.ts +1 -1
  271. package/build/views/SuspenseFallback.js +7 -0
  272. package/build/views/SuspenseFallback.js.map +1 -0
  273. package/build/views/Toast.d.ts +1 -1
  274. package/build/views/Toast.d.ts.map +1 -1
  275. package/build/views/Toast.js +73 -0
  276. package/build/views/Toast.js.map +1 -0
  277. package/build/views/Try.d.ts +1 -1
  278. package/build/views/Try.js +27 -0
  279. package/build/views/Try.js.map +1 -0
  280. package/build/views/Unmatched.d.ts.map +1 -1
  281. package/build/views/Unmatched.js +72 -0
  282. package/build/views/Unmatched.js.map +1 -0
  283. package/drawer.d.ts +2 -0
  284. package/drawer.js +1 -0
  285. package/entry.js +4 -5
  286. package/expo-module.config.json +8 -0
  287. package/head.d.ts +1 -0
  288. package/head.js +1 -0
  289. package/html.js +1 -0
  290. package/ios/ExpoHead.podspec +32 -0
  291. package/ios/ExpoHeadAppDelegateSubscriber.swift +94 -0
  292. package/ios/ExpoHeadModule.swift +186 -0
  293. package/node/getExpoConstantsManifest.js +22 -38
  294. package/node/render.js +1 -1
  295. package/package.json +42 -39
  296. package/plugin/build/index.d.ts +1 -1
  297. package/plugin/build/index.js +4 -2
  298. package/plugin/jest.config.js +1 -0
  299. package/stack.d.ts +2 -0
  300. package/stack.js +1 -0
  301. package/tabs.d.ts +2 -0
  302. package/tabs.js +1 -0
  303. package/testing-library.d.ts +1 -0
  304. package/testing-library.js +1 -0
  305. package/types/expect.d.ts +1 -1
  306. package/types/global.d.ts +7 -7
  307. package/types/metro-require.d.ts +1 -1
  308. package/types/react-native-web.d.ts +16 -20
  309. package/_ctx.tsx +0 -5
  310. package/_entry.tsx +0 -33
  311. package/_html-ctx.tsx +0 -9
  312. package/drawer.ts +0 -2
  313. package/head.ts +0 -6
  314. package/html.ts +0 -1
  315. package/plugin/src/index.ts +0 -54
  316. package/src/ExpoRoot.tsx +0 -116
  317. package/src/LocationProvider.tsx +0 -52
  318. package/src/Route.tsx +0 -120
  319. package/src/exports.ts +0 -34
  320. package/src/fork/NavigationContainer.native.tsx +0 -159
  321. package/src/fork/NavigationContainer.tsx +0 -4
  322. package/src/fork/expo/createRoot.tsx +0 -1
  323. package/src/fork/expo/registerRootComponent.tsx +0 -77
  324. package/src/fork/extractPathFromURL.ts +0 -103
  325. package/src/fork/findFocusedRoute.tsx +0 -15
  326. package/src/fork/getPathFromState.ts +0 -647
  327. package/src/fork/getStateFromPath.ts +0 -776
  328. package/src/fork/useLinking.native.ts +0 -224
  329. package/src/fork/useLinking.ts +0 -4
  330. package/src/fork/validatePathConfig.ts +0 -32
  331. package/src/getDevServer/index.native.ts +0 -1
  332. package/src/getDevServer/index.ts +0 -37
  333. package/src/getLinkingConfig.ts +0 -69
  334. package/src/getReactNavigationConfig.ts +0 -103
  335. package/src/getRoutes.ts +0 -520
  336. package/src/global-state/router-store.tsx +0 -256
  337. package/src/global-state/routing.ts +0 -213
  338. package/src/global-state/sort-routes.ts +0 -12
  339. package/src/imperative-api.ts +0 -10
  340. package/src/import-mode/index.ts +0 -1
  341. package/src/index.tsx +0 -3
  342. package/src/layouts/Drawer.tsx +0 -15
  343. package/src/layouts/Stack.tsx +0 -15
  344. package/src/layouts/Tabs.tsx +0 -61
  345. package/src/layouts/withLayoutContext.tsx +0 -114
  346. package/src/link/Link.tsx +0 -104
  347. package/src/link/href.ts +0 -60
  348. package/src/link/linking.ts +0 -106
  349. package/src/link/path.ts +0 -141
  350. package/src/link/stateOperations.ts +0 -152
  351. package/src/link/useLinkToPathProps.tsx +0 -60
  352. package/src/link/useLoadedNavigation.ts +0 -60
  353. package/src/loadStaticParamsAsync.ts +0 -196
  354. package/src/matchers.tsx +0 -56
  355. package/src/onboard/Tutorial.tsx +0 -202
  356. package/src/primitives.tsx +0 -5
  357. package/src/renderRootComponent.tsx +0 -87
  358. package/src/static/getRootComponent.ts +0 -28
  359. package/src/static/html.tsx +0 -38
  360. package/src/static/renderStaticContent.tsx +0 -103
  361. package/src/testing-library/context-stubs.ts +0 -52
  362. package/src/testing-library/expect.ts +0 -15
  363. package/src/testing-library/index.tsx +0 -103
  364. package/src/testing-library/mocks.ts +0 -39
  365. package/src/testing-library/require-context-ponyfill.ts +0 -44
  366. package/src/ts-declarations.d.ts +0 -1
  367. package/src/types.ts +0 -30
  368. package/src/useFocusEffect.tsx +0 -121
  369. package/src/useNavigation.ts +0 -84
  370. package/src/useScreens.tsx +0 -297
  371. package/src/utils/mockState.ts +0 -31
  372. package/src/views/EmptyRoute.tsx +0 -16
  373. package/src/views/ErrorBoundary.tsx +0 -175
  374. package/src/views/Navigator.tsx +0 -164
  375. package/src/views/Screen.tsx +0 -51
  376. package/src/views/Sitemap.tsx +0 -270
  377. package/src/views/Splash.tsx +0 -125
  378. package/src/views/SuspenseFallback.tsx +0 -12
  379. package/src/views/Toast.tsx +0 -102
  380. package/src/views/Try.tsx +0 -46
  381. package/src/views/Unmatched.tsx +0 -105
  382. package/stack.ts +0 -2
  383. package/tabs.ts +0 -2
@@ -0,0 +1,503 @@
1
+ import escape from 'escape-string-regexp';
2
+ import * as queryString from 'query-string';
3
+ import URL from 'url-parse';
4
+ import { matchGroupName, stripGroupSegmentsFromPath } from '../matchers';
5
+ import { findFocusedRoute } from './findFocusedRoute';
6
+ import validatePathConfig from './validatePathConfig';
7
+ export function getUrlWithReactNavigationConcessions(path) {
8
+ const parsed = new URL(path, 'https://acme.com');
9
+ const pathname = parsed.pathname;
10
+ // Make sure there is a trailing slash
11
+ return {
12
+ // The slashes are at the end, not the beginning
13
+ nonstandardPathname: pathname.replace(/^\/+/g, '').replace(/\/+$/g, '') + '/',
14
+ // React Navigation doesn't support hashes, so here
15
+ inputPathnameWithoutHash: path.replace(/#.*$/, ''),
16
+ };
17
+ }
18
+ /**
19
+ * Utility to parse a path string to initial state object accepted by the container.
20
+ * This is useful for deep linking when we need to handle the incoming URL.
21
+ *
22
+ * @example
23
+ * ```js
24
+ * getStateFromPath(
25
+ * '/chat/jane/42',
26
+ * {
27
+ * screens: {
28
+ * Chat: {
29
+ * path: 'chat/:author/:id',
30
+ * parse: { id: Number }
31
+ * }
32
+ * }
33
+ * }
34
+ * )
35
+ * ```
36
+ * @param path Path string to parse and convert, e.g. /foo/bar?count=42.
37
+ * @param options Extra options to fine-tune how to parse the path.
38
+ */
39
+ export default function getStateFromPath(path, options) {
40
+ const { initialRoutes, configs } = getMatchableRouteConfigs(options);
41
+ return getStateFromPathWithConfigs(path, configs, initialRoutes);
42
+ }
43
+ export function getMatchableRouteConfigs(options) {
44
+ if (options) {
45
+ validatePathConfig(options);
46
+ }
47
+ const screens = options?.screens;
48
+ // Expo Router disallows usage without a linking config.
49
+ if (!screens) {
50
+ throw Error("You must pass a 'screens' object to 'getStateFromPath' to generate a path.");
51
+ }
52
+ // This will be mutated...
53
+ const initialRoutes = [];
54
+ if (options?.initialRouteName) {
55
+ initialRoutes.push({
56
+ initialRouteName: options.initialRouteName,
57
+ parentScreens: [],
58
+ });
59
+ }
60
+ // Create a normalized configs array which will be easier to use.
61
+ const converted = Object.keys(screens)
62
+ .map((key) => createNormalizedConfigs(key, screens, [], initialRoutes))
63
+ .flat();
64
+ const resolvedInitialPatterns = initialRoutes.map((route) => joinPaths(...route.parentScreens, route.initialRouteName));
65
+ const convertedWithInitial = converted.map((config) => ({
66
+ ...config,
67
+ // TODO(EvanBacon): Probably a safer way to do this
68
+ // Mark initial routes to give them potential priority over other routes that match.
69
+ isInitial: resolvedInitialPatterns.includes(config.routeNames.join('/')),
70
+ }));
71
+ // Sort in order of resolution. This is extremely important for the algorithm to work.
72
+ const configs = convertedWithInitial.sort(sortConfigs);
73
+ // Assert any duplicates before we start parsing.
74
+ assertConfigDuplicates(configs);
75
+ return { configs, initialRoutes };
76
+ }
77
+ function assertConfigDuplicates(configs) {
78
+ // Check for duplicate patterns in the config
79
+ configs.reduce((acc, config) => {
80
+ // NOTE(EvanBacon): Uses the regex pattern as key to detect duplicate slugs.
81
+ const indexedKey = config.regex?.toString() ?? config.pattern;
82
+ const alpha = acc[indexedKey];
83
+ // NOTE(EvanBacon): Skips checking nodes that have children.
84
+ if (alpha && !alpha.hasChildren && !config.hasChildren) {
85
+ const a = alpha.routeNames;
86
+ const b = config.routeNames;
87
+ // It's not a problem if the path string omitted from a inner most screen
88
+ // For example, it's ok if a path resolves to `A > B > C` or `A > B`
89
+ const intersects = a.length > b.length ? b.every((it, i) => a[i] === it) : a.every((it, i) => b[i] === it);
90
+ if (!intersects) {
91
+ // NOTE(EvanBacon): Adds more context to the error message since we know about the
92
+ // file-based routing.
93
+ const last = config.pattern.split('/').pop();
94
+ const routeType = last?.startsWith(':')
95
+ ? 'dynamic route'
96
+ : last?.startsWith('*')
97
+ ? 'dynamic-rest route'
98
+ : 'route';
99
+ throw new Error(`The ${routeType} pattern '${config.pattern || '/'}' resolves to both '${alpha.userReadableName}' and '${config.userReadableName}'. Patterns must be unique and cannot resolve to more than one route.`);
100
+ }
101
+ }
102
+ return Object.assign(acc, {
103
+ [indexedKey]: config,
104
+ });
105
+ }, {});
106
+ }
107
+ function sortConfigs(a, b) {
108
+ // Sort config so that:
109
+ // - the most exhaustive ones are always at the beginning
110
+ // - patterns with wildcard are always at the end
111
+ // If 2 patterns are same, move the one with less route names up
112
+ // This is an error state, so it's only useful for consistent error messages
113
+ if (a.pattern === b.pattern) {
114
+ return b.routeNames.join('>').localeCompare(a.routeNames.join('>'));
115
+ }
116
+ // If one of the patterns starts with the other, it's more exhaustive
117
+ // So move it up
118
+ if (a.pattern.startsWith(b.pattern) &&
119
+ // NOTE(EvanBacon): This is a hack to make sure that `*` is always at the end
120
+ b.screen !== 'index') {
121
+ return -1;
122
+ }
123
+ if (b.pattern.startsWith(a.pattern) && a.screen !== 'index') {
124
+ return 1;
125
+ }
126
+ // NOTE(EvanBacon): Here we append `index` if the screen was `index` so the length is the same
127
+ // as a slug or wildcard when nested more than one level deep.
128
+ // This is so we can compare the length of the pattern, e.g. `foo/*` > `foo` vs `*` < ``.
129
+ const aParts = a.pattern
130
+ .split('/')
131
+ // Strip out group names to ensure they don't affect the priority.
132
+ .filter((part) => matchGroupName(part) == null);
133
+ if (a.screen === 'index') {
134
+ aParts.push('index');
135
+ }
136
+ const bParts = b.pattern.split('/').filter((part) => matchGroupName(part) == null);
137
+ if (b.screen === 'index') {
138
+ bParts.push('index');
139
+ }
140
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
141
+ // if b is longer, b get higher priority
142
+ if (aParts[i] == null) {
143
+ return 1;
144
+ }
145
+ // if a is longer, a get higher priority
146
+ if (bParts[i] == null) {
147
+ return -1;
148
+ }
149
+ const aWildCard = aParts[i].startsWith('*');
150
+ const bWildCard = bParts[i].startsWith('*');
151
+ // if both are wildcard we compare next component
152
+ if (aWildCard && bWildCard) {
153
+ continue;
154
+ }
155
+ // if only a is wild card, b get higher priority
156
+ if (aWildCard) {
157
+ return 1;
158
+ }
159
+ // if only b is wild card, a get higher priority
160
+ if (bWildCard) {
161
+ return -1;
162
+ }
163
+ const aSlug = aParts[i].startsWith(':');
164
+ const bSlug = bParts[i].startsWith(':');
165
+ // if both are wildcard we compare next component
166
+ if (aSlug && bSlug) {
167
+ continue;
168
+ }
169
+ // if only a is wild card, b get higher priority
170
+ if (aSlug) {
171
+ return 1;
172
+ }
173
+ // if only b is wild card, a get higher priority
174
+ if (bSlug) {
175
+ return -1;
176
+ }
177
+ }
178
+ // Sort initial routes with a higher priority than routes which will push more screens
179
+ // this ensures shared routes go to the shortest path.
180
+ if (a.isInitial && !b.isInitial) {
181
+ return -1;
182
+ }
183
+ if (!a.isInitial && b.isInitial) {
184
+ return 1;
185
+ }
186
+ return bParts.length - aParts.length;
187
+ }
188
+ function getStateFromEmptyPathWithConfigs(path, configs, initialRoutes) {
189
+ // We need to add special handling of empty path so navigation to empty path also works
190
+ // When handling empty path, we should only look at the root level config
191
+ // NOTE(EvanBacon): We only care about matching leaf nodes.
192
+ const leafNodes = configs
193
+ .filter((config) => !config.hasChildren)
194
+ .map((value) => {
195
+ return {
196
+ ...value,
197
+ // Collapse all levels of group segments before testing.
198
+ // This enables `app/(one)/(two)/index.js` to be matched.
199
+ path: stripGroupSegmentsFromPath(value.path),
200
+ };
201
+ });
202
+ const match = leafNodes.find((config) =>
203
+ // NOTE(EvanBacon): Test leaf node index routes that either don't have a regex or match an empty string.
204
+ config.path === '' && (!config.regex || config.regex.test(''))) ??
205
+ leafNodes.find((config) =>
206
+ // NOTE(EvanBacon): Test leaf node dynamic routes that match an empty string.
207
+ config.path.startsWith(':') && config.regex.test('')) ??
208
+ // NOTE(EvanBacon): Test leaf node deep dynamic routes that match a slash.
209
+ // This should be done last to enable dynamic routes having a higher priority.
210
+ leafNodes.find((config) => config.path.startsWith('*') && config.regex.test('/'));
211
+ if (!match) {
212
+ return undefined;
213
+ }
214
+ const routes = match.routeNames.map((name) => {
215
+ if (!match._route) {
216
+ return { name };
217
+ }
218
+ return {
219
+ name,
220
+ _route: match._route,
221
+ };
222
+ });
223
+ return createNestedStateObject(path, routes, configs, initialRoutes);
224
+ }
225
+ function getStateFromPathWithConfigs(path, configs, initialRoutes) {
226
+ const formattedPaths = getUrlWithReactNavigationConcessions(path);
227
+ if (formattedPaths.nonstandardPathname === '/') {
228
+ return getStateFromEmptyPathWithConfigs(formattedPaths.inputPathnameWithoutHash, configs, initialRoutes);
229
+ }
230
+ // We match the whole path against the regex instead of segments
231
+ // This makes sure matches such as wildcard will catch any unmatched routes, even if nested
232
+ const routes = matchAgainstConfigs(formattedPaths.nonstandardPathname, configs);
233
+ if (routes == null) {
234
+ return undefined;
235
+ }
236
+ // This will always be empty if full path matched
237
+ return createNestedStateObject(formattedPaths.inputPathnameWithoutHash, routes, configs, initialRoutes);
238
+ }
239
+ const joinPaths = (...paths) => []
240
+ .concat(...paths.map((p) => p.split('/')))
241
+ .filter(Boolean)
242
+ .join('/');
243
+ function matchAgainstConfigs(remaining, configs) {
244
+ let routes;
245
+ let remainingPath = remaining;
246
+ // Go through all configs, and see if the next path segment matches our regex
247
+ for (const config of configs) {
248
+ if (!config.regex) {
249
+ continue;
250
+ }
251
+ const match = remainingPath.match(config.regex);
252
+ // If our regex matches, we need to extract params from the path
253
+ if (!match) {
254
+ continue;
255
+ }
256
+ // TODO: Add support for wildcard routes
257
+ const matchedParams = config.pattern
258
+ ?.split('/')
259
+ .filter((p) => p.match(/^[:*]/))
260
+ .reduce((acc, p, i) => {
261
+ if (p.match(/^\*/)) {
262
+ return {
263
+ ...acc,
264
+ [p]: match[(i + 1) * 2], //?.replace(/\//, ""),
265
+ };
266
+ }
267
+ return Object.assign(acc, {
268
+ // The param segments appear every second item starting from 2 in the regex match result.
269
+ // This will only work if we ensure groups aren't included in the match.
270
+ [p]: match[(i + 1) * 2]?.replace(/\//, ''),
271
+ });
272
+ }, {});
273
+ const routeFromName = (name) => {
274
+ const config = configs.find((c) => c.screen === name);
275
+ if (!config?.path) {
276
+ return { name };
277
+ }
278
+ const segments = config.path.split('/');
279
+ const params = {};
280
+ segments
281
+ .filter((p) => p.match(/^[:*]/))
282
+ .forEach((p) => {
283
+ let value = matchedParams[p];
284
+ if (value) {
285
+ if (p.match(/^\*/)) {
286
+ // Convert to an array before providing as a route.
287
+ value = value?.split('/').filter(Boolean);
288
+ }
289
+ const key = p.replace(/^[:*]/, '').replace(/\?$/, '');
290
+ params[key] = config.parse?.[key] ? config.parse[key](value) : value;
291
+ }
292
+ });
293
+ if (params && Object.keys(params).length) {
294
+ return { name, params };
295
+ }
296
+ return { name };
297
+ };
298
+ routes = config.routeNames.map((name) => {
299
+ if (!config._route) {
300
+ return { ...routeFromName(name) };
301
+ }
302
+ return {
303
+ ...routeFromName(name),
304
+ _route: config._route,
305
+ };
306
+ });
307
+ // TODO(EvanBacon): Maybe we should warn / assert if multiple slugs use the same param name.
308
+ const combinedParams = routes.reduce((acc, r) => Object.assign(acc, r.params), {});
309
+ const hasCombinedParams = Object.keys(combinedParams).length > 0;
310
+ // Combine all params so a route `[foo]/[bar]/other.js` has access to `{ foo, bar }`
311
+ routes = routes.map((r) => {
312
+ if (hasCombinedParams) {
313
+ r.params = combinedParams;
314
+ }
315
+ return r;
316
+ });
317
+ remainingPath = remainingPath.replace(match[1], '');
318
+ break;
319
+ }
320
+ return routes;
321
+ }
322
+ function equalHeritage(a, b) {
323
+ if (a.length !== b.length) {
324
+ return false;
325
+ }
326
+ for (let i = 0; i < a.length; i++) {
327
+ if (a[i].localeCompare(b[i]) !== 0) {
328
+ return false;
329
+ }
330
+ }
331
+ return true;
332
+ }
333
+ const createNormalizedConfigs = (screen, routeConfig, routeNames = [], initials = [], parentScreens = [], parentPattern) => {
334
+ const configs = [];
335
+ routeNames.push(screen);
336
+ parentScreens.push(screen);
337
+ const config = routeConfig[screen];
338
+ if (typeof config === 'string') {
339
+ // TODO: This should never happen with the addition of `_route`
340
+ // If a string is specified as the value of the key(e.g. Foo: '/path'), use it as the pattern
341
+ const pattern = parentPattern ? joinPaths(parentPattern, config) : config;
342
+ configs.push(createConfigItem(screen, routeNames, pattern, config, false));
343
+ }
344
+ else if (typeof config === 'object') {
345
+ let pattern;
346
+ const { _route } = config;
347
+ // if an object is specified as the value (e.g. Foo: { ... }),
348
+ // it can have `path` property and
349
+ // it could have `screens` prop which has nested configs
350
+ if (typeof config.path === 'string') {
351
+ if (config.exact && config.path === undefined) {
352
+ throw new Error("A 'path' needs to be specified when specifying 'exact: true'. If you don't want this screen in the URL, specify it as empty string, e.g. `path: ''`.");
353
+ }
354
+ pattern =
355
+ config.exact !== true
356
+ ? joinPaths(parentPattern || '', config.path || '')
357
+ : config.path || '';
358
+ configs.push(createConfigItem(screen, routeNames, pattern, config.path, config.screens ? !!Object.keys(config.screens)?.length : false, config.parse, _route));
359
+ }
360
+ if (config.screens) {
361
+ // property `initialRouteName` without `screens` has no purpose
362
+ if (config.initialRouteName) {
363
+ initials.push({
364
+ initialRouteName: config.initialRouteName,
365
+ parentScreens,
366
+ });
367
+ }
368
+ Object.keys(config.screens).forEach((nestedConfig) => {
369
+ const result = createNormalizedConfigs(nestedConfig, config.screens, routeNames, initials, [...parentScreens], pattern ?? parentPattern);
370
+ configs.push(...result);
371
+ });
372
+ }
373
+ }
374
+ routeNames.pop();
375
+ return configs;
376
+ };
377
+ function formatRegexPattern(it) {
378
+ // Allow spaces in file path names.
379
+ it = it.replace(' ', '%20');
380
+ if (it.startsWith(':')) {
381
+ // TODO: Remove unused match group
382
+ return `(([^/]+\\/)${it.endsWith('?') ? '?' : ''})`;
383
+ }
384
+ else if (it.startsWith('*')) {
385
+ return `((.*\\/)${it.endsWith('?') ? '?' : ''})`;
386
+ }
387
+ // Strip groups from the matcher
388
+ if (matchGroupName(it) != null) {
389
+ // Groups are optional segments
390
+ // this enables us to match `/bar` and `/(foo)/bar` for the same route
391
+ // NOTE(EvanBacon): Ignore this match in the regex to avoid capturing the group
392
+ return `(?:${escape(it)}\\/)?`;
393
+ }
394
+ return escape(it) + `\\/`;
395
+ }
396
+ const createConfigItem = (screen, routeNames, pattern, path, hasChildren, parse, _route) => {
397
+ // Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc.
398
+ pattern = pattern.split('/').filter(Boolean).join('/');
399
+ const regex = pattern
400
+ ? new RegExp(`^(${pattern.split('/').map(formatRegexPattern).join('')})$`)
401
+ : undefined;
402
+ return {
403
+ screen,
404
+ regex,
405
+ pattern,
406
+ path,
407
+ // The routeNames array is mutated, so copy it to keep the current state
408
+ routeNames: [...routeNames],
409
+ parse,
410
+ userReadableName: [...routeNames.slice(0, -1), path || screen].join('/'),
411
+ hasChildren: !!hasChildren,
412
+ _route,
413
+ };
414
+ };
415
+ const findParseConfigForRoute = (routeName, routeConfigs) => {
416
+ for (const config of routeConfigs) {
417
+ if (routeName === config.routeNames[config.routeNames.length - 1]) {
418
+ return config.parse;
419
+ }
420
+ }
421
+ return undefined;
422
+ };
423
+ // Try to find an initial route connected with the one passed
424
+ const findInitialRoute = (routeName, parentScreens, initialRoutes) => {
425
+ for (const config of initialRoutes) {
426
+ if (equalHeritage(parentScreens, config.parentScreens)) {
427
+ // If the parents are the same but the route name doesn't match the initial route
428
+ // then we return the initial route.
429
+ return routeName !== config.initialRouteName ? config.initialRouteName : undefined;
430
+ }
431
+ }
432
+ return undefined;
433
+ };
434
+ // returns state object with values depending on whether
435
+ // it is the end of state and if there is initialRoute for this level
436
+ const createStateObject = (initialRoute, route, isEmpty) => {
437
+ if (isEmpty) {
438
+ if (initialRoute) {
439
+ return {
440
+ index: 1,
441
+ routes: [{ name: initialRoute }, route],
442
+ };
443
+ }
444
+ return {
445
+ routes: [route],
446
+ };
447
+ }
448
+ if (initialRoute) {
449
+ return {
450
+ index: 1,
451
+ routes: [{ name: initialRoute }, { ...route, state: { routes: [] } }],
452
+ };
453
+ }
454
+ return {
455
+ routes: [{ ...route, state: { routes: [] } }],
456
+ };
457
+ };
458
+ const createNestedStateObject = (path, routes, routeConfigs, initialRoutes) => {
459
+ let route = routes.shift();
460
+ const parentScreens = [];
461
+ let initialRoute = findInitialRoute(route.name, parentScreens, initialRoutes);
462
+ parentScreens.push(route.name);
463
+ const state = createStateObject(initialRoute, route, routes.length === 0);
464
+ if (routes.length > 0) {
465
+ let nestedState = state;
466
+ while ((route = routes.shift())) {
467
+ initialRoute = findInitialRoute(route.name, parentScreens, initialRoutes);
468
+ const nestedStateIndex = nestedState.index || nestedState.routes.length - 1;
469
+ nestedState.routes[nestedStateIndex].state = createStateObject(initialRoute, route, routes.length === 0);
470
+ if (routes.length > 0) {
471
+ nestedState = nestedState.routes[nestedStateIndex].state;
472
+ }
473
+ parentScreens.push(route.name);
474
+ }
475
+ }
476
+ route = findFocusedRoute(state);
477
+ // Remove groups from the path while preserving a trailing slash.
478
+ route.path = stripGroupSegmentsFromPath(path);
479
+ const params = parseQueryParams(route.path, findParseConfigForRoute(route.name, routeConfigs));
480
+ if (params) {
481
+ const resolvedParams = { ...route.params, ...params };
482
+ if (Object.keys(resolvedParams).length > 0) {
483
+ route.params = resolvedParams;
484
+ }
485
+ else {
486
+ delete route.params;
487
+ }
488
+ }
489
+ return state;
490
+ };
491
+ const parseQueryParams = (path, parseConfig) => {
492
+ const query = path.split('?')[1];
493
+ const params = queryString.parse(query);
494
+ if (parseConfig) {
495
+ Object.keys(params).forEach((name) => {
496
+ if (Object.hasOwnProperty.call(parseConfig, name) && typeof params[name] === 'string') {
497
+ params[name] = parseConfig[name](params[name]);
498
+ }
499
+ });
500
+ }
501
+ return Object.keys(params).length ? params : undefined;
502
+ };
503
+ //# sourceMappingURL=getStateFromPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getStateFromPath.js","sourceRoot":"","sources":["../../src/fork/getStateFromPath.ts"],"names":[],"mappings":"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","sourcesContent":["import { PathConfigMap } from '@react-navigation/core';\nimport type { InitialState, NavigationState, PartialState } from '@react-navigation/routers';\nimport escape from 'escape-string-regexp';\nimport * as queryString from 'query-string';\nimport URL from 'url-parse';\n\nimport { RouteNode } from '../Route';\nimport { matchGroupName, stripGroupSegmentsFromPath } from '../matchers';\nimport { findFocusedRoute } from './findFocusedRoute';\nimport validatePathConfig from './validatePathConfig';\n\ntype Options<ParamList extends object> = {\n initialRouteName?: string;\n screens: PathConfigMap<ParamList>;\n};\n\ntype ParseConfig = Record<string, (value: string) => any>;\n\ntype RouteConfig = {\n isInitial?: boolean;\n screen: string;\n regex?: RegExp;\n path: string;\n pattern: string;\n routeNames: string[];\n parse?: ParseConfig;\n hasChildren: boolean;\n userReadableName: string;\n _route?: RouteNode;\n};\n\ntype InitialRouteConfig = {\n initialRouteName: string;\n parentScreens: string[];\n};\n\nexport type ResultState = PartialState<NavigationState> & {\n state?: ResultState;\n};\n\ntype ParsedRoute = {\n name: string;\n path?: string;\n params?: Record<string, any> | undefined;\n};\n\nexport function getUrlWithReactNavigationConcessions(path: string) {\n const parsed = new URL(path, 'https://acme.com');\n const pathname = parsed.pathname;\n\n // Make sure there is a trailing slash\n return {\n // The slashes are at the end, not the beginning\n nonstandardPathname: pathname.replace(/^\\/+/g, '').replace(/\\/+$/g, '') + '/',\n // React Navigation doesn't support hashes, so here\n inputPathnameWithoutHash: path.replace(/#.*$/, ''),\n };\n}\n\n/**\n * Utility to parse a path string to initial state object accepted by the container.\n * This is useful for deep linking when we need to handle the incoming URL.\n *\n * @example\n * ```js\n * getStateFromPath(\n * '/chat/jane/42',\n * {\n * screens: {\n * Chat: {\n * path: 'chat/:author/:id',\n * parse: { id: Number }\n * }\n * }\n * }\n * )\n * ```\n * @param path Path string to parse and convert, e.g. /foo/bar?count=42.\n * @param options Extra options to fine-tune how to parse the path.\n */\nexport default function getStateFromPath<ParamList extends object>(\n path: string,\n options?: Options<ParamList>\n): ResultState | undefined {\n const { initialRoutes, configs } = getMatchableRouteConfigs(options);\n\n return getStateFromPathWithConfigs(path, configs, initialRoutes);\n}\n\nexport function getMatchableRouteConfigs<ParamList extends object>(options?: Options<ParamList>) {\n if (options) {\n validatePathConfig(options);\n }\n\n const screens = options?.screens;\n // Expo Router disallows usage without a linking config.\n if (!screens) {\n throw Error(\"You must pass a 'screens' object to 'getStateFromPath' to generate a path.\");\n }\n\n // This will be mutated...\n const initialRoutes: InitialRouteConfig[] = [];\n\n if (options?.initialRouteName) {\n initialRoutes.push({\n initialRouteName: options.initialRouteName,\n parentScreens: [],\n });\n }\n\n // Create a normalized configs array which will be easier to use.\n const converted = Object.keys(screens)\n .map((key) => createNormalizedConfigs(key, screens, [], initialRoutes))\n .flat();\n\n const resolvedInitialPatterns = initialRoutes.map((route) =>\n joinPaths(...route.parentScreens, route.initialRouteName)\n );\n\n const convertedWithInitial = converted.map((config) => ({\n ...config,\n // TODO(EvanBacon): Probably a safer way to do this\n // Mark initial routes to give them potential priority over other routes that match.\n isInitial: resolvedInitialPatterns.includes(config.routeNames.join('/')),\n }));\n\n // Sort in order of resolution. This is extremely important for the algorithm to work.\n const configs = convertedWithInitial.sort(sortConfigs);\n\n // Assert any duplicates before we start parsing.\n assertConfigDuplicates(configs);\n\n return { configs, initialRoutes };\n}\n\nfunction assertConfigDuplicates(configs: RouteConfig[]) {\n // Check for duplicate patterns in the config\n configs.reduce<Record<string, RouteConfig>>((acc, config) => {\n // NOTE(EvanBacon): Uses the regex pattern as key to detect duplicate slugs.\n const indexedKey = config.regex?.toString() ?? config.pattern;\n const alpha = acc[indexedKey];\n // NOTE(EvanBacon): Skips checking nodes that have children.\n if (alpha && !alpha.hasChildren && !config.hasChildren) {\n const a = alpha.routeNames;\n const b = config.routeNames;\n\n // It's not a problem if the path string omitted from a inner most screen\n // For example, it's ok if a path resolves to `A > B > C` or `A > B`\n const intersects =\n a.length > b.length ? b.every((it, i) => a[i] === it) : a.every((it, i) => b[i] === it);\n\n if (!intersects) {\n // NOTE(EvanBacon): Adds more context to the error message since we know about the\n // file-based routing.\n const last = config.pattern.split('/').pop();\n const routeType = last?.startsWith(':')\n ? 'dynamic route'\n : last?.startsWith('*')\n ? 'dynamic-rest route'\n : 'route';\n throw new Error(\n `The ${routeType} pattern '${config.pattern || '/'}' resolves to both '${\n alpha.userReadableName\n }' and '${\n config.userReadableName\n }'. Patterns must be unique and cannot resolve to more than one route.`\n );\n }\n }\n\n return Object.assign(acc, {\n [indexedKey]: config,\n });\n }, {});\n}\n\nfunction sortConfigs(a: RouteConfig, b: RouteConfig): number {\n // Sort config so that:\n // - the most exhaustive ones are always at the beginning\n // - patterns with wildcard are always at the end\n\n // If 2 patterns are same, move the one with less route names up\n // This is an error state, so it's only useful for consistent error messages\n if (a.pattern === b.pattern) {\n return b.routeNames.join('>').localeCompare(a.routeNames.join('>'));\n }\n\n // If one of the patterns starts with the other, it's more exhaustive\n // So move it up\n if (\n a.pattern.startsWith(b.pattern) &&\n // NOTE(EvanBacon): This is a hack to make sure that `*` is always at the end\n b.screen !== 'index'\n ) {\n return -1;\n }\n\n if (b.pattern.startsWith(a.pattern) && a.screen !== 'index') {\n return 1;\n }\n\n // NOTE(EvanBacon): Here we append `index` if the screen was `index` so the length is the same\n // as a slug or wildcard when nested more than one level deep.\n // This is so we can compare the length of the pattern, e.g. `foo/*` > `foo` vs `*` < ``.\n const aParts = a.pattern\n .split('/')\n // Strip out group names to ensure they don't affect the priority.\n .filter((part) => matchGroupName(part) == null);\n if (a.screen === 'index') {\n aParts.push('index');\n }\n\n const bParts = b.pattern.split('/').filter((part) => matchGroupName(part) == null);\n if (b.screen === 'index') {\n bParts.push('index');\n }\n\n for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {\n // if b is longer, b get higher priority\n if (aParts[i] == null) {\n return 1;\n }\n // if a is longer, a get higher priority\n if (bParts[i] == null) {\n return -1;\n }\n const aWildCard = aParts[i].startsWith('*');\n const bWildCard = bParts[i].startsWith('*');\n // if both are wildcard we compare next component\n if (aWildCard && bWildCard) {\n continue;\n }\n // if only a is wild card, b get higher priority\n if (aWildCard) {\n return 1;\n }\n // if only b is wild card, a get higher priority\n if (bWildCard) {\n return -1;\n }\n\n const aSlug = aParts[i].startsWith(':');\n const bSlug = bParts[i].startsWith(':');\n // if both are wildcard we compare next component\n if (aSlug && bSlug) {\n continue;\n }\n // if only a is wild card, b get higher priority\n if (aSlug) {\n return 1;\n }\n // if only b is wild card, a get higher priority\n if (bSlug) {\n return -1;\n }\n }\n\n // Sort initial routes with a higher priority than routes which will push more screens\n // this ensures shared routes go to the shortest path.\n if (a.isInitial && !b.isInitial) {\n return -1;\n }\n if (!a.isInitial && b.isInitial) {\n return 1;\n }\n\n return bParts.length - aParts.length;\n}\n\nfunction getStateFromEmptyPathWithConfigs(\n path: string,\n configs: RouteConfig[],\n initialRoutes: InitialRouteConfig[]\n): ResultState | undefined {\n // We need to add special handling of empty path so navigation to empty path also works\n // When handling empty path, we should only look at the root level config\n\n // NOTE(EvanBacon): We only care about matching leaf nodes.\n const leafNodes = configs\n .filter((config) => !config.hasChildren)\n .map((value) => {\n return {\n ...value,\n // Collapse all levels of group segments before testing.\n // This enables `app/(one)/(two)/index.js` to be matched.\n path: stripGroupSegmentsFromPath(value.path),\n };\n });\n\n const match =\n leafNodes.find(\n (config) =>\n // NOTE(EvanBacon): Test leaf node index routes that either don't have a regex or match an empty string.\n config.path === '' && (!config.regex || config.regex.test(''))\n ) ??\n leafNodes.find(\n (config) =>\n // NOTE(EvanBacon): Test leaf node dynamic routes that match an empty string.\n config.path.startsWith(':') && config.regex!.test('')\n ) ??\n // NOTE(EvanBacon): Test leaf node deep dynamic routes that match a slash.\n // This should be done last to enable dynamic routes having a higher priority.\n leafNodes.find((config) => config.path.startsWith('*') && config.regex!.test('/'));\n\n if (!match) {\n return undefined;\n }\n\n const routes = match.routeNames.map((name) => {\n if (!match._route) {\n return { name };\n }\n return {\n name,\n _route: match._route,\n };\n });\n\n return createNestedStateObject(path, routes, configs, initialRoutes);\n}\n\nfunction getStateFromPathWithConfigs(\n path: string,\n configs: RouteConfig[],\n initialRoutes: InitialRouteConfig[]\n): ResultState | undefined {\n const formattedPaths = getUrlWithReactNavigationConcessions(path);\n\n if (formattedPaths.nonstandardPathname === '/') {\n return getStateFromEmptyPathWithConfigs(\n formattedPaths.inputPathnameWithoutHash,\n configs,\n initialRoutes\n );\n }\n\n // We match the whole path against the regex instead of segments\n // This makes sure matches such as wildcard will catch any unmatched routes, even if nested\n const routes = matchAgainstConfigs(formattedPaths.nonstandardPathname, configs);\n\n if (routes == null) {\n return undefined;\n }\n // This will always be empty if full path matched\n return createNestedStateObject(\n formattedPaths.inputPathnameWithoutHash,\n routes,\n configs,\n initialRoutes\n );\n}\n\nconst joinPaths = (...paths: string[]): string =>\n ([] as string[])\n .concat(...paths.map((p) => p.split('/')))\n .filter(Boolean)\n .join('/');\n\nfunction matchAgainstConfigs(remaining: string, configs: RouteConfig[]): ParsedRoute[] | undefined {\n let routes: ParsedRoute[] | undefined;\n let remainingPath = remaining;\n\n // Go through all configs, and see if the next path segment matches our regex\n for (const config of configs) {\n if (!config.regex) {\n continue;\n }\n\n const match = remainingPath.match(config.regex);\n\n // If our regex matches, we need to extract params from the path\n if (!match) {\n continue;\n }\n\n // TODO: Add support for wildcard routes\n const matchedParams = config.pattern\n ?.split('/')\n .filter((p) => p.match(/^[:*]/))\n .reduce<Record<string, any>>((acc, p, i) => {\n if (p.match(/^\\*/)) {\n return {\n ...acc,\n [p]: match![(i + 1) * 2], //?.replace(/\\//, \"\"),\n };\n }\n return Object.assign(acc, {\n // The param segments appear every second item starting from 2 in the regex match result.\n // This will only work if we ensure groups aren't included in the match.\n [p]: match![(i + 1) * 2]?.replace(/\\//, ''),\n });\n }, {});\n\n const routeFromName = (name: string) => {\n const config = configs.find((c) => c.screen === name);\n if (!config?.path) {\n return { name };\n }\n\n const segments = config.path.split('/');\n\n const params: Record<string, any> = {};\n\n segments\n .filter((p) => p.match(/^[:*]/))\n .forEach((p) => {\n let value = matchedParams[p];\n if (value) {\n if (p.match(/^\\*/)) {\n // Convert to an array before providing as a route.\n value = value?.split('/').filter(Boolean);\n }\n\n const key = p.replace(/^[:*]/, '').replace(/\\?$/, '');\n params[key] = config.parse?.[key] ? config.parse[key](value) : value;\n }\n });\n\n if (params && Object.keys(params).length) {\n return { name, params };\n }\n\n return { name };\n };\n\n routes = config.routeNames.map((name) => {\n if (!config._route) {\n return { ...routeFromName(name) };\n }\n return {\n ...routeFromName(name),\n _route: config._route,\n };\n });\n\n // TODO(EvanBacon): Maybe we should warn / assert if multiple slugs use the same param name.\n const combinedParams = routes.reduce<Record<string, any>>(\n (acc, r) => Object.assign(acc, r.params),\n {}\n );\n\n const hasCombinedParams = Object.keys(combinedParams).length > 0;\n\n // Combine all params so a route `[foo]/[bar]/other.js` has access to `{ foo, bar }`\n routes = routes.map((r) => {\n if (hasCombinedParams) {\n r.params = combinedParams;\n }\n return r;\n });\n\n remainingPath = remainingPath.replace(match[1], '');\n\n break;\n }\n\n return routes;\n}\n\nfunction equalHeritage(a: string[], b: string[]): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i].localeCompare(b[i]) !== 0) {\n return false;\n }\n }\n return true;\n}\n\nconst createNormalizedConfigs = (\n screen: string,\n routeConfig: PathConfigMap<object>,\n routeNames: string[] = [],\n initials: InitialRouteConfig[] = [],\n parentScreens: string[] = [],\n parentPattern?: string\n): RouteConfig[] => {\n const configs: RouteConfig[] = [];\n\n routeNames.push(screen);\n\n parentScreens.push(screen);\n\n const config = (routeConfig as any)[screen];\n\n if (typeof config === 'string') {\n // TODO: This should never happen with the addition of `_route`\n\n // If a string is specified as the value of the key(e.g. Foo: '/path'), use it as the pattern\n const pattern = parentPattern ? joinPaths(parentPattern, config) : config;\n\n configs.push(createConfigItem(screen, routeNames, pattern, config, false));\n } else if (typeof config === 'object') {\n let pattern: string | undefined;\n\n const { _route } = config;\n // if an object is specified as the value (e.g. Foo: { ... }),\n // it can have `path` property and\n // it could have `screens` prop which has nested configs\n if (typeof config.path === 'string') {\n if (config.exact && config.path === undefined) {\n throw new Error(\n \"A 'path' needs to be specified when specifying 'exact: true'. If you don't want this screen in the URL, specify it as empty string, e.g. `path: ''`.\"\n );\n }\n\n pattern =\n config.exact !== true\n ? joinPaths(parentPattern || '', config.path || '')\n : config.path || '';\n\n configs.push(\n createConfigItem(\n screen,\n routeNames,\n pattern!,\n config.path,\n config.screens ? !!Object.keys(config.screens)?.length : false,\n config.parse,\n _route\n )\n );\n }\n\n if (config.screens) {\n // property `initialRouteName` without `screens` has no purpose\n if (config.initialRouteName) {\n initials.push({\n initialRouteName: config.initialRouteName,\n parentScreens,\n });\n }\n\n Object.keys(config.screens).forEach((nestedConfig) => {\n const result = createNormalizedConfigs(\n nestedConfig,\n config.screens as PathConfigMap<object>,\n routeNames,\n initials,\n [...parentScreens],\n pattern ?? parentPattern\n );\n\n configs.push(...result);\n });\n }\n }\n\n routeNames.pop();\n\n return configs;\n};\n\nfunction formatRegexPattern(it: string): string {\n // Allow spaces in file path names.\n it = it.replace(' ', '%20');\n\n if (it.startsWith(':')) {\n // TODO: Remove unused match group\n return `(([^/]+\\\\/)${it.endsWith('?') ? '?' : ''})`;\n } else if (it.startsWith('*')) {\n return `((.*\\\\/)${it.endsWith('?') ? '?' : ''})`;\n }\n\n // Strip groups from the matcher\n if (matchGroupName(it) != null) {\n // Groups are optional segments\n // this enables us to match `/bar` and `/(foo)/bar` for the same route\n // NOTE(EvanBacon): Ignore this match in the regex to avoid capturing the group\n return `(?:${escape(it)}\\\\/)?`;\n }\n\n return escape(it) + `\\\\/`;\n}\n\nconst createConfigItem = (\n screen: string,\n routeNames: string[],\n pattern: string,\n path: string,\n hasChildren?: boolean,\n parse?: ParseConfig,\n _route?: any\n): RouteConfig => {\n // Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc.\n pattern = pattern.split('/').filter(Boolean).join('/');\n\n const regex = pattern\n ? new RegExp(`^(${pattern.split('/').map(formatRegexPattern).join('')})$`)\n : undefined;\n\n return {\n screen,\n regex,\n pattern,\n path,\n // The routeNames array is mutated, so copy it to keep the current state\n routeNames: [...routeNames],\n parse,\n userReadableName: [...routeNames.slice(0, -1), path || screen].join('/'),\n hasChildren: !!hasChildren,\n _route,\n };\n};\n\nconst findParseConfigForRoute = (\n routeName: string,\n routeConfigs: RouteConfig[]\n): ParseConfig | undefined => {\n for (const config of routeConfigs) {\n if (routeName === config.routeNames[config.routeNames.length - 1]) {\n return config.parse;\n }\n }\n\n return undefined;\n};\n\n// Try to find an initial route connected with the one passed\nconst findInitialRoute = (\n routeName: string,\n parentScreens: string[],\n initialRoutes: InitialRouteConfig[]\n): string | undefined => {\n for (const config of initialRoutes) {\n if (equalHeritage(parentScreens, config.parentScreens)) {\n // If the parents are the same but the route name doesn't match the initial route\n // then we return the initial route.\n return routeName !== config.initialRouteName ? config.initialRouteName : undefined;\n }\n }\n return undefined;\n};\n\n// returns state object with values depending on whether\n// it is the end of state and if there is initialRoute for this level\nconst createStateObject = (\n initialRoute: string | undefined,\n route: ParsedRoute,\n isEmpty: boolean\n): InitialState => {\n if (isEmpty) {\n if (initialRoute) {\n return {\n index: 1,\n routes: [{ name: initialRoute }, route],\n };\n }\n return {\n routes: [route],\n };\n }\n\n if (initialRoute) {\n return {\n index: 1,\n routes: [{ name: initialRoute }, { ...route, state: { routes: [] } }],\n };\n }\n return {\n routes: [{ ...route, state: { routes: [] } }],\n };\n};\n\nconst createNestedStateObject = (\n path: string,\n routes: ParsedRoute[],\n routeConfigs: RouteConfig[],\n initialRoutes: InitialRouteConfig[]\n) => {\n let route = routes.shift() as ParsedRoute;\n const parentScreens: string[] = [];\n\n let initialRoute = findInitialRoute(route.name, parentScreens, initialRoutes);\n\n parentScreens.push(route.name);\n\n const state: InitialState = createStateObject(initialRoute, route, routes.length === 0);\n\n if (routes.length > 0) {\n let nestedState = state;\n\n while ((route = routes.shift() as ParsedRoute)) {\n initialRoute = findInitialRoute(route.name, parentScreens, initialRoutes);\n\n const nestedStateIndex = nestedState.index || nestedState.routes.length - 1;\n\n nestedState.routes[nestedStateIndex].state = createStateObject(\n initialRoute,\n route,\n routes.length === 0\n );\n\n if (routes.length > 0) {\n nestedState = nestedState.routes[nestedStateIndex].state as InitialState;\n }\n\n parentScreens.push(route.name);\n }\n }\n\n route = findFocusedRoute(state) as ParsedRoute;\n\n // Remove groups from the path while preserving a trailing slash.\n route.path = stripGroupSegmentsFromPath(path);\n\n const params = parseQueryParams(route.path, findParseConfigForRoute(route.name, routeConfigs));\n\n if (params) {\n const resolvedParams = { ...route.params, ...params };\n if (Object.keys(resolvedParams).length > 0) {\n route.params = resolvedParams;\n } else {\n delete route.params;\n }\n }\n\n return state;\n};\n\nconst parseQueryParams = (path: string, parseConfig?: Record<string, (value: string) => any>) => {\n const query = path.split('?')[1];\n const params = queryString.parse(query);\n\n if (parseConfig) {\n Object.keys(params).forEach((name) => {\n if (Object.hasOwnProperty.call(parseConfig, name) && typeof params[name] === 'string') {\n params[name] = parseConfig[name](params[name] as string);\n }\n });\n }\n\n return Object.keys(params).length ? params : undefined;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useLinking.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.ts"],"names":[],"mappings":";AAGA,wBAA0E"}
1
+ {"version":3,"file":"useLinking.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.ts"],"names":[],"mappings":";AAEA,wBAA0E"}
@@ -0,0 +1,3 @@
1
+ import useLinking from '@react-navigation/native/lib/module/useLinking';
2
+ export default useLinking;
3
+ //# sourceMappingURL=useLinking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLinking.js","sourceRoot":"","sources":["../../src/fork/useLinking.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,gDAAgD,CAAC;AAExE,eAAe,UAA0D,CAAC","sourcesContent":["import useLinking from '@react-navigation/native/lib/module/useLinking';\n\nexport default useLinking as typeof import('./useLinking.native').default;\n"]}
@@ -1,6 +1,6 @@
1
- import { NavigationContainerRef, ParamListBase } from "@react-navigation/core";
2
- import type { LinkingOptions } from "@react-navigation/native";
3
- import * as React from "react";
1
+ import { NavigationContainerRef, ParamListBase } from '@react-navigation/core';
2
+ import type { LinkingOptions } from '@react-navigation/native';
3
+ import * as React from 'react';
4
4
  type Options = LinkingOptions<ParamListBase>;
5
5
  export default function useLinking(ref: React.RefObject<NavigationContainerRef<ParamListBase>>, { filter, config, getInitialURL, subscribe, getStateFromPath, getActionFromState, }: Options): {
6
6
  getInitialState: () => PromiseLike<(Partial<Omit<Readonly<{
@@ -1 +1 @@
1
- {"version":3,"file":"useLinking.native.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.native.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,sBAAsB,EACtB,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,KAAK,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;AAI7C,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,EAC3D,EAGE,MAAM,EACN,MAAM,EACN,aAQI,EACJ,SAUC,EACD,gBAA0C,EAC1C,kBAA8C,GAC/C,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4KX"}
1
+ {"version":3,"file":"useLinking.native.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.native.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,sBAAsB,EACtB,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,KAAK,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;AAI7C,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,EAC3D,EAGE,MAAM,EACN,MAAM,EACN,aAQI,EACJ,SAUC,EACD,gBAA0C,EAC1C,kBAA8C,GAC/C,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqKX"}