@react-navigation/core 8.0.0-alpha.23 → 8.0.0-alpha.24

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 (60) hide show
  1. package/lib/module/NavigationBuilderContext.js.map +1 -1
  2. package/lib/module/StaticNavigation.js +1 -1
  3. package/lib/module/StaticNavigation.js.map +1 -1
  4. package/lib/module/createNavigatorFactory.js.map +1 -1
  5. package/lib/module/getPathFromState.js +87 -57
  6. package/lib/module/getPathFromState.js.map +1 -1
  7. package/lib/module/getStateFromPath.js +77 -46
  8. package/lib/module/getStateFromPath.js.map +1 -1
  9. package/lib/module/index.js.map +1 -1
  10. package/lib/module/types.js +13 -0
  11. package/lib/module/types.js.map +1 -1
  12. package/lib/module/useEventEmitter.js +4 -1
  13. package/lib/module/useEventEmitter.js.map +1 -1
  14. package/lib/module/useNavigationBuilder.js +1 -7
  15. package/lib/module/useNavigationBuilder.js.map +1 -1
  16. package/lib/module/useOnAction.js +4 -1
  17. package/lib/module/useOnAction.js.map +1 -1
  18. package/lib/module/useOnPreventRemove.js +35 -24
  19. package/lib/module/useOnPreventRemove.js.map +1 -1
  20. package/lib/module/useRoute.js.map +1 -1
  21. package/lib/module/validatePathConfig.js +50 -37
  22. package/lib/module/validatePathConfig.js.map +1 -1
  23. package/lib/typescript/src/NavigationBuilderContext.d.ts +2 -2
  24. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  25. package/lib/typescript/src/StaticNavigation.d.ts +3 -3
  26. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  27. package/lib/typescript/src/createNavigatorFactory.d.ts +4 -2
  28. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  29. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  30. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  31. package/lib/typescript/src/index.d.ts +1 -1
  32. package/lib/typescript/src/index.d.ts.map +1 -1
  33. package/lib/typescript/src/types.d.ts +66 -17
  34. package/lib/typescript/src/types.d.ts.map +1 -1
  35. package/lib/typescript/src/useEventEmitter.d.ts +1 -1
  36. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  37. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  38. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  39. package/lib/typescript/src/useOnPreventRemove.d.ts +2 -6
  40. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  41. package/lib/typescript/src/useRoute.d.ts +1 -1
  42. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  43. package/lib/typescript/src/utilities.d.ts +4 -38
  44. package/lib/typescript/src/utilities.d.ts.map +1 -1
  45. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  46. package/package.json +5 -5
  47. package/src/NavigationBuilderContext.tsx +5 -1
  48. package/src/StaticNavigation.tsx +7 -6
  49. package/src/createNavigatorFactory.tsx +23 -2
  50. package/src/getPathFromState.tsx +97 -66
  51. package/src/getStateFromPath.tsx +168 -142
  52. package/src/index.tsx +1 -0
  53. package/src/types.tsx +257 -33
  54. package/src/useEventEmitter.tsx +6 -1
  55. package/src/useNavigationBuilder.tsx +1 -8
  56. package/src/useOnAction.tsx +6 -2
  57. package/src/useOnPreventRemove.tsx +68 -36
  58. package/src/useRoute.tsx +3 -5
  59. package/src/utilities.tsx +8 -41
  60. package/src/validatePathConfig.tsx +85 -58
@@ -1,24 +1,39 @@
1
- const formatToList = (items: Record<string, string>) =>
2
- Object.entries(items)
3
- .map(([key, value]) => `- ${key} (${value})`)
4
- .join('\n');
1
+ const ROOT_VALIDATION_LIST = [
2
+ '- path (string)',
3
+ '- initialRouteName (string)',
4
+ '- screens (object)',
5
+ ].join('\n');
5
6
 
6
- export function validatePathConfig(config: unknown, root = true) {
7
- const validation = {
8
- path: 'string',
9
- initialRouteName: 'string',
10
- screens: 'object',
11
- ...(root
12
- ? null
13
- : {
14
- alias: 'array',
15
- exact: 'boolean',
16
- stringify: 'object',
17
- parse: 'object',
18
- shared: 'boolean',
19
- }),
20
- };
7
+ const NESTED_VALIDATION_LIST = [
8
+ ROOT_VALIDATION_LIST,
9
+ '- alias (array)',
10
+ '- exact (boolean)',
11
+ '- stringify (object)',
12
+ '- parse (object)',
13
+ '- shared (boolean)',
14
+ ].join('\n');
15
+
16
+ const getValidationType = (key: string, root: boolean) => {
17
+ switch (key) {
18
+ case 'path':
19
+ case 'initialRouteName':
20
+ return 'string';
21
+ case 'screens':
22
+ return 'object';
23
+ case 'alias':
24
+ return root ? undefined : 'array';
25
+ case 'exact':
26
+ case 'shared':
27
+ return root ? undefined : 'boolean';
28
+ case 'stringify':
29
+ case 'parse':
30
+ return root ? undefined : 'object';
31
+ default:
32
+ return undefined;
33
+ }
34
+ };
21
35
 
36
+ export function validatePathConfig(config: unknown, root = true) {
22
37
  if (typeof config !== 'object' || config === null) {
23
38
  throw new Error(
24
39
  `Expected the configuration to be an object, but got ${JSON.stringify(
@@ -27,58 +42,70 @@ export function validatePathConfig(config: unknown, root = true) {
27
42
  );
28
43
  }
29
44
 
30
- const validationErrors = Object.fromEntries(
31
- Object.keys(config)
32
- .map((key) => {
33
- if (key in validation) {
34
- const type = validation[key as keyof typeof validation];
35
- // @ts-expect-error: we know the key exists
36
- const value = config[key];
37
-
38
- if (value !== undefined) {
39
- if (type === 'array') {
40
- if (!Array.isArray(value)) {
41
- return [key, `expected 'Array', got '${typeof value}'`];
42
- }
43
- } else if (typeof value !== type) {
44
- return [key, `expected '${type}', got '${typeof value}'`];
45
- }
46
- }
47
- } else {
48
- return [key, 'extraneous'];
49
- }
50
-
51
- return null;
52
- })
53
- .filter(Boolean) as [string, string][]
54
- );
55
-
56
- if (Object.keys(validationErrors).length) {
45
+ const pathConfig = config as Record<string, unknown>;
46
+ let validationErrors: string[] | undefined;
47
+
48
+ for (const key in pathConfig) {
49
+ const type = getValidationType(key, root);
50
+
51
+ if (type === undefined) {
52
+ (validationErrors ??= []).push(`- ${key} (extraneous)`);
53
+ continue;
54
+ }
55
+
56
+ const value = pathConfig[key];
57
+
58
+ if (value === undefined) {
59
+ continue;
60
+ }
61
+
62
+ if (type === 'array') {
63
+ if (!Array.isArray(value)) {
64
+ (validationErrors ??= []).push(
65
+ `- ${key} (expected 'Array', got '${typeof value}')`
66
+ );
67
+ }
68
+ } else if (typeof value !== type) {
69
+ (validationErrors ??= []).push(
70
+ `- ${key} (expected '${type}', got '${typeof value}')`
71
+ );
72
+ }
73
+ }
74
+
75
+ if (validationErrors) {
57
76
  throw new Error(
58
- `Found invalid properties in the configuration:\n${formatToList(
59
- validationErrors
60
- )}\n\nYou can only specify the following properties:\n${formatToList(
61
- validation
62
- )}\n\nIf you want to specify configuration for screens, you need to specify them under a 'screens' property.\n\nSee https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration.`
77
+ `Found invalid properties in the configuration:\n${validationErrors.join(
78
+ '\n'
79
+ )}\n\nYou can only specify the following properties:\n${
80
+ root ? ROOT_VALIDATION_LIST : NESTED_VALIDATION_LIST
81
+ }\n\nIf you want to specify configuration for screens, you need to specify them under a 'screens' property.\n\nSee https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration.`
63
82
  );
64
83
  }
65
84
 
85
+ const path = pathConfig.path;
86
+
66
87
  if (
67
88
  root &&
68
- 'path' in config &&
69
- typeof config.path === 'string' &&
70
- config.path.includes(':')
89
+ 'path' in pathConfig &&
90
+ typeof path === 'string' &&
91
+ path.includes(':')
71
92
  ) {
72
93
  throw new Error(
73
- `Found invalid path '${config.path}'. The 'path' in the top-level configuration cannot contain patterns for params.`
94
+ `Found invalid path '${path}'. The 'path' in the top-level configuration cannot contain patterns for params.`
74
95
  );
75
96
  }
76
97
 
77
- if ('screens' in config && config.screens) {
78
- Object.entries(config.screens).forEach(([_, value]) => {
98
+ const screens = pathConfig.screens;
99
+
100
+ if (screens && typeof screens === 'object') {
101
+ const screenConfig = screens as Record<string, unknown>;
102
+
103
+ for (const name in screenConfig) {
104
+ const value = screenConfig[name];
105
+
79
106
  if (typeof value !== 'string') {
80
107
  validatePathConfig(value, false);
81
108
  }
82
- });
109
+ }
83
110
  }
84
111
  }