expo-router 0.0.41 → 0.0.43
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/babel.js +42 -7
- package/build/ContextNavigator.js +0 -1
- package/build/ContextNavigator.js.map +1 -1
- package/build/LocationProvider.d.ts +4 -2
- package/build/LocationProvider.d.ts.map +1 -1
- package/build/LocationProvider.js +21 -18
- package/build/LocationProvider.js.map +1 -1
- package/build/exports.d.ts +6 -1
- package/build/exports.d.ts.map +1 -1
- package/build/exports.js +7 -1
- package/build/exports.js.map +1 -1
- package/build/fork/getPathFromState.js +40 -29
- package/build/fork/getPathFromState.js.map +1 -1
- package/build/fork/getStateFromPath.d.ts.map +1 -1
- package/build/fork/getStateFromPath.js +16 -1
- package/build/fork/getStateFromPath.js.map +1 -1
- package/build/getLinkingConfig.d.ts.map +1 -1
- package/build/getLinkingConfig.js +2 -0
- package/build/getLinkingConfig.js.map +1 -1
- package/build/getRoutes.d.ts.map +1 -1
- package/build/getRoutes.js +12 -10
- package/build/getRoutes.js.map +1 -1
- package/build/useScreens.d.ts +2 -4
- package/build/useScreens.d.ts.map +1 -1
- package/build/useScreens.js +11 -4
- package/build/useScreens.js.map +1 -1
- package/build/views/Layout.d.ts +11 -11
- package/build/views/Layout.d.ts.map +1 -1
- package/build/views/Layout.js +29 -26
- package/build/views/Layout.js.map +1 -1
- package/node/getExpoConstantsManifest.js +179 -0
- package/package.json +4 -3
package/babel.js
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
const nodePath = require("path");
|
|
2
2
|
const resolveFrom = require("resolve-from");
|
|
3
|
+
const { getExpoConstantsManifest } = require("./node/getExpoConstantsManifest");
|
|
3
4
|
|
|
4
5
|
const debug = require("debug")("expo:router:babel");
|
|
5
6
|
|
|
7
|
+
function getExpoAppManifest(projectRoot) {
|
|
8
|
+
if (process.env.APP_MANIFEST) {
|
|
9
|
+
return process.env.APP_MANIFEST;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const exp = getExpoConstantsManifest(projectRoot);
|
|
13
|
+
|
|
14
|
+
debug("public manifest", exp);
|
|
15
|
+
|
|
16
|
+
return JSON.stringify(exp);
|
|
17
|
+
}
|
|
18
|
+
|
|
6
19
|
function getExpoRouterAppRoot(projectRoot) {
|
|
7
20
|
if (process.env.EXPO_ROUTER_APP_ROOT) {
|
|
8
21
|
return process.env.EXPO_ROUTER_APP_ROOT;
|
|
@@ -35,7 +48,17 @@ module.exports = function (api) {
|
|
|
35
48
|
// Add support for Node.js __filename
|
|
36
49
|
Identifier(path, state) {
|
|
37
50
|
if (path.node.name === "__filename") {
|
|
38
|
-
path.replaceWith(
|
|
51
|
+
path.replaceWith(
|
|
52
|
+
t.stringLiteral(
|
|
53
|
+
// `/index.js` is the value used by Webpack.
|
|
54
|
+
getRelPath(state)
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
// Add support for Node.js `__dirname`.
|
|
59
|
+
// This static value comes from Webpack somewhere.
|
|
60
|
+
if (path.node.name === "__dirname") {
|
|
61
|
+
path.replaceWith(t.stringLiteral("/"));
|
|
39
62
|
}
|
|
40
63
|
},
|
|
41
64
|
|
|
@@ -53,6 +76,9 @@ module.exports = function (api) {
|
|
|
53
76
|
return;
|
|
54
77
|
}
|
|
55
78
|
|
|
79
|
+
const projectRoot =
|
|
80
|
+
process.env.EXPO_PROJECT_ROOT || state.file.opts.root || "";
|
|
81
|
+
|
|
56
82
|
// Used for log box and stuff
|
|
57
83
|
if (
|
|
58
84
|
t.isIdentifier(parent.node.property, {
|
|
@@ -60,11 +86,20 @@ module.exports = function (api) {
|
|
|
60
86
|
}) &&
|
|
61
87
|
!parent.parentPath.isAssignmentExpression()
|
|
62
88
|
) {
|
|
63
|
-
parent.replaceWith(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
89
|
+
parent.replaceWith(t.stringLiteral(projectRoot));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Surfaces the `app.json` (config) as an environment variable which is then parsed by
|
|
94
|
+
// `expo-constants` https://docs.expo.dev/versions/latest/sdk/constants/
|
|
95
|
+
if (
|
|
96
|
+
t.isIdentifier(parent.node.property, {
|
|
97
|
+
name: "APP_MANIFEST",
|
|
98
|
+
}) &&
|
|
99
|
+
!parent.parentPath.isAssignmentExpression()
|
|
100
|
+
) {
|
|
101
|
+
const manifest = getExpoAppManifest(projectRoot);
|
|
102
|
+
parent.replaceWith(t.stringLiteral(manifest));
|
|
68
103
|
return;
|
|
69
104
|
}
|
|
70
105
|
|
|
@@ -82,7 +117,7 @@ module.exports = function (api) {
|
|
|
82
117
|
|
|
83
118
|
parent.replaceWith(
|
|
84
119
|
// This is defined in Expo CLI when using Metro. It points to the relative path for the project app directory.
|
|
85
|
-
t.stringLiteral(getExpoRouterAppRoot(
|
|
120
|
+
t.stringLiteral(getExpoRouterAppRoot(projectRoot))
|
|
86
121
|
);
|
|
87
122
|
},
|
|
88
123
|
},
|
|
@@ -31,7 +31,6 @@ export function ContextNavigator({ context }) {
|
|
|
31
31
|
function RootRoute() {
|
|
32
32
|
const root = useRootRouteNodeContext();
|
|
33
33
|
const Component = getQualifiedRouteComponent(root);
|
|
34
|
-
// @ts-expect-error: TODO: Drop navigation and route props
|
|
35
34
|
return React.createElement(Component, null);
|
|
36
35
|
}
|
|
37
36
|
//# sourceMappingURL=ContextNavigator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextNavigator.js","sourceRoot":"","sources":["../src/ContextNavigator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,SAAS,wBAAwB,CAAC,OAAuB;IACvD,4CAA4C;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,qBAAqB,CAAC,EAC7B,OAAO,EACP,QAAQ,GAIT;IACC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CACL,oBAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,IACzC,QAAQ,CACqB,CACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAA+B;IACvE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,QAAQ,EAAE;QACZ,YAAY,CAAC,SAAS,EAAE,CAAC;QACzB,OAAO,oBAAC,QAAQ,OAAG,CAAC;KACrB;IAED,OAAO,CACL,oBAAC,qBAAqB,IAAC,OAAO,EAAE,OAAO;QACrC,oBAAC,0BAA0B;YACzB,oBAAC,wBAAwB;gBACvB,oBAAC,gBAAgB;oBACf,oBAAC,SAAS,OAAG,CACI,CACM,CACA,CACP,CACzB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,uBAAuB,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC;IACnD,
|
|
1
|
+
{"version":3,"file":"ContextNavigator.js","sourceRoot":"","sources":["../src/ContextNavigator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,SAAS,wBAAwB,CAAC,OAAuB;IACvD,4CAA4C;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,qBAAqB,CAAC,EAC7B,OAAO,EACP,QAAQ,GAIT;IACC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CACL,oBAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,IACzC,QAAQ,CACqB,CACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAA+B;IACvE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,QAAQ,EAAE;QACZ,YAAY,CAAC,SAAS,EAAE,CAAC;QACzB,OAAO,oBAAC,QAAQ,OAAG,CAAC;KACrB;IAED,OAAO,CACL,oBAAC,qBAAqB,IAAC,OAAO,EAAE,OAAO;QACrC,oBAAC,0BAA0B;YACzB,oBAAC,wBAAwB;gBACvB,oBAAC,gBAAgB;oBACf,oBAAC,SAAS,OAAG,CACI,CACM,CACA,CACP,CACzB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,uBAAuB,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC;IACnD,OAAO,oBAAC,SAAS,OAAG,CAAC;AACvB,CAAC","sourcesContent":["import React, { useMemo } from \"react\";\n\nimport { ContextNavigationContainer } from \"./ContextNavigationContainer\";\nimport { LocationProvider } from \"./LocationProvider\";\nimport { RootRouteNodeContext, useRootRouteNodeContext } from \"./context\";\nimport { getRoutes } from \"./getRoutes\";\nimport { useTutorial } from \"./onboard/useTutorial\";\nimport { InitialRootStateProvider } from \"./rootStateContext\";\nimport { RequireContext } from \"./types\";\nimport { getQualifiedRouteComponent } from \"./useScreens\";\nimport { SplashScreen } from \"./views/Splash\";\n\nfunction useContextModuleAsRoutes(context: RequireContext) {\n // TODO: Is this an optimal hook dependency?\n const keys = useMemo(() => context.keys(), [context]);\n return useMemo(() => getRoutes(context), [keys]);\n}\n\nfunction RootRouteNodeProvider({\n context,\n children,\n}: {\n context: RequireContext;\n children: React.ReactNode;\n}) {\n const routes = useContextModuleAsRoutes(context);\n return (\n <RootRouteNodeContext.Provider value={routes}>\n {children}\n </RootRouteNodeContext.Provider>\n );\n}\n\nexport function ContextNavigator({ context }: { context: RequireContext }) {\n const Tutorial = useTutorial(context);\n if (Tutorial) {\n SplashScreen.hideAsync();\n return <Tutorial />;\n }\n\n return (\n <RootRouteNodeProvider context={context}>\n <ContextNavigationContainer>\n <InitialRootStateProvider>\n <LocationProvider>\n <RootRoute />\n </LocationProvider>\n </InitialRootStateProvider>\n </ContextNavigationContainer>\n </RootRouteNodeProvider>\n );\n}\n\nfunction RootRoute() {\n const root = useRootRouteNodeContext();\n const Component = getQualifiedRouteComponent(root);\n return <Component />;\n}\n"]}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
declare type SearchParams = Record<string, string>;
|
|
2
3
|
export declare function LocationProvider({ children }: {
|
|
3
4
|
children: React.ReactNode;
|
|
4
5
|
}): JSX.Element;
|
|
5
6
|
/** @returns Currently selected route as a normalized string without search parameters. e.g. `/acme?foo=bar` -> `/acme`. Segments will be normalized: `/[id]?id=normal` -> `/normal` */
|
|
6
7
|
export declare function usePathname(): string;
|
|
7
8
|
/** @returns Current URL Search Parameters. */
|
|
8
|
-
export declare function useSearchParams():
|
|
9
|
-
/** @returns
|
|
9
|
+
export declare function useSearchParams(): SearchParams;
|
|
10
|
+
/** @returns Array of selected segments. */
|
|
10
11
|
export declare function useSegments(): string[];
|
|
12
|
+
export {};
|
|
11
13
|
//# sourceMappingURL=LocationProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationProvider.d.ts","sourceRoot":"","sources":["../src/LocationProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"LocationProvider.d.ts","sourceRoot":"","sources":["../src/LocationProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,aAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA0I3C,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,eAM3E;AAcD,uLAAuL;AACvL,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,8CAA8C;AAC9C,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAEtC"}
|
|
@@ -4,30 +4,25 @@ import { useLinkingContext } from "./link/useLinkingContext";
|
|
|
4
4
|
import { useInitialRootStateContext } from "./rootStateContext";
|
|
5
5
|
function getRouteInfoFromState(getPathFromState, state) {
|
|
6
6
|
const path = getPathFromState(state, false);
|
|
7
|
+
const qualified = getPathFromState(state, true);
|
|
7
8
|
return {
|
|
8
9
|
pathname: path.split("?")["0"],
|
|
9
|
-
|
|
10
|
-
...getNormalizedStatePath(getPathFromState(state, true)),
|
|
10
|
+
...getNormalizedStatePath(qualified),
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function compareRouteInfo(a, b) {
|
|
14
|
+
return (a.segments.length === b.segments.length &&
|
|
15
|
+
a.segments.every((segment, index) => segment === b.segments[index]) &&
|
|
16
|
+
a.pathname === b.pathname &&
|
|
17
|
+
compareUrlSearchParams(a.params, b.params));
|
|
18
|
+
}
|
|
19
|
+
function compareUrlSearchParams(a, b) {
|
|
14
20
|
const aKeys = Object.keys(a);
|
|
15
21
|
const bKeys = Object.keys(b);
|
|
16
22
|
if (aKeys.length !== bKeys.length) {
|
|
17
23
|
return false;
|
|
18
24
|
}
|
|
19
|
-
|
|
20
|
-
if (a[key] !== b[key]) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
function compareRouteInfo(a, b) {
|
|
27
|
-
return (a.segments.length === b.segments.length &&
|
|
28
|
-
a.segments.every((segment, index) => segment === b.segments[index]) &&
|
|
29
|
-
a.pathname === b.pathname &&
|
|
30
|
-
compareShallowRecords(a.params, b.params));
|
|
25
|
+
return aKeys.every((key) => a[key] === b[key]);
|
|
31
26
|
}
|
|
32
27
|
function useUrlObject() {
|
|
33
28
|
const initialRootState = useInitialRootStateContext();
|
|
@@ -81,9 +76,18 @@ function getNormalizedStatePath(statePath) {
|
|
|
81
76
|
segments: pathname.split("/").filter(Boolean),
|
|
82
77
|
// TODO: This is not efficient, we should generate based on the state instead
|
|
83
78
|
// of converting to string then back to object
|
|
84
|
-
params:
|
|
79
|
+
params: queryStringToObject(querystring),
|
|
85
80
|
};
|
|
86
81
|
}
|
|
82
|
+
function queryStringToObject(queryString) {
|
|
83
|
+
return (queryString
|
|
84
|
+
?.split("&")
|
|
85
|
+
.map((pair) => pair.split("="))
|
|
86
|
+
.reduce((acc, [key, value]) => {
|
|
87
|
+
acc[key] = value;
|
|
88
|
+
return acc;
|
|
89
|
+
}, {}) ?? {});
|
|
90
|
+
}
|
|
87
91
|
const LocationContext = React.createContext(undefined);
|
|
88
92
|
if (process.env.NODE_ENV !== "production") {
|
|
89
93
|
LocationContext.displayName = "LocationContext";
|
|
@@ -104,10 +108,9 @@ export function usePathname() {
|
|
|
104
108
|
}
|
|
105
109
|
/** @returns Current URL Search Parameters. */
|
|
106
110
|
export function useSearchParams() {
|
|
107
|
-
// TODO: Make this readonly
|
|
108
111
|
return useLocation().params;
|
|
109
112
|
}
|
|
110
|
-
/** @returns
|
|
113
|
+
/** @returns Array of selected segments. */
|
|
111
114
|
export function useSegments() {
|
|
112
115
|
return useLocation().segments;
|
|
113
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationProvider.js","sourceRoot":"","sources":["../src/LocationProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"LocationProvider.js","sourceRoot":"","sources":["../src/LocationProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAUhE,SAAS,qBAAqB,CAC5B,gBAA2D,EAC3D,KAAY;IAEZ,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChD,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC9B,GAAG,sBAAsB,CAAC,SAAS,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAY,EAAE,CAAY;IAClD,OAAO,CACL,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM;QACvC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACnE,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;QACzB,sBAAsB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAC3C,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,CAAe,EAAE,CAAe;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE7B,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;QACjC,OAAO,KAAK,CAAC;KACd;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,gBAAgB,GAAG,0BAA0B,EAAE,CAAC;IACtD,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAE/C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAC9C,qBAAqB,CACnB,gBAAgB;IAChB,+EAA+E;IAC/E,4FAA4F;IAC5F,aAAa,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,IAAI,gBAAgB,CAC1D,CACF,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE7C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,YAAY,CAAC,OAAO,GAAG,SAAS,CAAC;IACnC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,oBAAoB,GAAG,KAAK,CAAC,WAAW,CAC5C,CAAC,KAAY,EAAE,EAAE;QACf,8BAA8B;QAC9B,MAAM,YAAY,GAAG,qBAAqB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACpE,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE;YACzD,YAAY,CAAC,YAAY,CAAC,CAAC;SAC5B;IACH,CAAC,EACD;QACE,oCAAoC;QACpC,gBAAgB;KACjB,CACF,CAAC;IAEF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;QAE9C,OAAO,cAAc,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;YACtD,kFAAkF;YAClF,0CAA0C;YAC1C,MAAM,eAAe,GACnB,cAAc,CAAC,YAAY,EAAE,IAAK,IAAI,CAAC,KAA0B,CAAC;YACpE,oFAAoF;YACpF,oBAAoB,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAE3B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,OAAO,KAAK,CAAC,WAAW,CACtB,CAAC,KAA6C,EAAE,MAAe,EAAE,EAAE;QACjE,OAAO,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE;YACrC,GAAG,OAAO,CAAC,MAAM;YACjB,mBAAmB;YACnB,qBAAqB,EAAE,MAAM;YAC7B,cAAc,EAAE,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,SAAS,sBAAsB,CAC7B,SAAiB;IAEjB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAErD,OAAO;QACL,gCAAgC;QAChC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC7C,6EAA6E;QAC7E,8CAA8C;QAC9C,MAAM,EAAE,mBAAmB,CAAC,WAAW,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAoB;IAC/C,OAAO,CACL,WAAW;QACT,EAAE,KAAK,CAAC,GAAG,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC9B,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAkB,CAAC,IAAI,EAAE,CAC/B,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CAAwB,SAAS,CAAC,CAAC;AAE9E,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;IACzC,eAAe,CAAC,WAAW,GAAG,iBAAiB,CAAC;CACjD;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAiC;IAC1E,OAAO,CACL,oBAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,EAAE,IAC5C,QAAQ,CACgB,CAC5B,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAEnD,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;KACH;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,uLAAuL;AACvL,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,EAAE,CAAC,QAAQ,CAAC;AAChC,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,eAAe;IAC7B,OAAO,WAAW,EAAE,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,EAAE,CAAC,QAAQ,CAAC;AAChC,CAAC","sourcesContent":["import React from \"react\";\n\nimport { RootContainer } from \"./ContextNavigationContainer\";\nimport getPathFromState, { State } from \"./fork/getPathFromState\";\nimport { useLinkingContext } from \"./link/useLinkingContext\";\nimport { useInitialRootStateContext } from \"./rootStateContext\";\n\ntype SearchParams = Record<string, string>;\n\ntype UrlObject = {\n pathname: string;\n readonly params: SearchParams;\n segments: string[];\n};\n\nfunction getRouteInfoFromState(\n getPathFromState: (state: State, asPath: boolean) => string,\n state: State\n): UrlObject {\n const path = getPathFromState(state, false);\n const qualified = getPathFromState(state, true);\n return {\n pathname: path.split(\"?\")[\"0\"],\n ...getNormalizedStatePath(qualified),\n };\n}\n\nfunction compareRouteInfo(a: UrlObject, b: UrlObject) {\n return (\n a.segments.length === b.segments.length &&\n a.segments.every((segment, index) => segment === b.segments[index]) &&\n a.pathname === b.pathname &&\n compareUrlSearchParams(a.params, b.params)\n );\n}\n\nfunction compareUrlSearchParams(a: SearchParams, b: SearchParams): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => a[key] === b[key]);\n}\n\nfunction useUrlObject(): UrlObject {\n const initialRootState = useInitialRootStateContext();\n const getPathFromState = useGetPathFromState();\n\n const [routeInfo, setRouteInfo] = React.useState<UrlObject>(\n getRouteInfoFromState(\n getPathFromState,\n // If the root state (from upstream) is not ready, use the hacky initial state.\n // Initial state can be generate because it assumes the linking configuration never changes.\n RootContainer.getRef().getRootState() ?? initialRootState\n )\n );\n\n const routeInfoRef = React.useRef(routeInfo);\n\n React.useEffect(() => {\n routeInfoRef.current = routeInfo;\n }, [routeInfo]);\n\n const maybeUpdateRouteInfo = React.useCallback(\n (state: State) => {\n // Prevent unnecessary updates\n const newRouteInfo = getRouteInfoFromState(getPathFromState, state);\n if (!compareRouteInfo(routeInfoRef.current, newRouteInfo)) {\n setRouteInfo(newRouteInfo);\n }\n },\n [\n // TODO: This probably never changes\n getPathFromState,\n ]\n );\n\n React.useEffect(() => {\n const rootNavigation = RootContainer.getRef();\n\n return rootNavigation.addListener(\"state\", ({ data }) => {\n // Attempt to use the complete state from the root, otherwise this will default to\n // sending events from the nearest layout.\n const navigationState =\n rootNavigation.getRootState() ?? (data.state as unknown as State);\n // NOTE(EvanBacon): It's probably worth asserting if the root state is missing here.\n maybeUpdateRouteInfo(navigationState);\n });\n }, [maybeUpdateRouteInfo]);\n\n return routeInfo;\n}\n\nfunction useGetPathFromState() {\n const linking = useLinkingContext();\n\n return React.useCallback(\n (state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {\n return linking.getPathFromState(state, {\n ...linking.config,\n // @ts-expect-error\n preserveDynamicRoutes: asPath,\n preserveGroups: asPath,\n });\n },\n [linking]\n );\n}\n\n// TODO: Split up getPathFromState to return all this info at once.\nfunction getNormalizedStatePath(\n statePath: string\n): Omit<UrlObject, \"pathname\"> {\n const [pathname, querystring] = statePath.split(\"?\");\n\n return {\n // Strip empty path at the start\n segments: pathname.split(\"/\").filter(Boolean),\n // TODO: This is not efficient, we should generate based on the state instead\n // of converting to string then back to object\n params: queryStringToObject(querystring),\n };\n}\n\nfunction queryStringToObject(queryString?: string): SearchParams {\n return (\n queryString\n ?.split(\"&\")\n .map((pair) => pair.split(\"=\"))\n .reduce((acc, [key, value]) => {\n acc[key] = value;\n return acc;\n }, {} as SearchParams) ?? {}\n );\n}\n\nconst LocationContext = React.createContext<UrlObject | undefined>(undefined);\n\nif (process.env.NODE_ENV !== \"production\") {\n LocationContext.displayName = \"LocationContext\";\n}\n\nexport function LocationProvider({ children }: { children: React.ReactNode }) {\n return (\n <LocationContext.Provider value={useUrlObject()}>\n {children}\n </LocationContext.Provider>\n );\n}\n\nfunction useLocation() {\n const location = React.useContext(LocationContext);\n\n if (!location) {\n throw new Error(\n \"Location context is missing. Make sure you are rendering a <LocationProvider />.\"\n );\n }\n\n return location;\n}\n\n/** @returns Currently selected route as a normalized string without search parameters. e.g. `/acme?foo=bar` -> `/acme`. Segments will be normalized: `/[id]?id=normal` -> `/normal` */\nexport function usePathname(): string {\n return useLocation().pathname;\n}\n\n/** @returns Current URL Search Parameters. */\nexport function useSearchParams(): SearchParams {\n return useLocation().params;\n}\n\n/** @returns Array of selected segments. */\nexport function useSegments(): string[] {\n return useLocation().segments;\n}\n"]}
|
package/build/exports.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { Navigator, Slot } from "./views/Layout";
|
|
1
2
|
export { useRouter } from "./link/useRouter";
|
|
2
3
|
export { usePathname, useSearchParams, useSegments } from "./LocationProvider";
|
|
3
4
|
export { Link, Redirect } from "./link/Link";
|
|
4
5
|
export { withLayoutContext } from "./layouts/withLayoutContext";
|
|
5
|
-
export {
|
|
6
|
+
export { Navigator, Slot };
|
|
6
7
|
export { ExpoRoot } from "./views/Root";
|
|
7
8
|
export { Unmatched } from "./views/Unmatched";
|
|
8
9
|
export { ErrorBoundaryProps } from "./views/Try";
|
|
@@ -12,4 +13,8 @@ export * as Linking from "./link/linking";
|
|
|
12
13
|
export { useNavigation } from "./useNavigation";
|
|
13
14
|
export { RootContainer } from "./ContextNavigationContainer";
|
|
14
15
|
export { useFocusEffect } from "./useFocusEffect";
|
|
16
|
+
/** @deprecated use `<Navigator />` */
|
|
17
|
+
export declare const Layout: typeof Navigator;
|
|
18
|
+
/** @deprecated use `<Slot />` */
|
|
19
|
+
export declare const Children: typeof Slot;
|
|
15
20
|
//# sourceMappingURL=exports.d.ts.map
|
package/build/exports.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAG3B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAG1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlD,sCAAsC;AACtC,eAAO,MAAM,MAAM,kBAAY,CAAC;AAChC,iCAAiC;AACjC,eAAO,MAAM,QAAQ,aAAO,CAAC"}
|
package/build/exports.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Expo Router API
|
|
2
|
+
import { Navigator, Slot } from "./views/Layout";
|
|
2
3
|
export { useRouter } from "./link/useRouter";
|
|
3
4
|
export { usePathname, useSearchParams, useSegments } from "./LocationProvider";
|
|
4
5
|
export { Link, Redirect } from "./link/Link";
|
|
5
6
|
export { withLayoutContext } from "./layouts/withLayoutContext";
|
|
6
|
-
export {
|
|
7
|
+
export { Navigator, Slot };
|
|
7
8
|
// Expo Router Views
|
|
8
9
|
export { ExpoRoot } from "./views/Root";
|
|
9
10
|
export { Unmatched } from "./views/Unmatched";
|
|
@@ -16,4 +17,9 @@ export { Linking_1 as Linking };
|
|
|
16
17
|
export { useNavigation } from "./useNavigation";
|
|
17
18
|
export { RootContainer } from "./ContextNavigationContainer";
|
|
18
19
|
export { useFocusEffect } from "./useFocusEffect";
|
|
20
|
+
// Deprecated (doesn't matter in beta)
|
|
21
|
+
/** @deprecated use `<Navigator />` */
|
|
22
|
+
export const Layout = Navigator;
|
|
23
|
+
/** @deprecated use `<Slot />` */
|
|
24
|
+
export const Children = Slot;
|
|
19
25
|
//# sourceMappingURL=exports.js.map
|
package/build/exports.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAE3B,oBAAoB;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,WAAW;AACX,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;2BACrB,gBAAgB;sBAA7B,OAAO;AAEnB,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,sCAAsC;AAEtC,sCAAsC;AACtC,MAAM,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC;AAChC,iCAAiC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC","sourcesContent":["// Expo Router API\nimport { Navigator, Slot } from \"./views/Layout\";\n\nexport { useRouter } from \"./link/useRouter\";\nexport { usePathname, useSearchParams, useSegments } from \"./LocationProvider\";\nexport { Link, Redirect } from \"./link/Link\";\n\nexport { withLayoutContext } from \"./layouts/withLayoutContext\";\nexport { Navigator, Slot };\n\n// Expo Router Views\nexport { ExpoRoot } from \"./views/Root\";\nexport { Unmatched } from \"./views/Unmatched\";\nexport { ErrorBoundaryProps } from \"./views/Try\";\nexport { ErrorBoundary } from \"./views/ErrorBoundary\";\n\n// Platform\nexport { SplashScreen } from \"./views/Splash\";\nexport * as Linking from \"./link/linking\";\n\n// React Navigation\nexport { useNavigation } from \"./useNavigation\";\nexport { RootContainer } from \"./ContextNavigationContainer\";\nexport { useFocusEffect } from \"./useFocusEffect\";\n\n// Deprecated (doesn't matter in beta)\n\n/** @deprecated use `<Navigator />` */\nexport const Layout = Navigator;\n/** @deprecated use `<Slot />` */\nexport const Children = Slot;\n"]}
|
|
@@ -125,7 +125,7 @@ function deepEqual(a, b) {
|
|
|
125
125
|
}
|
|
126
126
|
return false;
|
|
127
127
|
}
|
|
128
|
-
function walkConfigItems(route, focusedRoute, configs) {
|
|
128
|
+
function walkConfigItems(route, focusedRoute, configs, { preserveDynamicRoutes, }) {
|
|
129
129
|
// NOTE(EvanBacon): Fill in current route using state that was passed as params.
|
|
130
130
|
if (!route.state && isInvalidParams(route.params)) {
|
|
131
131
|
route.state = createFakeState(route.params);
|
|
@@ -148,13 +148,18 @@ function walkConfigItems(route, focusedRoute, configs) {
|
|
|
148
148
|
Object.assign(collectedParams, params);
|
|
149
149
|
}
|
|
150
150
|
if (deepEqual(focusedRoute, route)) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
151
|
+
if (preserveDynamicRoutes) {
|
|
152
|
+
focusedParams = params;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// If this is the focused route, keep the params for later use
|
|
156
|
+
// We save it here since it's been stringified already
|
|
157
|
+
focusedParams = getParamsWithConventionsCollapsed({
|
|
158
|
+
params,
|
|
159
|
+
pattern,
|
|
160
|
+
routeName: route.name,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
158
163
|
}
|
|
159
164
|
}
|
|
160
165
|
if (!route.state && isInvalidParams(route.params)) {
|
|
@@ -170,13 +175,15 @@ function walkConfigItems(route, focusedRoute, configs) {
|
|
|
170
175
|
// NOTE(EvanBacon): Big hack to support initial route changes in tab bars.
|
|
171
176
|
pattern = initialRouteConfig.pattern;
|
|
172
177
|
if (focusedParams) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
if (!preserveDynamicRoutes) {
|
|
179
|
+
// If this is the focused route, keep the params for later use
|
|
180
|
+
// We save it here since it's been stringified already
|
|
181
|
+
focusedParams = getParamsWithConventionsCollapsed({
|
|
182
|
+
params: focusedParams,
|
|
183
|
+
pattern,
|
|
184
|
+
routeName: route.name,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
180
187
|
}
|
|
181
188
|
}
|
|
182
189
|
break;
|
|
@@ -198,13 +205,18 @@ function walkConfigItems(route, focusedRoute, configs) {
|
|
|
198
205
|
throw new Error(`No pattern found for route "${route.name}". Options are: ${Object.keys(configs).join(", ")}.`);
|
|
199
206
|
}
|
|
200
207
|
if (pattern && !focusedParams && focusedRoute.params) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
if (preserveDynamicRoutes) {
|
|
209
|
+
focusedParams = focusedRoute.params;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// If this is the focused route, keep the params for later use
|
|
213
|
+
// We save it here since it's been stringified already
|
|
214
|
+
focusedParams = getParamsWithConventionsCollapsed({
|
|
215
|
+
params: focusedRoute.params,
|
|
216
|
+
pattern,
|
|
217
|
+
routeName: route.name,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
208
220
|
Object.assign(focusedParams, collectedParams);
|
|
209
221
|
}
|
|
210
222
|
return {
|
|
@@ -226,7 +238,7 @@ function getPathFromResolvedState(state, configs, { preserveGroups, preserveDyna
|
|
|
226
238
|
if (!route.state && isInvalidParams(route.params)) {
|
|
227
239
|
route.state = createFakeState(route.params);
|
|
228
240
|
}
|
|
229
|
-
const { pattern, params, nextRoute, focusedParams } = walkConfigItems(route, getActiveRoute(current), { ...configs });
|
|
241
|
+
const { pattern, params, nextRoute, focusedParams } = walkConfigItems(route, getActiveRoute(current), { ...configs }, { preserveDynamicRoutes });
|
|
230
242
|
Object.assign(allParams, params);
|
|
231
243
|
path += getPathWithConventionsCollapsed({
|
|
232
244
|
pattern,
|
|
@@ -247,17 +259,16 @@ function getPathFromResolvedState(state, configs, { preserveGroups, preserveDyna
|
|
|
247
259
|
}
|
|
248
260
|
else {
|
|
249
261
|
// Finished crawling state.
|
|
250
|
-
const outputParams = preserveDynamicRoutes ? params : focusedParams;
|
|
251
262
|
// Check for query params before exiting.
|
|
252
|
-
if (
|
|
253
|
-
for (const param in
|
|
263
|
+
if (focusedParams) {
|
|
264
|
+
for (const param in focusedParams) {
|
|
254
265
|
// TODO: This is not good. We shouldn't squat strings named "undefined".
|
|
255
|
-
if (
|
|
266
|
+
if (focusedParams[param] === "undefined") {
|
|
256
267
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
257
|
-
delete
|
|
268
|
+
delete focusedParams[param];
|
|
258
269
|
}
|
|
259
270
|
}
|
|
260
|
-
const query = queryString.stringify(
|
|
271
|
+
const query = queryString.stringify(focusedParams, { sort: false });
|
|
261
272
|
if (query) {
|
|
262
273
|
path += `?${query}`;
|
|
263
274
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPathFromState.js","sourceRoot":"","sources":["../../src/fork/getPathFromState.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n PathConfig,\n PathConfigMap,\n validatePathConfig,\n} from \"@react-navigation/core\";\nimport type {\n NavigationState,\n PartialState,\n Route,\n} from \"@react-navigation/routers\";\nimport * as queryString from \"query-string\";\n\nimport {\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchGroupName,\n} from \"../matchers\";\n\ntype Options<ParamList extends object> = {\n initialRouteName?: string;\n screens: PathConfigMap<ParamList>;\n};\n\nexport type State =\n | NavigationState\n | Omit<PartialState<NavigationState>, \"stale\">;\n\ntype StringifyConfig = Record<string, (value: any) => string>;\n\ntype ConfigItem = {\n pattern?: string;\n stringify?: StringifyConfig;\n screens?: Record<string, ConfigItem>;\n // Used as fallback for groups\n initialRouteName?: string;\n};\n\ntype CustomRoute = Route<string> & {\n state?: State;\n};\n\nconst getActiveRoute = (state: State): { name: string; params?: object } => {\n const route =\n typeof state.index === \"number\"\n ? state.routes[state.index]\n : state.routes[state.routes.length - 1];\n\n if (route.state) {\n return getActiveRoute(route.state);\n }\n\n if (route && isInvalidParams(route.params)) {\n return getActiveRoute(createFakeState(route.params));\n }\n\n return route;\n};\n\nfunction createFakeState(params: StateAsParams) {\n return {\n stale: false,\n type: \"UNKNOWN\",\n key: \"UNKNOWN\",\n index: 0,\n routeNames: [],\n routes: [\n {\n key: \"UNKNOWN\",\n name: params.screen,\n params: params.params,\n path: params.path,\n },\n ],\n };\n}\n\nfunction segmentMatchesConvention(segment: string): boolean {\n return (\n segment === \"index\" ||\n matchDynamicName(segment) != null ||\n matchGroupName(segment) != null ||\n matchDeepDynamicRouteName(segment) != null\n );\n}\n\nfunction encodeURIComponentPreservingBrackets(str: string) {\n return encodeURIComponent(str).replace(/%5B/g, \"[\").replace(/%5D/g, \"]\");\n}\n\n/**\n * Utility to serialize a navigation state object to a path string.\n *\n * @example\n * ```js\n * getPathFromState(\n * {\n * routes: [\n * {\n * name: 'Chat',\n * params: { author: 'Jane', id: 42 },\n * },\n * ],\n * },\n * {\n * screens: {\n * Chat: {\n * path: 'chat/:author/:id',\n * stringify: { author: author => author.toLowerCase() }\n * }\n * }\n * }\n * )\n * ```\n *\n * @param state Navigation state to serialize.\n * @param options Extra options to fine-tune how to serialize the path.\n * @returns Path representing the state, e.g. /foo/bar?count=42.\n */\nexport default function getPathFromState<ParamList extends object>(\n state: State,\n // @ts-expect-error: non-standard options\n _options?: Options<ParamList> & {\n preserveGroups?: boolean;\n preserveDynamicRoutes?: boolean;\n } = {}\n): string {\n if (state == null) {\n throw Error(\n \"Got 'undefined' for the navigation state. You must pass a valid state object.\"\n );\n }\n\n const { preserveGroups, preserveDynamicRoutes, ...options } = _options;\n\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(\n \"You must pass a 'screens' object to 'getPathFromState' to generate a path.\"\n );\n }\n\n return getPathFromResolvedState(\n state,\n // Create a normalized configs object which will be easier to use\n createNormalizedConfigs(screens),\n { preserveGroups, preserveDynamicRoutes }\n );\n}\n\nfunction processParamsWithUserSettings(\n configItem: ConfigItem,\n params: Record<string, any>\n) {\n const stringify = configItem?.stringify;\n\n return Object.fromEntries(\n Object.entries(params).map(([key, value]) => [\n key,\n // TODO: Strip nullish values here.\n stringify?.[key] ? stringify[key](value) : String(value),\n ])\n );\n}\n\nfunction deepEqual(a: any, b: any) {\n if (a === b) {\n return true;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n if (typeof a === \"object\" && typeof b === \"object\") {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n for (const key of keysA) {\n if (!deepEqual(a[key], b[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\nfunction walkConfigItems(\n route: CustomRoute,\n focusedRoute: {\n name: string;\n params?: object;\n },\n configs: Record<string, ConfigItem>\n) {\n // NOTE(EvanBacon): Fill in current route using state that was passed as params.\n if (!route.state && isInvalidParams(route.params)) {\n route.state = createFakeState(route.params);\n }\n\n let pattern: string | null = null;\n let focusedParams: Record<string, any> | undefined;\n\n const collectedParams: Record<string, any> = {};\n\n while (route.name in configs) {\n const configItem = configs[route.name];\n const inputPattern = configItem.pattern;\n\n if (inputPattern == null) {\n // This should never happen in Expo Router.\n throw new Error(\"Unexpected: No pattern found for route \" + route.name);\n }\n pattern = inputPattern;\n\n if (route.params) {\n const params = processParamsWithUserSettings(configItem, route.params);\n\n // TODO: Does this need to be a null check?\n if (pattern) {\n Object.assign(collectedParams, params);\n }\n if (deepEqual(focusedRoute, route)) {\n // If this is the focused route, keep the params for later use\n // We save it here since it's been stringified already\n focusedParams = getParamsWithConventionsCollapsed({\n params,\n pattern,\n routeName: route.name,\n });\n }\n }\n\n if (!route.state && isInvalidParams(route.params)) {\n route.state = createFakeState(route.params);\n }\n\n // If there is no `screens` property or no nested state, we return pattern\n if (!configItem.screens || route.state === undefined) {\n if (\n configItem.initialRouteName &&\n configItem.screens &&\n configItem.initialRouteName in configItem.screens &&\n configItem.screens[configItem.initialRouteName]?.pattern\n ) {\n const initialRouteConfig =\n configItem.screens[configItem.initialRouteName];\n\n // NOTE(EvanBacon): Big hack to support initial route changes in tab bars.\n pattern = initialRouteConfig.pattern!;\n if (focusedParams) {\n // If this is the focused route, keep the params for later use\n // We save it here since it's been stringified already\n focusedParams = getParamsWithConventionsCollapsed({\n params: focusedParams,\n pattern,\n routeName: route.name,\n });\n }\n }\n break;\n }\n\n const index = route.state.index ?? route.state.routes.length - 1;\n\n const nextRoute = route.state.routes[index];\n const nestedScreens = configItem.screens;\n\n // if there is config for next route name, we go deeper\n if (nestedScreens && nextRoute.name in nestedScreens) {\n route = nextRoute as CustomRoute;\n configs = nestedScreens;\n } else {\n // If not, there is no sense in going deeper in config\n break;\n }\n }\n\n if (pattern == null) {\n throw new Error(\n `No pattern found for route \"${route.name}\". Options are: ${Object.keys(\n configs\n ).join(\", \")}.`\n );\n }\n\n if (pattern && !focusedParams && focusedRoute.params) {\n // If this is the focused route, keep the params for later use\n // We save it here since it's been stringified already\n focusedParams = getParamsWithConventionsCollapsed({\n params: focusedRoute.params,\n pattern,\n routeName: route.name,\n });\n Object.assign(focusedParams, collectedParams);\n }\n\n return {\n pattern,\n nextRoute: route,\n focusedParams,\n params: collectedParams,\n };\n}\n\nfunction getPathFromResolvedState(\n state: State,\n configs: Record<string, ConfigItem>,\n {\n preserveGroups,\n preserveDynamicRoutes,\n }: { preserveGroups?: boolean; preserveDynamicRoutes?: boolean }\n) {\n let path = \"\";\n let current: State = state;\n\n const allParams: Record<string, any> = {};\n\n while (current) {\n path += \"/\";\n\n const route = current.routes[current.index ?? 0] as CustomRoute;\n // NOTE(EvanBacon): Fill in current route using state that was passed as params.\n // if (isInvalidParams(route.params)) {\n if (!route.state && isInvalidParams(route.params)) {\n route.state = createFakeState(route.params);\n }\n\n const { pattern, params, nextRoute, focusedParams } = walkConfigItems(\n route,\n getActiveRoute(current),\n { ...configs }\n );\n\n Object.assign(allParams, params);\n\n path += getPathWithConventionsCollapsed({\n pattern,\n routePath: nextRoute.path,\n params: allParams,\n initialRouteName: configs[nextRoute.name]?.initialRouteName,\n preserveGroups,\n preserveDynamicRoutes,\n });\n\n if (\n nextRoute.state &&\n // NOTE(EvanBacon): The upstream implementation allows for sending in synthetic states (states that weren't generated by `getStateFromPath`)\n // and any invalid routes will simply be ignored.\n // Because of this, we need to check if the next route is valid before continuing, otherwise our more strict\n // implementation will throw an error.\n configs[nextRoute.state.routes?.[nextRoute.state?.index ?? 0]?.name]\n ) {\n // Continue looping with the next state if available.\n current = nextRoute.state;\n } else {\n // Finished crawling state.\n\n const outputParams = preserveDynamicRoutes ? params : focusedParams;\n // Check for query params before exiting.\n if (outputParams) {\n for (const param in outputParams) {\n // TODO: This is not good. We shouldn't squat strings named \"undefined\".\n if (outputParams[param] === \"undefined\") {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete outputParams[param];\n }\n }\n\n const query = queryString.stringify(outputParams, { sort: false });\n\n if (query) {\n path += `?${query}`;\n }\n }\n break;\n }\n }\n return basicSanitizePath(path);\n}\n\nfunction getPathWithConventionsCollapsed({\n pattern,\n routePath,\n params,\n preserveGroups,\n preserveDynamicRoutes,\n initialRouteName,\n}: {\n pattern: string;\n routePath?: string;\n params: Record<string, any>;\n preserveGroups?: boolean;\n preserveDynamicRoutes?: boolean;\n initialRouteName?: string;\n}) {\n const segments = pattern.split(\"/\");\n return segments\n .map((p, i) => {\n const name = getParamName(p);\n\n // We don't know what to show for wildcard patterns\n // Showing the route name seems ok, though whatever we show here will be incorrect\n // Since the page doesn't actually exist\n if (p === \"*\") {\n if (i === 0) {\n // This can occur when a wildcard matches all routes and the given path was `/`.\n return routePath;\n }\n // remove existing segments from route.path and return it\n // this is used for nested wildcard routes. Without this, the path would add\n // all nested segments to the beginning of the wildcard route.\n return routePath\n ?.split(\"/\")\n .slice(i + 1)\n .join(\"/\");\n }\n\n // If the path has a pattern for a param, put the param in the path\n if (p.startsWith(\":\")) {\n if (preserveDynamicRoutes) {\n return `[${name}]`;\n }\n // Optional params without value assigned in route.params should be ignored\n return params[name];\n }\n\n if (!preserveGroups && matchGroupName(p) != null) {\n // When the last part is a group it could be a shared URL\n // if the route has an initialRouteName defined, then we should\n // use that as the component path as we can assume it will be shown.\n if (segments.length - 1 === i) {\n if (initialRouteName) {\n // Return an empty string if the init route is ambiguous.\n if (segmentMatchesConvention(initialRouteName)) {\n return \"\";\n }\n return encodeURIComponentPreservingBrackets(initialRouteName);\n }\n }\n return \"\";\n }\n // Preserve dynamic syntax for rehydration\n return encodeURIComponentPreservingBrackets(p);\n })\n .map((v) => v ?? \"\")\n .join(\"/\");\n}\n\n/** Given a set of query params and a pattern with possible conventions, collapse the conventions and return the remaining params. */\nfunction getParamsWithConventionsCollapsed({\n pattern,\n routeName,\n params,\n}: {\n pattern: string;\n /** Route name is required for matching the wildcard route. This is specific to Expo Router. */\n routeName: string;\n params: object;\n}): Record<string, string> {\n const processedParams = { ...params };\n\n // Remove the params present in the pattern since we'll only use the rest for query string\n\n const segments = pattern.split(\"/\");\n\n // Dynamic Routes\n segments\n .filter((segment) => segment.startsWith(\":\"))\n .forEach((segment) => {\n const name = getParamName(segment);\n delete processedParams[name];\n });\n\n // Deep Dynamic Routes\n if (segments.some((segment) => segment === \"*\")) {\n // NOTE(EvanBacon): Drop the param name matching the wildcard route name -- this is specific to Expo Router.\n const name = matchDeepDynamicRouteName(routeName) ?? routeName;\n delete processedParams[name];\n }\n\n return processedParams;\n}\n\n// Remove multiple as well as trailing slashes\nfunction basicSanitizePath(path: string) {\n // Remove duplicate slashes like `foo//bar` -> `foo/bar`\n const simplifiedPath = path.replace(/\\/+/g, \"/\");\n if (simplifiedPath.length <= 1) {\n return simplifiedPath;\n }\n // Remove trailing slash like `foo/bar/` -> `foo/bar`\n return simplifiedPath.replace(/\\/$/, \"\");\n}\n\ntype StateAsParams = {\n initial: boolean;\n path?: string;\n screen: string;\n params: Record<string, any>;\n};\n\n// TODO: Make StackRouter not do this...\n// Detect if the params came from StackRouter using `params` to pass around internal state.\nfunction isInvalidParams(\n params?: Record<string, any>\n): params is StateAsParams {\n if (!params) {\n return false;\n }\n\n if (\n \"params\" in params &&\n typeof params.params === \"object\" &&\n !!params.params\n ) {\n return true;\n }\n\n return (\n \"initial\" in params &&\n typeof params.initial === \"boolean\" &&\n // \"path\" in params &&\n \"screen\" in params\n );\n}\n\nconst getParamName = (pattern: string) =>\n pattern.replace(/^:/, \"\").replace(/\\?$/, \"\");\n\nconst joinPaths = (...paths: string[]): string =>\n ([] as string[])\n .concat(...paths.map((p) => p.split(\"/\")))\n .filter(Boolean)\n .join(\"/\");\n\nconst createConfigItem = (\n config: PathConfig<object> | string,\n parentPattern?: string\n): ConfigItem => {\n if (typeof config === \"string\") {\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 return { pattern };\n }\n\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 // If an object is specified as the value (e.g. Foo: { ... }),\n // It can have `path` property and `screens` prop which has nested configs\n const pattern =\n config.exact !== true\n ? joinPaths(parentPattern || \"\", config.path || \"\")\n : config.path || \"\";\n\n const screens = config.screens\n ? createNormalizedConfigs(config.screens, pattern)\n : undefined;\n\n return {\n // Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc.\n pattern: pattern?.split(\"/\").filter(Boolean).join(\"/\"),\n stringify: config.stringify,\n screens,\n initialRouteName: config.initialRouteName,\n };\n};\n\nconst createNormalizedConfigs = (\n options: PathConfigMap<object>,\n pattern?: string\n): Record<string, ConfigItem> =>\n Object.fromEntries(\n Object.entries(options).map(([name, c]) => [\n name,\n createConfigItem(c, pattern),\n ])\n );\n"]}
|
|
1
|
+
{"version":3,"file":"getPathFromState.js","sourceRoot":"","sources":["../../src/fork/getPathFromState.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n PathConfig,\n PathConfigMap,\n validatePathConfig,\n} from \"@react-navigation/core\";\nimport type {\n NavigationState,\n PartialState,\n Route,\n} from \"@react-navigation/routers\";\nimport * as queryString from \"query-string\";\n\nimport {\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchGroupName,\n} from \"../matchers\";\n\ntype Options<ParamList extends object> = {\n initialRouteName?: string;\n screens: PathConfigMap<ParamList>;\n};\n\nexport type State =\n | NavigationState\n | Omit<PartialState<NavigationState>, \"stale\">;\n\ntype StringifyConfig = Record<string, (value: any) => string>;\n\ntype ConfigItem = {\n pattern?: string;\n stringify?: StringifyConfig;\n screens?: Record<string, ConfigItem>;\n // Used as fallback for groups\n initialRouteName?: string;\n};\n\ntype CustomRoute = Route<string> & {\n state?: State;\n};\n\nconst getActiveRoute = (state: State): { name: string; params?: object } => {\n const route =\n typeof state.index === \"number\"\n ? state.routes[state.index]\n : state.routes[state.routes.length - 1];\n\n if (route.state) {\n return getActiveRoute(route.state);\n }\n\n if (route && isInvalidParams(route.params)) {\n return getActiveRoute(createFakeState(route.params));\n }\n\n return route;\n};\n\nfunction createFakeState(params: StateAsParams) {\n return {\n stale: false,\n type: \"UNKNOWN\",\n key: \"UNKNOWN\",\n index: 0,\n routeNames: [],\n routes: [\n {\n key: \"UNKNOWN\",\n name: params.screen,\n params: params.params,\n path: params.path,\n },\n ],\n };\n}\n\nfunction segmentMatchesConvention(segment: string): boolean {\n return (\n segment === \"index\" ||\n matchDynamicName(segment) != null ||\n matchGroupName(segment) != null ||\n matchDeepDynamicRouteName(segment) != null\n );\n}\n\nfunction encodeURIComponentPreservingBrackets(str: string) {\n return encodeURIComponent(str).replace(/%5B/g, \"[\").replace(/%5D/g, \"]\");\n}\n\n/**\n * Utility to serialize a navigation state object to a path string.\n *\n * @example\n * ```js\n * getPathFromState(\n * {\n * routes: [\n * {\n * name: 'Chat',\n * params: { author: 'Jane', id: 42 },\n * },\n * ],\n * },\n * {\n * screens: {\n * Chat: {\n * path: 'chat/:author/:id',\n * stringify: { author: author => author.toLowerCase() }\n * }\n * }\n * }\n * )\n * ```\n *\n * @param state Navigation state to serialize.\n * @param options Extra options to fine-tune how to serialize the path.\n * @returns Path representing the state, e.g. /foo/bar?count=42.\n */\nexport default function getPathFromState<ParamList extends object>(\n state: State,\n // @ts-expect-error: non-standard options\n _options?: Options<ParamList> & {\n preserveGroups?: boolean;\n preserveDynamicRoutes?: boolean;\n } = {}\n): string {\n if (state == null) {\n throw Error(\n \"Got 'undefined' for the navigation state. You must pass a valid state object.\"\n );\n }\n\n const { preserveGroups, preserveDynamicRoutes, ...options } = _options;\n\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(\n \"You must pass a 'screens' object to 'getPathFromState' to generate a path.\"\n );\n }\n\n return getPathFromResolvedState(\n state,\n // Create a normalized configs object which will be easier to use\n createNormalizedConfigs(screens),\n { preserveGroups, preserveDynamicRoutes }\n );\n}\n\nfunction processParamsWithUserSettings(\n configItem: ConfigItem,\n params: Record<string, any>\n) {\n const stringify = configItem?.stringify;\n\n return Object.fromEntries(\n Object.entries(params).map(([key, value]) => [\n key,\n // TODO: Strip nullish values here.\n stringify?.[key] ? stringify[key](value) : String(value),\n ])\n );\n}\n\nfunction deepEqual(a: any, b: any) {\n if (a === b) {\n return true;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n if (typeof a === \"object\" && typeof b === \"object\") {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n for (const key of keysA) {\n if (!deepEqual(a[key], b[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\nfunction walkConfigItems(\n route: CustomRoute,\n focusedRoute: {\n name: string;\n params?: object;\n },\n configs: Record<string, ConfigItem>,\n {\n preserveDynamicRoutes,\n }: {\n preserveDynamicRoutes?: boolean;\n }\n) {\n // NOTE(EvanBacon): Fill in current route using state that was passed as params.\n if (!route.state && isInvalidParams(route.params)) {\n route.state = createFakeState(route.params);\n }\n\n let pattern: string | null = null;\n let focusedParams: Record<string, any> | undefined;\n\n const collectedParams: Record<string, any> = {};\n\n while (route.name in configs) {\n const configItem = configs[route.name];\n const inputPattern = configItem.pattern;\n\n if (inputPattern == null) {\n // This should never happen in Expo Router.\n throw new Error(\"Unexpected: No pattern found for route \" + route.name);\n }\n pattern = inputPattern;\n\n if (route.params) {\n const params = processParamsWithUserSettings(configItem, route.params);\n\n // TODO: Does this need to be a null check?\n if (pattern) {\n Object.assign(collectedParams, params);\n }\n if (deepEqual(focusedRoute, route)) {\n if (preserveDynamicRoutes) {\n focusedParams = params;\n } else {\n // If this is the focused route, keep the params for later use\n // We save it here since it's been stringified already\n focusedParams = getParamsWithConventionsCollapsed({\n params,\n pattern,\n routeName: route.name,\n });\n }\n }\n }\n\n if (!route.state && isInvalidParams(route.params)) {\n route.state = createFakeState(route.params);\n }\n\n // If there is no `screens` property or no nested state, we return pattern\n if (!configItem.screens || route.state === undefined) {\n if (\n configItem.initialRouteName &&\n configItem.screens &&\n configItem.initialRouteName in configItem.screens &&\n configItem.screens[configItem.initialRouteName]?.pattern\n ) {\n const initialRouteConfig =\n configItem.screens[configItem.initialRouteName];\n\n // NOTE(EvanBacon): Big hack to support initial route changes in tab bars.\n pattern = initialRouteConfig.pattern!;\n if (focusedParams) {\n if (!preserveDynamicRoutes) {\n // If this is the focused route, keep the params for later use\n // We save it here since it's been stringified already\n focusedParams = getParamsWithConventionsCollapsed({\n params: focusedParams,\n pattern,\n routeName: route.name,\n });\n }\n }\n }\n break;\n }\n\n const index = route.state.index ?? route.state.routes.length - 1;\n\n const nextRoute = route.state.routes[index];\n const nestedScreens = configItem.screens;\n\n // if there is config for next route name, we go deeper\n if (nestedScreens && nextRoute.name in nestedScreens) {\n route = nextRoute as CustomRoute;\n configs = nestedScreens;\n } else {\n // If not, there is no sense in going deeper in config\n break;\n }\n }\n\n if (pattern == null) {\n throw new Error(\n `No pattern found for route \"${route.name}\". Options are: ${Object.keys(\n configs\n ).join(\", \")}.`\n );\n }\n\n if (pattern && !focusedParams && focusedRoute.params) {\n if (preserveDynamicRoutes) {\n focusedParams = focusedRoute.params;\n } else {\n // If this is the focused route, keep the params for later use\n // We save it here since it's been stringified already\n focusedParams = getParamsWithConventionsCollapsed({\n params: focusedRoute.params,\n pattern,\n routeName: route.name,\n });\n }\n Object.assign(focusedParams, collectedParams);\n }\n\n return {\n pattern,\n nextRoute: route,\n focusedParams,\n params: collectedParams,\n };\n}\n\nfunction getPathFromResolvedState(\n state: State,\n configs: Record<string, ConfigItem>,\n {\n preserveGroups,\n preserveDynamicRoutes,\n }: { preserveGroups?: boolean; preserveDynamicRoutes?: boolean }\n) {\n let path = \"\";\n let current: State = state;\n\n const allParams: Record<string, any> = {};\n\n while (current) {\n path += \"/\";\n\n const route = current.routes[current.index ?? 0] as CustomRoute;\n // NOTE(EvanBacon): Fill in current route using state that was passed as params.\n // if (isInvalidParams(route.params)) {\n if (!route.state && isInvalidParams(route.params)) {\n route.state = createFakeState(route.params);\n }\n\n const { pattern, params, nextRoute, focusedParams } = walkConfigItems(\n route,\n getActiveRoute(current),\n { ...configs },\n { preserveDynamicRoutes }\n );\n\n Object.assign(allParams, params);\n\n path += getPathWithConventionsCollapsed({\n pattern,\n routePath: nextRoute.path,\n params: allParams,\n initialRouteName: configs[nextRoute.name]?.initialRouteName,\n preserveGroups,\n preserveDynamicRoutes,\n });\n\n if (\n nextRoute.state &&\n // NOTE(EvanBacon): The upstream implementation allows for sending in synthetic states (states that weren't generated by `getStateFromPath`)\n // and any invalid routes will simply be ignored.\n // Because of this, we need to check if the next route is valid before continuing, otherwise our more strict\n // implementation will throw an error.\n configs[nextRoute.state.routes?.[nextRoute.state?.index ?? 0]?.name]\n ) {\n // Continue looping with the next state if available.\n current = nextRoute.state;\n } else {\n // Finished crawling state.\n\n // Check for query params before exiting.\n if (focusedParams) {\n for (const param in focusedParams) {\n // TODO: This is not good. We shouldn't squat strings named \"undefined\".\n if (focusedParams[param] === \"undefined\") {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete focusedParams[param];\n }\n }\n\n const query = queryString.stringify(focusedParams, { sort: false });\n\n if (query) {\n path += `?${query}`;\n }\n }\n break;\n }\n }\n return basicSanitizePath(path);\n}\n\nfunction getPathWithConventionsCollapsed({\n pattern,\n routePath,\n params,\n preserveGroups,\n preserveDynamicRoutes,\n initialRouteName,\n}: {\n pattern: string;\n routePath?: string;\n params: Record<string, any>;\n preserveGroups?: boolean;\n preserveDynamicRoutes?: boolean;\n initialRouteName?: string;\n}) {\n const segments = pattern.split(\"/\");\n return segments\n .map((p, i) => {\n const name = getParamName(p);\n\n // We don't know what to show for wildcard patterns\n // Showing the route name seems ok, though whatever we show here will be incorrect\n // Since the page doesn't actually exist\n if (p === \"*\") {\n if (i === 0) {\n // This can occur when a wildcard matches all routes and the given path was `/`.\n return routePath;\n }\n // remove existing segments from route.path and return it\n // this is used for nested wildcard routes. Without this, the path would add\n // all nested segments to the beginning of the wildcard route.\n return routePath\n ?.split(\"/\")\n .slice(i + 1)\n .join(\"/\");\n }\n\n // If the path has a pattern for a param, put the param in the path\n if (p.startsWith(\":\")) {\n if (preserveDynamicRoutes) {\n return `[${name}]`;\n }\n // Optional params without value assigned in route.params should be ignored\n return params[name];\n }\n\n if (!preserveGroups && matchGroupName(p) != null) {\n // When the last part is a group it could be a shared URL\n // if the route has an initialRouteName defined, then we should\n // use that as the component path as we can assume it will be shown.\n if (segments.length - 1 === i) {\n if (initialRouteName) {\n // Return an empty string if the init route is ambiguous.\n if (segmentMatchesConvention(initialRouteName)) {\n return \"\";\n }\n return encodeURIComponentPreservingBrackets(initialRouteName);\n }\n }\n return \"\";\n }\n // Preserve dynamic syntax for rehydration\n return encodeURIComponentPreservingBrackets(p);\n })\n .map((v) => v ?? \"\")\n .join(\"/\");\n}\n\n/** Given a set of query params and a pattern with possible conventions, collapse the conventions and return the remaining params. */\nfunction getParamsWithConventionsCollapsed({\n pattern,\n routeName,\n params,\n}: {\n pattern: string;\n /** Route name is required for matching the wildcard route. This is specific to Expo Router. */\n routeName: string;\n params: object;\n}): Record<string, string> {\n const processedParams = { ...params };\n\n // Remove the params present in the pattern since we'll only use the rest for query string\n\n const segments = pattern.split(\"/\");\n\n // Dynamic Routes\n segments\n .filter((segment) => segment.startsWith(\":\"))\n .forEach((segment) => {\n const name = getParamName(segment);\n delete processedParams[name];\n });\n\n // Deep Dynamic Routes\n if (segments.some((segment) => segment === \"*\")) {\n // NOTE(EvanBacon): Drop the param name matching the wildcard route name -- this is specific to Expo Router.\n const name = matchDeepDynamicRouteName(routeName) ?? routeName;\n delete processedParams[name];\n }\n\n return processedParams;\n}\n\n// Remove multiple as well as trailing slashes\nfunction basicSanitizePath(path: string) {\n // Remove duplicate slashes like `foo//bar` -> `foo/bar`\n const simplifiedPath = path.replace(/\\/+/g, \"/\");\n if (simplifiedPath.length <= 1) {\n return simplifiedPath;\n }\n // Remove trailing slash like `foo/bar/` -> `foo/bar`\n return simplifiedPath.replace(/\\/$/, \"\");\n}\n\ntype StateAsParams = {\n initial: boolean;\n path?: string;\n screen: string;\n params: Record<string, any>;\n};\n\n// TODO: Make StackRouter not do this...\n// Detect if the params came from StackRouter using `params` to pass around internal state.\nfunction isInvalidParams(\n params?: Record<string, any>\n): params is StateAsParams {\n if (!params) {\n return false;\n }\n\n if (\n \"params\" in params &&\n typeof params.params === \"object\" &&\n !!params.params\n ) {\n return true;\n }\n\n return (\n \"initial\" in params &&\n typeof params.initial === \"boolean\" &&\n // \"path\" in params &&\n \"screen\" in params\n );\n}\n\nconst getParamName = (pattern: string) =>\n pattern.replace(/^:/, \"\").replace(/\\?$/, \"\");\n\nconst joinPaths = (...paths: string[]): string =>\n ([] as string[])\n .concat(...paths.map((p) => p.split(\"/\")))\n .filter(Boolean)\n .join(\"/\");\n\nconst createConfigItem = (\n config: PathConfig<object> | string,\n parentPattern?: string\n): ConfigItem => {\n if (typeof config === \"string\") {\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 return { pattern };\n }\n\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 // If an object is specified as the value (e.g. Foo: { ... }),\n // It can have `path` property and `screens` prop which has nested configs\n const pattern =\n config.exact !== true\n ? joinPaths(parentPattern || \"\", config.path || \"\")\n : config.path || \"\";\n\n const screens = config.screens\n ? createNormalizedConfigs(config.screens, pattern)\n : undefined;\n\n return {\n // Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc.\n pattern: pattern?.split(\"/\").filter(Boolean).join(\"/\"),\n stringify: config.stringify,\n screens,\n initialRouteName: config.initialRouteName,\n };\n};\n\nconst createNormalizedConfigs = (\n options: PathConfigMap<object>,\n pattern?: string\n): Record<string, ConfigItem> =>\n Object.fromEntries(\n Object.entries(options).map(([name, c]) => [\n name,\n createConfigItem(c, pattern),\n ])\n );\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getStateFromPath.d.ts","sourceRoot":"","sources":["../../src/fork/getStateFromPath.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAGd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACb,MAAM,2BAA2B,CAAC;AAUnC,aAAK,OAAO,CAAC,SAAS,SAAS,MAAM,IAAI;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;CACnC,CAAC;AAqBF,aAAK,WAAW,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG;IACjD,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAkBF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,SAAS,SAAS,MAAM,EAC/D,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAC3B,WAAW,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"getStateFromPath.d.ts","sourceRoot":"","sources":["../../src/fork/getStateFromPath.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAGd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACb,MAAM,2BAA2B,CAAC;AAUnC,aAAK,OAAO,CAAC,SAAS,SAAS,MAAM,IAAI;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;CACnC,CAAC;AAqBF,aAAK,WAAW,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG;IACjD,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAkBF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,SAAS,SAAS,MAAM,EAC/D,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAC3B,WAAW,GAAG,SAAS,CA8CzB"}
|
|
@@ -42,6 +42,12 @@ export default function getStateFromPath(path, options) {
|
|
|
42
42
|
}
|
|
43
43
|
// This will be mutated...
|
|
44
44
|
const initialRoutes = [];
|
|
45
|
+
if (options?.initialRouteName) {
|
|
46
|
+
initialRoutes.push({
|
|
47
|
+
initialRouteName: options.initialRouteName,
|
|
48
|
+
parentScreens: [],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
45
51
|
// Create a normalized configs array which will be easier to use.
|
|
46
52
|
const converted = Object.keys(screens)
|
|
47
53
|
.map((key) => createNormalizedConfigs(key, screens, [], initialRoutes))
|
|
@@ -178,7 +184,16 @@ function getStateFromEmptyPathWithConfigs(path, configs, initialRoutes) {
|
|
|
178
184
|
// We need to add special handling of empty path so navigation to empty path also works
|
|
179
185
|
// When handling empty path, we should only look at the root level config
|
|
180
186
|
// NOTE(EvanBacon): We only care about matching leaf nodes.
|
|
181
|
-
const leafNodes = configs
|
|
187
|
+
const leafNodes = configs
|
|
188
|
+
.filter((config) => !config.hasChildren)
|
|
189
|
+
.map((value) => {
|
|
190
|
+
return {
|
|
191
|
+
...value,
|
|
192
|
+
// Collapse all levels of group segments before testing.
|
|
193
|
+
// This enables `app/(one)/(two)/index.js` to be matched.
|
|
194
|
+
path: stripGroupSegmentsFromPath(value.path),
|
|
195
|
+
};
|
|
196
|
+
});
|
|
182
197
|
const match = leafNodes.find((config) =>
|
|
183
198
|
// NOTE(EvanBacon): Test leaf node index routes that either don't have a regex or match an empty string.
|
|
184
199
|
config.path === "" && (!config.regex || config.regex.test(""))) ??
|