expo-router 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/build/loadStaticParamsAsync.d.ts.map +1 -1
  2. package/build/static/renderStaticContent.d.ts.map +1 -1
  3. package/build/static/useServerState.d.ts.map +1 -1
  4. package/build/views/Screen.d.ts.map +1 -1
  5. package/build/views/Unmatched.d.ts.map +1 -1
  6. package/package.json +5 -4
  7. package/src/loadStaticParamsAsync.ts +51 -24
  8. package/src/static/renderStaticContent.tsx +5 -1
  9. package/src/static/useServerState.ts +4 -1
  10. package/src/views/Screen.tsx +4 -1
  11. package/src/views/Unmatched.tsx +17 -3
  12. package/src/__tests__/LocationProvider.test.node.ts +0 -55
  13. package/src/__tests__/Route.test.node.ts +0 -70
  14. package/src/__tests__/getReactNavigationConfig.test.node.ts +0 -138
  15. package/src/__tests__/getRoutes.test.node.ts +0 -486
  16. package/src/__tests__/loadStaticParamsAsync.test.node.ts +0 -413
  17. package/src/__tests__/matchers.test.node.ts +0 -59
  18. package/src/__tests__/useNavigation.test.node.ts +0 -24
  19. package/src/__tests__/useScreens.test.node.tsx +0 -66
  20. package/src/fork/__tests__/__snapshots__/extractPathFromURL.test.ios.ts.snap +0 -97
  21. package/src/fork/__tests__/extractPathFromURL.test.ios.ts +0 -76
  22. package/src/fork/__tests__/getPathFromState-upstream.test.node.ts +0 -1981
  23. package/src/fork/__tests__/getStateFromPath-upstream.test.node.ts +0 -2570
  24. package/src/fork/__tests__/getStateFromPath.test.node.ts +0 -131
  25. package/src/link/__tests__/href.test.node.ts +0 -57
  26. package/src/link/__tests__/stateOperations.test.node.ts +0 -373
  27. package/src/link/__tests__/useLinkToPath.test.node.ts +0 -53
  28. package/src/utils/__tests__/mockState.test.node.ts +0 -119
@@ -1 +1 @@
1
- {"version":3,"file":"loadStaticParamsAsync.d.ts","sourceRoot":"","sources":["../src/loadStaticParamsAsync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAWzC,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,SAAS,CAAC,CAWpB"}
1
+ {"version":3,"file":"loadStaticParamsAsync.d.ts","sourceRoot":"","sources":["../src/loadStaticParamsAsync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,SAAS,CAAC;AAW5D,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,SAAS,CAAC,CAWpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderStaticContent.d.ts","sourceRoot":"","sources":["../../src/static/renderStaticContent.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,CA6CtD;AA0BD,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"renderStaticContent.d.ts","sourceRoot":"","sources":["../../src/static/renderStaticContent.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,CA6CtD;AA0BD,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useServerState.d.ts","sourceRoot":"","sources":["../../src/static/useServerState.ts"],"names":[],"mappings":"AA8BA,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAO7B"}
1
+ {"version":3,"file":"useServerState.d.ts","sourceRoot":"","sources":["../../src/static/useServerState.ts"],"names":[],"mappings":"AAiCA,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAO7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"Screen.d.ts","sourceRoot":"","sources":["../../src/views/Screen.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACxD;IACF;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,EAAE,EACvD,IAAI,EACJ,QAAQ,EACR,OAAO,GACR,EAAE,WAAW,CAAC,QAAQ,CAAC,QAmBvB"}
1
+ {"version":3,"file":"Screen.d.ts","sourceRoot":"","sources":["../../src/views/Screen.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACxD;IACF;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC;AAKF,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,EAAE,EACvD,IAAI,EACJ,QAAQ,EACR,OAAO,GACR,EAAE,WAAW,CAAC,QAAQ,CAAC,QAmBvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Unmatched.d.ts","sourceRoot":"","sources":["../../src/views/Unmatched.tsx"],"names":[],"mappings":";AAQA,2CAA2C;AAC3C,wBAAgB,SAAS,gBAwCxB"}
1
+ {"version":3,"file":"Unmatched.d.ts","sourceRoot":"","sources":["../../src/views/Unmatched.tsx"],"names":[],"mappings":";AAYA,2CAA2C;AAC3C,wBAAgB,SAAS,gBAkDxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-router",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "main": "src/index.tsx",
5
5
  "types": "build/index.d.ts",
6
6
  "files": [
@@ -19,7 +19,8 @@
19
19
  "src",
20
20
  "stack.ts",
21
21
  "tabs.ts",
22
- "types"
22
+ "types",
23
+ "!**/__tests__"
23
24
  ],
24
25
  "repository": {
25
26
  "url": "https://github.com/expo/router.git",
@@ -56,7 +57,7 @@
56
57
  "expo-constants": "*",
57
58
  "expo-linking": "*",
58
59
  "expo-status-bar": "*",
59
- "metro": "~0.73.7",
60
+ "metro": "~0.76.0",
60
61
  "react-native-gesture-handler": "*",
61
62
  "react-native-reanimated": "*",
62
63
  "react-native-safe-area-context": "*",
@@ -91,7 +92,7 @@
91
92
  },
92
93
  "dependencies": {
93
94
  "@bacons/react-views": "^1.1.3",
94
- "@expo/metro-runtime": "2.0.1",
95
+ "@expo/metro-runtime": "2.0.3",
95
96
  "@radix-ui/react-slot": "^1.0.0",
96
97
  "@react-navigation/bottom-tabs": "~6.5.7",
97
98
  "@react-navigation/native": "~6.1.6",
@@ -1,4 +1,4 @@
1
- import type { RouteNode } from "./Route";
1
+ import type { DynamicConvention, RouteNode } from "./Route";
2
2
 
3
3
  async function recurseAndFlattenNodes<
4
4
  T,
@@ -24,7 +24,10 @@ export async function loadStaticParamsAsync(
24
24
  return route;
25
25
  }
26
26
 
27
- function assertStaticParams(route: RouteNode, params: any) {
27
+ function assertStaticParams(
28
+ route: RouteNode,
29
+ params: Record<string, string | string[]>
30
+ ) {
28
31
  const matches = route.dynamic!.every((dynamic) => {
29
32
  const value = params[dynamic.name];
30
33
  return value !== undefined && value !== null;
@@ -37,20 +40,44 @@ function assertStaticParams(route: RouteNode, params: any) {
37
40
  );
38
41
  }
39
42
 
43
+ const validateSingleParam = (
44
+ dynamic: DynamicConvention,
45
+ value: any,
46
+ allowMultipleSegments?: boolean
47
+ ) => {
48
+ if (typeof value !== "string") {
49
+ throw new Error(
50
+ `generateStaticParams() for route "${
51
+ route.contextKey
52
+ }" expected param "${
53
+ dynamic.name
54
+ }" to be of type string, instead found "${typeof value}" while parsing "${value}".`
55
+ );
56
+ }
57
+ const parts = value.split("/").filter(Boolean);
58
+ if (parts.length > 1 && !allowMultipleSegments) {
59
+ throw new Error(
60
+ `generateStaticParams() for route "${route.contextKey}" expected param "${dynamic.name}" to not contain "/" (multiple segments) while parsing "${value}".`
61
+ );
62
+ }
63
+ if (parts.length === 0) {
64
+ throw new Error(
65
+ `generateStaticParams() for route "${route.contextKey}" expected param "${dynamic.name}" not to be empty while parsing "${value}".`
66
+ );
67
+ }
68
+ };
69
+
40
70
  route.dynamic!.forEach((dynamic) => {
41
71
  const value = params[dynamic.name];
42
72
  if (dynamic.deep) {
73
+ // TODO: We could split strings by `/` and use that too.
43
74
  if (!Array.isArray(value)) {
44
- throw new Error(
45
- `generateStaticParams() for route "${route.contextKey}" expected param "${dynamic.name}" to be of type Array.`
46
- );
75
+ validateSingleParam(dynamic, value, true);
76
+ } else {
77
+ validateSingleParam(dynamic, value.filter(Boolean).join("/"), true);
47
78
  }
48
79
  } else {
49
- if (Array.isArray(value)) {
50
- throw new Error(
51
- `generateStaticParams() for route "${route.contextKey}" expected param "${dynamic.name}" to not be of type Array.`
52
- );
53
- }
80
+ validateSingleParam(dynamic, value);
54
81
  }
55
82
  return value !== undefined && value !== null;
56
83
  });
@@ -73,27 +100,27 @@ async function loadStaticParamsRecursive(
73
100
  route: RouteNode,
74
101
  props: { parentParams: any }
75
102
  ): Promise<RouteNode[]> {
76
- if (!route?.dynamic) {
103
+ if (!route?.dynamic && !route?.children?.length) {
77
104
  return [route];
78
105
  }
79
106
 
80
107
  const loaded = await route.loadRoute();
81
- if (!loaded.generateStaticParams) {
82
- return [route];
83
- }
84
108
 
85
- const staticParams = await loaded.generateStaticParams({
86
- params: props.parentParams || {},
87
- });
109
+ let staticParams: Record<string, string | string[]>[] = [];
88
110
 
89
- if (!Array.isArray(staticParams)) {
90
- throw new Error(
91
- `generateStaticParams() must return an array of params, received ${staticParams}`
92
- );
93
- }
111
+ if (loaded.generateStaticParams) {
112
+ staticParams = await loaded.generateStaticParams({
113
+ params: props.parentParams || {},
114
+ });
115
+ if (!Array.isArray(staticParams)) {
116
+ throw new Error(
117
+ `generateStaticParams() must return an array of params, received ${staticParams}`
118
+ );
119
+ }
94
120
 
95
- // Assert that at least one param from each matches the dynamic route.
96
- staticParams.forEach((params) => assertStaticParams(route, params));
121
+ // Assert that at least one param from each matches the dynamic route.
122
+ staticParams.forEach((params) => assertStaticParams(route, params));
123
+ }
97
124
 
98
125
  route.children = uniqBy(
99
126
  (
@@ -6,7 +6,11 @@
6
6
  */
7
7
 
8
8
  import { ServerContainerRef } from "@react-navigation/native";
9
- import ServerContainer from "@react-navigation/native/src/ServerContainer";
9
+ // We use the value from `main` in the `package.json` since this
10
+ // should only be accessed from processes that are running in Node.js and
11
+ // conform to using `mainFields: ['main']` in their bundler config.
12
+ // @ts-expect-error
13
+ import ServerContainer from "@react-navigation/native/lib/commonjs/ServerContainer";
10
14
  import App, { getManifest } from "expo-router/_entry";
11
15
  import React from "react";
12
16
  import ReactDOMServer from "react-dom/server";
@@ -6,7 +6,10 @@ import { useLinkingContext } from "../link/useLinkingContext";
6
6
  function useServerStateNode() {
7
7
  // TODO: Expose this from React Navigation
8
8
  const ServerContext =
9
- require("@react-navigation/native/src/ServerContext").default;
9
+ // We use the value from `main` in the `package.json` since this
10
+ // should only be accessed from processes that are running in Node.js and
11
+ // conform to using `mainFields: ['main']` in their bundler config.
12
+ require("@react-navigation/native/lib/commonjs/ServerContext").default;
10
13
  const getStateFromPath = useGetStateFromPath();
11
14
  const server = React.useContext<any>(ServerContext);
12
15
  const pathname = React.useMemo<string>(() => {
@@ -21,6 +21,9 @@ export type ScreenProps<
21
21
  options?: TOptions;
22
22
  };
23
23
 
24
+ const useLayoutEffect =
25
+ typeof window !== "undefined" ? React.useLayoutEffect : function () {};
26
+
24
27
  /** Component for setting the current screen's options dynamically. */
25
28
  export function Screen<TOptions extends object = object>({
26
29
  name,
@@ -29,7 +32,7 @@ export function Screen<TOptions extends object = object>({
29
32
  }: ScreenProps<TOptions>) {
30
33
  const navigation = useNavigation(name);
31
34
 
32
- React.useLayoutEffect(() => {
35
+ useLayoutEffect(() => {
33
36
  navigation.setOptions(options ?? {});
34
37
  }, [navigation, options]);
35
38
 
@@ -4,15 +4,20 @@ import React from "react";
4
4
 
5
5
  import { usePathname } from "../LocationProvider";
6
6
  import { Link } from "../link/Link";
7
+ import { useRouter } from "../link/useRouter";
7
8
  import { useNavigation } from "../useNavigation";
8
9
 
10
+ const useLayoutEffect =
11
+ typeof window !== "undefined" ? React.useLayoutEffect : function () {};
12
+
9
13
  /** Default screen for unmatched routes. */
10
14
  export function Unmatched() {
15
+ const router = useRouter();
11
16
  const navigation = useNavigation();
12
17
  const pathname = usePathname();
13
18
  const url = createURL(pathname);
14
19
 
15
- React.useLayoutEffect(() => {
20
+ useLayoutEffect(() => {
16
21
  navigation.setOptions({
17
22
  title: "Not Found",
18
23
  });
@@ -33,9 +38,18 @@ export function Unmatched() {
33
38
  style={styles.subtitle}
34
39
  >
35
40
  Page could not be found.{" "}
36
- <Link href="/" replace style={styles.link}>
41
+ <Text
42
+ onPress={() => {
43
+ if (navigation.canGoBack()) {
44
+ navigation.goBack();
45
+ } else {
46
+ router.replace("/");
47
+ }
48
+ }}
49
+ style={styles.link}
50
+ >
37
51
  Go back.
38
- </Link>
52
+ </Text>
39
53
  </Text>
40
54
 
41
55
  <Link href={pathname} replace style={styles.link}>
@@ -1,55 +0,0 @@
1
- import {
2
- getNormalizedStatePath,
3
- compareUrlSearchParams,
4
- } from "../LocationProvider";
5
-
6
- describe(getNormalizedStatePath, () => {
7
- // Ensure all values are correctly decoded
8
- it(`returns the normalized path`, () => {
9
- expect(
10
- getNormalizedStatePath({
11
- path: "/foo/bar%20baz?alpha=beta",
12
- params: {
13
- alpha: "beta other",
14
- beta: "gamma",
15
- charlie: "delta%20echo",
16
- delta: ["evan", "foxtrot%20gamma", "hotel india"],
17
- },
18
- })
19
- ).toEqual({
20
- segments: ["foo", "bar baz"],
21
- params: {
22
- alpha: "beta other",
23
- beta: "gamma",
24
- charlie: "delta echo",
25
- // Ensure arrays are preserved (rest params).
26
- delta: ["evan", "foxtrot gamma", "hotel india"],
27
- },
28
- });
29
- });
30
- });
31
-
32
- describe(compareUrlSearchParams, () => {
33
- it("compares search params", () => {
34
- expect(
35
- compareUrlSearchParams(
36
- { one: "two", three: ["four"] },
37
- { one: "two", three: ["four"] }
38
- )
39
- ).toBe(true);
40
-
41
- expect(
42
- compareUrlSearchParams(
43
- { one: "two", three: ["four"], five: "six", seven: "eight" },
44
- { one: "two", three: ["four"], five: "six", seven: "eight" }
45
- )
46
- ).toBe(true);
47
-
48
- expect(
49
- compareUrlSearchParams(
50
- { six: "seven", eight: ["nine"] },
51
- { one: "two", three: ["four"] }
52
- )
53
- ).toBe(false);
54
- });
55
- });
@@ -1,70 +0,0 @@
1
- import { RouteNode, sortRoutes } from "../Route";
2
- import { generateDynamic } from "../getRoutes";
3
-
4
- const asRouteNode = (route: string) =>
5
- ({
6
- children: [],
7
- dynamic: generateDynamic(route),
8
- loadRoute(): any {
9
- return {
10
- default() {
11
- return null;
12
- },
13
- };
14
- },
15
- route,
16
- contextKey: "INVALID_TEST_VALUE",
17
- } as RouteNode);
18
-
19
- describe(sortRoutes, () => {
20
- it(`sorts index routes by priority`, () => {
21
- // Index before deep dynamic
22
- expect(sortRoutes(asRouteNode("index"), asRouteNode("[...a]"))).toBe(-1);
23
- // Index before dynamic
24
- expect(sortRoutes(asRouteNode("index"), asRouteNode("[a]"))).toBe(-1);
25
- // Index before named
26
- expect(sortRoutes(asRouteNode("index"), asRouteNode("a"))).toBe(-1);
27
- expect(sortRoutes(asRouteNode("index"), asRouteNode("z"))).toBe(-1);
28
-
29
- // Index tied with group
30
- expect(sortRoutes(asRouteNode("index"), asRouteNode("(z)"))).toBe(2);
31
- });
32
- it(`sorts group routes by priority`, () => {
33
- expect(sortRoutes(asRouteNode("(zzz)"), asRouteNode("[...a]"))).toBe(-1);
34
- expect(sortRoutes(asRouteNode("(zzz)"), asRouteNode("[a]"))).toBe(-1);
35
- expect(sortRoutes(asRouteNode("(zzz)"), asRouteNode("a"))).toBe(-1);
36
- expect(sortRoutes(asRouteNode("(zzz)"), asRouteNode("z"))).toBe(-1);
37
- expect(sortRoutes(asRouteNode("(zzz)"), asRouteNode("index"))).toBe(0);
38
- });
39
- it(`sorts multiple dynamic routes higher than a single deep dynamic route`, () => {
40
- // dynamic before deep dynamic
41
- expect(sortRoutes(asRouteNode("[a]/[b]"), asRouteNode("[...a]"))).toBe(-1);
42
- expect(sortRoutes(asRouteNode("[...a]"), asRouteNode("[a]/[b]"))).toBe(1);
43
- });
44
-
45
- it(`sorts dynamic routes by priority`, () => {
46
- // dynamic before deep dynamic
47
- expect(sortRoutes(asRouteNode("[a]"), asRouteNode("[...a]"))).toBe(-1);
48
- // tied with two dynamic routes
49
- expect(sortRoutes(asRouteNode("[a]"), asRouteNode("[b]"))).toBe(0);
50
- expect(sortRoutes(asRouteNode("[a]/[b]"), asRouteNode("[b]/[a]"))).toBe(0);
51
- // Lower priority
52
- expect(sortRoutes(asRouteNode("[a]"), asRouteNode("index"))).toBe(1);
53
- expect(sortRoutes(asRouteNode("[a]"), asRouteNode("a"))).toBe(1);
54
- expect(sortRoutes(asRouteNode("[a]"), asRouteNode("(a)"))).toBe(1);
55
- });
56
- it(`sorts deep dynamic routes by priority`, () => {
57
- expect(sortRoutes(asRouteNode("[...a]"), asRouteNode("[...beta]"))).toBe(0);
58
- expect(
59
- sortRoutes(asRouteNode("[...a]/[b]"), asRouteNode("[...beta]/[c]"))
60
- ).toBe(0);
61
- // Lower priority
62
- expect(sortRoutes(asRouteNode("[...a]"), asRouteNode("[b]"))).toBe(1);
63
- expect(sortRoutes(asRouteNode("[...a]/[a]"), asRouteNode("[b]/[c]"))).toBe(
64
- 1
65
- );
66
- expect(sortRoutes(asRouteNode("[...a]"), asRouteNode("index"))).toBe(1);
67
- expect(sortRoutes(asRouteNode("[...a]"), asRouteNode("a"))).toBe(1);
68
- expect(sortRoutes(asRouteNode("[...a]"), asRouteNode("(a)"))).toBe(1);
69
- });
70
- });
@@ -1,138 +0,0 @@
1
- import { getReactNavigationScreensConfig } from "../getReactNavigationConfig";
2
-
3
- const mockRoutes = [
4
- {
5
- children: [
6
- {
7
- children: [],
8
- dynamic: null,
9
- route: "people",
10
- contextKey: "./(second-group)/people.tsx",
11
- },
12
- ],
13
- dynamic: null,
14
- route: "(second-group)",
15
- contextKey: "./(second-group)/_layout.tsx",
16
- },
17
- {
18
- children: [
19
- {
20
- children: [],
21
- dynamic: [
22
- {
23
- name: "deep",
24
- deep: true,
25
- },
26
- ],
27
- route: "[...deep]",
28
- contextKey: "./(group)/[...deep].tsx",
29
- },
30
- {
31
- children: [],
32
- dynamic: [
33
- {
34
- name: "dynamic",
35
- deep: false,
36
- },
37
- ],
38
- route: "[dynamic]",
39
- contextKey: "./(group)/[dynamic].tsx",
40
- },
41
- {
42
- children: [],
43
- dynamic: null,
44
- route: "index",
45
- contextKey: "./(group)/index.tsx",
46
- },
47
- ],
48
- dynamic: null,
49
- route: "(group)",
50
- contextKey: "./(group)/_layout.tsx",
51
- },
52
- {
53
- children: [],
54
- dynamic: [
55
- {
56
- name: "screen",
57
- deep: true,
58
- },
59
- ],
60
- route: "other/nested/[...screen]",
61
- contextKey: "./other/nested/[...screen].js",
62
- },
63
- {
64
- children: [],
65
- dynamic: null,
66
- route: "_sitemap",
67
- contextKey: "./_sitemap.tsx",
68
- generated: true,
69
- internal: true,
70
- },
71
- ];
72
-
73
- describe(getReactNavigationScreensConfig, () => {
74
- it("should return a valid linking config", () => {
75
- expect(
76
- getReactNavigationScreensConfig(
77
- // @ts-expect-error
78
- mockRoutes,
79
- true
80
- )
81
- ).toEqual({
82
- "(group)": {
83
- initialRouteName: undefined,
84
- path: "(group)",
85
- screens: { "[...deep]": "*deep", "[dynamic]": ":dynamic", index: "" },
86
- },
87
- "(second-group)": {
88
- initialRouteName: undefined,
89
- path: "(second-group)",
90
- screens: { people: "people" },
91
- },
92
- _sitemap: "_sitemap",
93
- "other/nested/[...screen]": "other/nested/*screen",
94
- });
95
- });
96
- it("should return a valid linking config with route nodes", () => {
97
- expect(
98
- getReactNavigationScreensConfig(
99
- // @ts-expect-error
100
- mockRoutes,
101
- false
102
- )
103
- ).toEqual({
104
- "(group)": {
105
- initialRouteName: undefined,
106
- path: "(group)",
107
- _route: expect.anything(),
108
- screens: {
109
- "[...deep]": {
110
- path: "*deep",
111
- screens: {},
112
- _route: expect.anything(),
113
- },
114
- "[dynamic]": {
115
- path: ":dynamic",
116
- screens: {},
117
- _route: expect.anything(),
118
- },
119
- index: { path: "", screens: {}, _route: expect.anything() },
120
- },
121
- },
122
- "(second-group)": {
123
- initialRouteName: undefined,
124
- path: "(second-group)",
125
- _route: expect.anything(),
126
- screens: {
127
- people: { path: "people", screens: {}, _route: expect.anything() },
128
- },
129
- },
130
- _sitemap: { path: "_sitemap", screens: {}, _route: expect.anything() },
131
- "other/nested/[...screen]": {
132
- path: "other/nested/*screen",
133
- screens: {},
134
- _route: expect.anything(),
135
- },
136
- });
137
- });
138
- });