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.
- package/README.md +1 -1
- package/{_ctx.android.tsx → _ctx.android.js} +1 -2
- package/_ctx.d.ts +3 -0
- package/{_ctx.ios.tsx → _ctx.ios.js} +1 -2
- package/_ctx.js +1 -0
- package/{_ctx.web.tsx → _ctx.web.js} +1 -2
- package/_error.js +2 -4
- package/app.plugin.js +1 -1
- package/babel.js +44 -55
- package/build/ExpoRoot.d.ts +2 -2
- package/build/ExpoRoot.d.ts.map +1 -1
- package/build/ExpoRoot.js +79 -0
- package/build/ExpoRoot.js.map +1 -0
- package/build/LocationProvider.d.ts +2 -2
- package/build/LocationProvider.d.ts.map +1 -1
- package/build/LocationProvider.js +30 -0
- package/build/LocationProvider.js.map +1 -0
- package/build/Route.d.ts +3 -3
- package/build/Route.d.ts.map +1 -1
- package/build/Route.js +68 -0
- package/build/Route.js.map +1 -0
- package/build/exports.d.ts +12 -12
- package/build/exports.js +17 -0
- package/build/exports.js.map +1 -0
- package/build/fork/NavigationContainer.d.ts +1 -1
- package/build/fork/NavigationContainer.js +4 -0
- package/build/fork/NavigationContainer.js.map +1 -0
- package/build/fork/NavigationContainer.native.d.ts +3 -3
- package/build/fork/NavigationContainer.native.d.ts.map +1 -1
- package/build/fork/NavigationContainer.native.js +81 -0
- package/build/fork/NavigationContainer.native.js.map +1 -0
- package/build/fork/expo/createRoot.d.ts +1 -1
- package/build/fork/expo/createRoot.js +2 -0
- package/build/fork/expo/createRoot.js.map +1 -0
- package/{src/fork/expo/createRoot.native.tsx → build/fork/expo/createRoot.native.js} +3 -2
- package/build/fork/expo/createRoot.native.js.map +1 -0
- package/build/fork/expo/registerRootComponent.d.ts +3 -3
- package/build/fork/expo/registerRootComponent.js +51 -0
- package/build/fork/expo/registerRootComponent.js.map +1 -0
- package/build/fork/extractPathFromURL.d.ts.map +1 -1
- package/build/fork/extractPathFromURL.js +76 -0
- package/build/fork/extractPathFromURL.js.map +1 -0
- package/build/fork/findFocusedRoute.d.ts +1 -1
- package/build/fork/findFocusedRoute.js +10 -0
- package/build/fork/findFocusedRoute.js.map +1 -0
- package/build/fork/getPathFromState.d.ts +3 -3
- package/build/fork/getPathFromState.d.ts.map +1 -1
- package/build/fork/getPathFromState.js +419 -0
- package/build/fork/getPathFromState.js.map +1 -0
- package/build/fork/getStateFromPath.d.ts +3 -3
- package/build/fork/getStateFromPath.d.ts.map +1 -1
- package/build/fork/getStateFromPath.js +503 -0
- package/build/fork/getStateFromPath.js.map +1 -0
- package/build/fork/useLinking.d.ts.map +1 -1
- package/build/fork/useLinking.js +3 -0
- package/build/fork/useLinking.js.map +1 -0
- package/build/fork/useLinking.native.d.ts +3 -3
- package/build/fork/useLinking.native.d.ts.map +1 -1
- package/build/fork/useLinking.native.js +154 -0
- package/build/fork/useLinking.native.js.map +1 -0
- package/build/fork/validatePathConfig.d.ts.map +1 -1
- package/build/fork/validatePathConfig.js +19 -0
- package/build/fork/validatePathConfig.js.map +1 -0
- package/build/getDevServer/index.js +30 -0
- package/build/getDevServer/index.js.map +1 -0
- package/build/getDevServer/index.native.js +2 -0
- package/build/getDevServer/index.native.js.map +1 -0
- package/build/getLinkingConfig.d.ts +4 -4
- package/build/getLinkingConfig.d.ts.map +1 -1
- package/build/getLinkingConfig.js +43 -0
- package/build/getLinkingConfig.js.map +1 -0
- package/build/getReactNavigationConfig.d.ts +1 -1
- package/build/getReactNavigationConfig.d.ts.map +1 -1
- package/build/getReactNavigationConfig.js +69 -0
- package/build/getReactNavigationConfig.js.map +1 -0
- package/build/getRoutes.d.ts +4 -4
- package/build/getRoutes.d.ts.map +1 -1
- package/build/getRoutes.js +378 -0
- package/build/getRoutes.js.map +1 -0
- package/build/global-state/router-store.d.ts +15 -16
- package/build/global-state/router-store.d.ts.map +1 -1
- package/build/global-state/router-store.js +179 -0
- package/build/global-state/router-store.js.map +1 -0
- package/build/global-state/routing.d.ts +6 -6
- package/build/global-state/routing.d.ts.map +1 -1
- package/build/global-state/routing.js +149 -0
- package/build/global-state/routing.js.map +1 -0
- package/build/global-state/sort-routes.d.ts +1 -1
- package/build/global-state/sort-routes.d.ts.map +1 -1
- package/build/global-state/sort-routes.js +8 -0
- package/build/global-state/sort-routes.js.map +1 -0
- package/build/head/ExpoHead.android.d.ts +10 -0
- package/build/head/ExpoHead.android.d.ts.map +1 -0
- package/build/head/ExpoHead.android.js +6 -0
- package/build/head/ExpoHead.android.js.map +1 -0
- package/build/head/ExpoHead.d.ts +8 -0
- package/build/head/ExpoHead.d.ts.map +1 -0
- package/build/head/ExpoHead.ios.d.ts +7 -0
- package/build/head/ExpoHead.ios.d.ts.map +1 -0
- package/build/head/ExpoHead.ios.js +242 -0
- package/build/head/ExpoHead.ios.js.map +1 -0
- package/build/head/ExpoHead.js +7 -0
- package/build/head/ExpoHead.js.map +1 -0
- package/build/head/ExpoHeadModule.d.ts +33 -0
- package/build/head/ExpoHeadModule.d.ts.map +1 -0
- package/build/head/ExpoHeadModule.js +4 -0
- package/build/head/ExpoHeadModule.js.map +1 -0
- package/build/head/ExpoHeadModule.native.d.ts +3 -0
- package/build/head/ExpoHeadModule.native.d.ts.map +1 -0
- package/build/head/ExpoHeadModule.native.js +10 -0
- package/build/head/ExpoHeadModule.native.js.map +1 -0
- package/build/head/index.d.ts +2 -0
- package/build/head/index.d.ts.map +1 -0
- package/build/head/index.js +2 -0
- package/build/head/index.js.map +1 -0
- package/build/head/url.d.ts +2 -0
- package/build/head/url.d.ts.map +1 -0
- package/build/head/url.js +64 -0
- package/build/head/url.js.map +1 -0
- package/build/hooks.d.ts +1 -1
- package/build/hooks.d.ts.map +1 -1
- package/{src/hooks.ts → build/hooks.js} +34 -66
- package/build/hooks.js.map +1 -0
- package/build/imperative-api.d.ts +1 -1
- package/build/imperative-api.js +9 -0
- package/build/imperative-api.js.map +1 -0
- package/{src/import-mode/index.android.ts → build/import-mode/index.android.js} +1 -0
- package/build/import-mode/index.android.js.map +1 -0
- package/{src/import-mode/index.ios.ts → build/import-mode/index.ios.js} +1 -0
- package/build/import-mode/index.ios.js.map +1 -0
- package/build/import-mode/index.js +2 -0
- package/build/import-mode/index.js.map +1 -0
- package/{src/import-mode/index.web.ts → build/import-mode/index.web.js} +1 -0
- package/build/import-mode/index.web.js.map +1 -0
- package/build/index.d.ts +3 -3
- package/build/index.js +4 -0
- package/build/index.js.map +1 -0
- package/build/layouts/Drawer.d.ts +1 -1
- package/build/layouts/Drawer.d.ts.map +1 -1
- package/build/layouts/Drawer.js +6 -0
- package/build/layouts/Drawer.js.map +1 -0
- package/build/layouts/Stack.d.ts +1 -1
- package/build/layouts/Stack.d.ts.map +1 -1
- package/build/layouts/Stack.js +6 -0
- package/build/layouts/Stack.js.map +1 -0
- package/build/layouts/Tabs.d.ts +4 -4
- package/build/layouts/Tabs.d.ts.map +1 -1
- package/build/layouts/Tabs.js +34 -0
- package/build/layouts/Tabs.js.map +1 -0
- package/build/layouts/withLayoutContext.d.ts +4 -4
- package/build/layouts/withLayoutContext.d.ts.map +1 -1
- package/build/layouts/withLayoutContext.js +65 -0
- package/build/layouts/withLayoutContext.js.map +1 -0
- package/build/link/Link.d.ts +5 -5
- package/build/link/Link.d.ts.map +1 -1
- package/build/link/Link.js +63 -0
- package/build/link/Link.js.map +1 -0
- package/build/link/href.d.ts.map +1 -1
- package/build/link/href.js +46 -0
- package/build/link/href.js.map +1 -0
- package/build/link/linking.d.ts +2 -2
- package/build/link/linking.d.ts.map +1 -1
- package/build/link/linking.js +86 -0
- package/build/link/linking.js.map +1 -0
- package/build/link/path.d.ts.map +1 -1
- package/build/link/path.js +143 -0
- package/build/link/path.js.map +1 -0
- package/build/link/stateOperations.d.ts +3 -3
- package/build/link/stateOperations.js +91 -0
- package/build/link/stateOperations.js.map +1 -0
- package/build/link/useLinkToPathProps.d.ts +2 -2
- package/build/link/useLinkToPathProps.d.ts.map +1 -1
- package/build/link/useLinkToPathProps.js +45 -0
- package/build/link/useLinkToPathProps.js.map +1 -0
- package/build/link/useLoadedNavigation.d.ts +1 -1
- package/build/link/useLoadedNavigation.js +46 -0
- package/build/link/useLoadedNavigation.js.map +1 -0
- package/build/loadStaticParamsAsync.d.ts +1 -1
- package/build/loadStaticParamsAsync.d.ts.map +1 -1
- package/build/loadStaticParamsAsync.js +117 -0
- package/build/loadStaticParamsAsync.js.map +1 -0
- package/build/matchers.js +49 -0
- package/build/matchers.js.map +1 -0
- package/build/onboard/Tutorial.d.ts.map +1 -1
- package/build/onboard/Tutorial.js +155 -0
- package/build/onboard/Tutorial.js.map +1 -0
- package/{src/onboard/createEntryFile.ts → build/onboard/createEntryFile.js} +19 -22
- package/build/onboard/createEntryFile.js.map +1 -0
- package/build/primitives.js +5 -0
- package/build/primitives.js.map +1 -0
- package/build/qualified-entry.d.ts +3 -0
- package/build/qualified-entry.d.ts.map +1 -0
- package/{_app.tsx → build/qualified-entry.js} +7 -10
- package/build/qualified-entry.js.map +1 -0
- package/build/renderRootComponent.d.ts +1 -1
- package/build/renderRootComponent.d.ts.map +1 -1
- package/build/renderRootComponent.js +72 -0
- package/build/renderRootComponent.js.map +1 -0
- package/build/static/getRootComponent.d.ts.map +1 -1
- package/build/static/getRootComponent.js +22 -0
- package/build/static/getRootComponent.js.map +1 -0
- package/build/static/html.d.ts +1 -1
- package/build/static/html.js +25 -0
- package/build/static/html.js.map +1 -0
- package/build/static/renderStaticContent.d.ts +6 -1
- package/build/static/renderStaticContent.d.ts.map +1 -1
- package/build/static/renderStaticContent.js +85 -0
- package/build/static/renderStaticContent.js.map +1 -0
- package/build/testing-library/context-stubs.d.ts +1 -1
- package/build/testing-library/context-stubs.d.ts.map +1 -1
- package/build/testing-library/context-stubs.js +30 -0
- package/build/testing-library/context-stubs.js.map +1 -0
- package/build/testing-library/expect.js +14 -0
- package/build/testing-library/expect.js.map +1 -0
- package/build/testing-library/index.d.ts +4 -4
- package/build/testing-library/index.d.ts.map +1 -1
- package/build/testing-library/index.js +57 -0
- package/build/testing-library/index.js.map +1 -0
- package/build/testing-library/mocks.d.ts +1 -1
- package/build/testing-library/mocks.js +33 -0
- package/build/testing-library/mocks.js.map +1 -0
- package/build/testing-library/require-context-ponyfill.d.ts +1 -1
- package/build/testing-library/require-context-ponyfill.js +29 -0
- package/build/testing-library/require-context-ponyfill.js.map +1 -0
- package/build/types.d.ts +1 -1
- package/build/types.d.ts.map +1 -1
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/useDeprecated.d.ts +3 -0
- package/build/useDeprecated.d.ts.map +1 -0
- package/build/useDeprecated.js +23 -0
- package/build/useDeprecated.js.map +1 -0
- package/build/useFocusEffect.d.ts.map +1 -1
- package/build/useFocusEffect.js +98 -0
- package/build/useFocusEffect.js.map +1 -0
- package/build/useNavigation.d.ts +1 -1
- package/build/useNavigation.d.ts.map +1 -1
- package/build/useNavigation.js +63 -0
- package/build/useNavigation.js.map +1 -0
- package/build/useScreens.d.ts +4 -4
- package/build/useScreens.d.ts.map +1 -1
- package/build/useScreens.js +183 -0
- package/build/useScreens.js.map +1 -0
- package/build/utils/mockState.d.ts +1 -1
- package/build/utils/mockState.d.ts.map +1 -1
- package/build/utils/mockState.js +24 -0
- package/build/utils/mockState.js.map +1 -0
- package/{src/utils/url.ts → build/utils/url.js} +3 -2
- package/build/utils/url.js.map +1 -0
- package/build/views/EmptyRoute.js +9 -0
- package/build/views/EmptyRoute.js.map +1 -0
- package/build/views/ErrorBoundary.d.ts +1 -1
- package/build/views/ErrorBoundary.d.ts.map +1 -1
- package/build/views/ErrorBoundary.js +124 -0
- package/build/views/ErrorBoundary.js.map +1 -0
- package/build/views/Navigator.d.ts +11 -11
- package/build/views/Navigator.d.ts.map +1 -1
- package/build/views/Navigator.js +87 -0
- package/build/views/Navigator.js.map +1 -0
- package/build/views/Screen.d.ts.map +1 -1
- package/build/views/Screen.js +30 -0
- package/build/views/Screen.js.map +1 -0
- package/build/views/Sitemap.d.ts +1 -1
- package/build/views/Sitemap.d.ts.map +1 -1
- package/build/views/Sitemap.js +156 -0
- package/build/views/Sitemap.js.map +1 -0
- package/build/views/Splash.d.ts.map +1 -1
- package/build/views/Splash.js +109 -0
- package/build/views/Splash.js.map +1 -0
- package/build/views/SuspenseFallback.d.ts +1 -1
- package/build/views/SuspenseFallback.js +7 -0
- package/build/views/SuspenseFallback.js.map +1 -0
- package/build/views/Toast.d.ts +1 -1
- package/build/views/Toast.d.ts.map +1 -1
- package/build/views/Toast.js +73 -0
- package/build/views/Toast.js.map +1 -0
- package/build/views/Try.d.ts +1 -1
- package/build/views/Try.js +27 -0
- package/build/views/Try.js.map +1 -0
- package/build/views/Unmatched.d.ts.map +1 -1
- package/build/views/Unmatched.js +72 -0
- package/build/views/Unmatched.js.map +1 -0
- package/drawer.d.ts +2 -0
- package/drawer.js +1 -0
- package/entry.js +4 -5
- package/expo-module.config.json +8 -0
- package/head.d.ts +1 -0
- package/head.js +1 -0
- package/html.js +1 -0
- package/ios/ExpoHead.podspec +32 -0
- package/ios/ExpoHeadAppDelegateSubscriber.swift +94 -0
- package/ios/ExpoHeadModule.swift +186 -0
- package/node/getExpoConstantsManifest.js +22 -38
- package/node/render.js +1 -1
- package/package.json +42 -39
- package/plugin/build/index.d.ts +1 -1
- package/plugin/build/index.js +4 -2
- package/plugin/jest.config.js +1 -0
- package/stack.d.ts +2 -0
- package/stack.js +1 -0
- package/tabs.d.ts +2 -0
- package/tabs.js +1 -0
- package/testing-library.d.ts +1 -0
- package/testing-library.js +1 -0
- package/types/expect.d.ts +1 -1
- package/types/global.d.ts +7 -7
- package/types/metro-require.d.ts +1 -1
- package/types/react-native-web.d.ts +16 -20
- package/_ctx.tsx +0 -5
- package/_entry.tsx +0 -33
- package/_html-ctx.tsx +0 -9
- package/drawer.ts +0 -2
- package/head.ts +0 -6
- package/html.ts +0 -1
- package/plugin/src/index.ts +0 -54
- package/src/ExpoRoot.tsx +0 -116
- package/src/LocationProvider.tsx +0 -52
- package/src/Route.tsx +0 -120
- package/src/exports.ts +0 -34
- package/src/fork/NavigationContainer.native.tsx +0 -159
- package/src/fork/NavigationContainer.tsx +0 -4
- package/src/fork/expo/createRoot.tsx +0 -1
- package/src/fork/expo/registerRootComponent.tsx +0 -77
- package/src/fork/extractPathFromURL.ts +0 -103
- package/src/fork/findFocusedRoute.tsx +0 -15
- package/src/fork/getPathFromState.ts +0 -647
- package/src/fork/getStateFromPath.ts +0 -776
- package/src/fork/useLinking.native.ts +0 -224
- package/src/fork/useLinking.ts +0 -4
- package/src/fork/validatePathConfig.ts +0 -32
- package/src/getDevServer/index.native.ts +0 -1
- package/src/getDevServer/index.ts +0 -37
- package/src/getLinkingConfig.ts +0 -69
- package/src/getReactNavigationConfig.ts +0 -103
- package/src/getRoutes.ts +0 -520
- package/src/global-state/router-store.tsx +0 -256
- package/src/global-state/routing.ts +0 -213
- package/src/global-state/sort-routes.ts +0 -12
- package/src/imperative-api.ts +0 -10
- package/src/import-mode/index.ts +0 -1
- package/src/index.tsx +0 -3
- package/src/layouts/Drawer.tsx +0 -15
- package/src/layouts/Stack.tsx +0 -15
- package/src/layouts/Tabs.tsx +0 -61
- package/src/layouts/withLayoutContext.tsx +0 -114
- package/src/link/Link.tsx +0 -104
- package/src/link/href.ts +0 -60
- package/src/link/linking.ts +0 -106
- package/src/link/path.ts +0 -141
- package/src/link/stateOperations.ts +0 -152
- package/src/link/useLinkToPathProps.tsx +0 -60
- package/src/link/useLoadedNavigation.ts +0 -60
- package/src/loadStaticParamsAsync.ts +0 -196
- package/src/matchers.tsx +0 -56
- package/src/onboard/Tutorial.tsx +0 -202
- package/src/primitives.tsx +0 -5
- package/src/renderRootComponent.tsx +0 -87
- package/src/static/getRootComponent.ts +0 -28
- package/src/static/html.tsx +0 -38
- package/src/static/renderStaticContent.tsx +0 -103
- package/src/testing-library/context-stubs.ts +0 -52
- package/src/testing-library/expect.ts +0 -15
- package/src/testing-library/index.tsx +0 -103
- package/src/testing-library/mocks.ts +0 -39
- package/src/testing-library/require-context-ponyfill.ts +0 -44
- package/src/ts-declarations.d.ts +0 -1
- package/src/types.ts +0 -30
- package/src/useFocusEffect.tsx +0 -121
- package/src/useNavigation.ts +0 -84
- package/src/useScreens.tsx +0 -297
- package/src/utils/mockState.ts +0 -31
- package/src/views/EmptyRoute.tsx +0 -16
- package/src/views/ErrorBoundary.tsx +0 -175
- package/src/views/Navigator.tsx +0 -164
- package/src/views/Screen.tsx +0 -51
- package/src/views/Sitemap.tsx +0 -270
- package/src/views/Splash.tsx +0 -125
- package/src/views/SuspenseFallback.tsx +0 -12
- package/src/views/Toast.tsx +0 -102
- package/src/views/Try.tsx +0 -46
- package/src/views/Unmatched.tsx +0 -105
- package/stack.ts +0 -2
- 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":";
|
|
1
|
+
{"version":3,"file":"useLinking.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.ts"],"names":[],"mappings":";AAEA,wBAA0E"}
|
|
@@ -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
|
|
2
|
-
import type { LinkingOptions } from
|
|
3
|
-
import * as React from
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
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"}
|