one 1.1.473 → 1.1.475

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 (245) hide show
  1. package/dist/cjs/Root.cjs +5 -1
  2. package/dist/cjs/Root.js +2 -2
  3. package/dist/cjs/Root.js.map +1 -1
  4. package/dist/cjs/Root.native.js +5 -2
  5. package/dist/cjs/Root.native.js.map +2 -2
  6. package/dist/cjs/createApp.cjs +2 -0
  7. package/dist/cjs/createApp.js +16 -2
  8. package/dist/cjs/createApp.js.map +1 -1
  9. package/dist/cjs/createApp.native.js +1 -0
  10. package/dist/cjs/createApp.native.js.map +2 -2
  11. package/dist/cjs/fork/__tests__/getPathFromState.test.cjs +1440 -0
  12. package/dist/cjs/fork/__tests__/getPathFromState.test.js +1559 -0
  13. package/dist/cjs/fork/__tests__/getPathFromState.test.js.map +6 -0
  14. package/dist/cjs/fork/__tests__/getPathFromState.test.native.js +1726 -0
  15. package/dist/cjs/fork/__tests__/getPathFromState.test.native.js.map +6 -0
  16. package/dist/cjs/fork/__tests__/getStateFromPath.test.cjs +2565 -0
  17. package/dist/cjs/fork/__tests__/getStateFromPath.test.js +2702 -0
  18. package/dist/cjs/fork/__tests__/getStateFromPath.test.js.map +6 -0
  19. package/dist/cjs/fork/__tests__/getStateFromPath.test.native.js +2861 -0
  20. package/dist/cjs/fork/__tests__/getStateFromPath.test.native.js.map +6 -0
  21. package/dist/cjs/fork/getPathFromState.cjs +2 -1
  22. package/dist/cjs/fork/getPathFromState.js +1 -1
  23. package/dist/cjs/fork/getPathFromState.js.map +1 -1
  24. package/dist/cjs/fork/getPathFromState.native.js +10 -5
  25. package/dist/cjs/fork/getPathFromState.native.js.map +1 -1
  26. package/dist/cjs/fork/getPathFromState.test.cjs +113 -0
  27. package/dist/cjs/fork/getPathFromState.test.js +122 -0
  28. package/dist/cjs/fork/getPathFromState.test.js.map +6 -0
  29. package/dist/cjs/fork/getPathFromState.test.native.js +135 -0
  30. package/dist/cjs/fork/getPathFromState.test.native.js.map +6 -0
  31. package/dist/cjs/fork/getStateFromPath.test.cjs +229 -0
  32. package/dist/cjs/fork/getStateFromPath.test.js +290 -0
  33. package/dist/cjs/fork/getStateFromPath.test.js.map +6 -0
  34. package/dist/cjs/fork/getStateFromPath.test.native.js +374 -0
  35. package/dist/cjs/fork/getStateFromPath.test.native.js.map +6 -0
  36. package/dist/cjs/render.cjs +1 -1
  37. package/dist/cjs/render.js +1 -1
  38. package/dist/cjs/render.js.map +1 -1
  39. package/dist/cjs/router/FlagsContext.cjs +27 -0
  40. package/dist/cjs/router/FlagsContext.js +22 -0
  41. package/dist/cjs/router/FlagsContext.js.map +6 -0
  42. package/dist/cjs/router/FlagsContext.native.js +26 -0
  43. package/dist/cjs/router/FlagsContext.native.js.map +6 -0
  44. package/dist/cjs/router/getRoutes.cjs +11 -1
  45. package/dist/cjs/router/getRoutes.js +11 -1
  46. package/dist/cjs/router/getRoutes.js.map +1 -1
  47. package/dist/cjs/router/getRoutes.native.js +11 -1
  48. package/dist/cjs/router/getRoutes.native.js.map +2 -2
  49. package/dist/cjs/router/matchers.test.cjs +38 -0
  50. package/dist/cjs/router/matchers.test.js +42 -0
  51. package/dist/cjs/router/matchers.test.js.map +6 -0
  52. package/dist/cjs/router/matchers.test.native.js +39 -0
  53. package/dist/cjs/router/matchers.test.native.js.map +6 -0
  54. package/dist/cjs/router/router.cjs +3 -35
  55. package/dist/cjs/router/router.js +2 -26
  56. package/dist/cjs/router/router.js.map +1 -1
  57. package/dist/cjs/router/router.native.js +2 -33
  58. package/dist/cjs/router/router.native.js.map +2 -2
  59. package/dist/cjs/router/utils/getNavigateAction.cjs +61 -0
  60. package/dist/cjs/router/utils/getNavigateAction.js +46 -0
  61. package/dist/cjs/router/utils/getNavigateAction.js.map +6 -0
  62. package/dist/cjs/router/utils/getNavigateAction.native.js +58 -0
  63. package/dist/cjs/router/utils/getNavigateAction.native.js.map +6 -0
  64. package/dist/cjs/router/utils/getNavigateAction.test.cjs +259 -0
  65. package/dist/cjs/router/utils/getNavigateAction.test.js +295 -0
  66. package/dist/cjs/router/utils/getNavigateAction.test.js.map +6 -0
  67. package/dist/cjs/router/utils/getNavigateAction.test.native.js +330 -0
  68. package/dist/cjs/router/utils/getNavigateAction.test.native.js.map +6 -0
  69. package/dist/cjs/testing-utils.cjs +63 -0
  70. package/dist/cjs/testing-utils.js +55 -0
  71. package/dist/cjs/testing-utils.js.map +6 -0
  72. package/dist/cjs/testing-utils.native.js +79 -0
  73. package/dist/cjs/testing-utils.native.js.map +6 -0
  74. package/dist/cjs/views/Navigator.cjs +8 -1
  75. package/dist/cjs/views/Navigator.js +25 -11
  76. package/dist/cjs/views/Navigator.js.map +1 -1
  77. package/dist/cjs/views/Navigator.native.js +7 -4
  78. package/dist/cjs/views/Navigator.native.js.map +2 -2
  79. package/dist/cjs/vite/one.cjs +6 -1
  80. package/dist/cjs/vite/one.js +6 -1
  81. package/dist/cjs/vite/one.js.map +1 -1
  82. package/dist/cjs/vite/one.native.js +7 -2
  83. package/dist/cjs/vite/one.native.js.map +2 -2
  84. package/dist/cjs/vite/plugins/virtualEntryPlugin.cjs +2 -0
  85. package/dist/cjs/vite/plugins/virtualEntryPlugin.js +2 -0
  86. package/dist/cjs/vite/plugins/virtualEntryPlugin.js.map +1 -1
  87. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js +2 -0
  88. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +2 -2
  89. package/dist/esm/Root.js +2 -1
  90. package/dist/esm/Root.js.map +1 -1
  91. package/dist/esm/Root.mjs +5 -1
  92. package/dist/esm/Root.mjs.map +1 -1
  93. package/dist/esm/Root.native.js +5 -1
  94. package/dist/esm/Root.native.js.map +1 -1
  95. package/dist/esm/createApp.js +16 -2
  96. package/dist/esm/createApp.js.map +1 -1
  97. package/dist/esm/createApp.mjs +2 -0
  98. package/dist/esm/createApp.mjs.map +1 -1
  99. package/dist/esm/createApp.native.js +1 -0
  100. package/dist/esm/createApp.native.js.map +1 -1
  101. package/dist/esm/fork/__tests__/getPathFromState.test.js +1561 -0
  102. package/dist/esm/fork/__tests__/getPathFromState.test.js.map +6 -0
  103. package/dist/esm/fork/__tests__/getPathFromState.test.mjs +1441 -0
  104. package/dist/esm/fork/__tests__/getPathFromState.test.mjs.map +1 -0
  105. package/dist/esm/fork/__tests__/getPathFromState.test.native.js +1580 -0
  106. package/dist/esm/fork/__tests__/getPathFromState.test.native.js.map +1 -0
  107. package/dist/esm/fork/__tests__/getStateFromPath.test.js +2706 -0
  108. package/dist/esm/fork/__tests__/getStateFromPath.test.js.map +6 -0
  109. package/dist/esm/fork/__tests__/getStateFromPath.test.mjs +2566 -0
  110. package/dist/esm/fork/__tests__/getStateFromPath.test.mjs.map +1 -0
  111. package/dist/esm/fork/__tests__/getStateFromPath.test.native.js +2636 -0
  112. package/dist/esm/fork/__tests__/getStateFromPath.test.native.js.map +1 -0
  113. package/dist/esm/fork/getPathFromState.js +1 -1
  114. package/dist/esm/fork/getPathFromState.js.map +1 -1
  115. package/dist/esm/fork/getPathFromState.mjs +2 -1
  116. package/dist/esm/fork/getPathFromState.mjs.map +1 -1
  117. package/dist/esm/fork/getPathFromState.native.js +9 -5
  118. package/dist/esm/fork/getPathFromState.native.js.map +1 -1
  119. package/dist/esm/fork/getPathFromState.test.js +123 -0
  120. package/dist/esm/fork/getPathFromState.test.js.map +6 -0
  121. package/dist/esm/fork/getPathFromState.test.mjs +114 -0
  122. package/dist/esm/fork/getPathFromState.test.mjs.map +1 -0
  123. package/dist/esm/fork/getPathFromState.test.native.js +122 -0
  124. package/dist/esm/fork/getPathFromState.test.native.js.map +1 -0
  125. package/dist/esm/fork/getStateFromPath.test.js +294 -0
  126. package/dist/esm/fork/getStateFromPath.test.js.map +6 -0
  127. package/dist/esm/fork/getStateFromPath.test.mjs +230 -0
  128. package/dist/esm/fork/getStateFromPath.test.mjs.map +1 -0
  129. package/dist/esm/fork/getStateFromPath.test.native.js +233 -0
  130. package/dist/esm/fork/getStateFromPath.test.native.js.map +1 -0
  131. package/dist/esm/render.js +1 -1
  132. package/dist/esm/render.js.map +1 -1
  133. package/dist/esm/render.mjs +1 -1
  134. package/dist/esm/render.mjs.map +1 -1
  135. package/dist/esm/router/FlagsContext.js +6 -0
  136. package/dist/esm/router/FlagsContext.js.map +6 -0
  137. package/dist/esm/router/FlagsContext.mjs +4 -0
  138. package/dist/esm/router/FlagsContext.mjs.map +1 -0
  139. package/dist/esm/router/FlagsContext.native.js +4 -0
  140. package/dist/esm/router/FlagsContext.native.js.map +1 -0
  141. package/dist/esm/router/getRoutes.js +11 -1
  142. package/dist/esm/router/getRoutes.js.map +1 -1
  143. package/dist/esm/router/getRoutes.mjs +11 -1
  144. package/dist/esm/router/getRoutes.mjs.map +1 -1
  145. package/dist/esm/router/getRoutes.native.js +11 -1
  146. package/dist/esm/router/getRoutes.native.js.map +1 -1
  147. package/dist/esm/router/matchers.test.js +50 -0
  148. package/dist/esm/router/matchers.test.js.map +6 -0
  149. package/dist/esm/router/matchers.test.mjs +39 -0
  150. package/dist/esm/router/matchers.test.mjs.map +1 -0
  151. package/dist/esm/router/matchers.test.native.js +39 -0
  152. package/dist/esm/router/matchers.test.native.js.map +1 -0
  153. package/dist/esm/router/router.js +1 -26
  154. package/dist/esm/router/router.js.map +1 -1
  155. package/dist/esm/router/router.mjs +1 -33
  156. package/dist/esm/router/router.mjs.map +1 -1
  157. package/dist/esm/router/router.native.js +1 -37
  158. package/dist/esm/router/router.native.js.map +1 -1
  159. package/dist/esm/router/utils/getNavigateAction.js +32 -0
  160. package/dist/esm/router/utils/getNavigateAction.js.map +6 -0
  161. package/dist/esm/router/utils/getNavigateAction.mjs +38 -0
  162. package/dist/esm/router/utils/getNavigateAction.mjs.map +1 -0
  163. package/dist/esm/router/utils/getNavigateAction.native.js +42 -0
  164. package/dist/esm/router/utils/getNavigateAction.native.js.map +1 -0
  165. package/dist/esm/router/utils/getNavigateAction.test.js +296 -0
  166. package/dist/esm/router/utils/getNavigateAction.test.js.map +6 -0
  167. package/dist/esm/router/utils/getNavigateAction.test.mjs +260 -0
  168. package/dist/esm/router/utils/getNavigateAction.test.mjs.map +1 -0
  169. package/dist/esm/router/utils/getNavigateAction.test.native.js +273 -0
  170. package/dist/esm/router/utils/getNavigateAction.test.native.js.map +1 -0
  171. package/dist/esm/testing-utils.js +33 -0
  172. package/dist/esm/testing-utils.js.map +6 -0
  173. package/dist/esm/testing-utils.mjs +27 -0
  174. package/dist/esm/testing-utils.mjs.map +1 -0
  175. package/dist/esm/testing-utils.native.js +38 -0
  176. package/dist/esm/testing-utils.native.js.map +1 -0
  177. package/dist/esm/views/Navigator.js +29 -11
  178. package/dist/esm/views/Navigator.js.map +1 -1
  179. package/dist/esm/views/Navigator.mjs +8 -1
  180. package/dist/esm/views/Navigator.mjs.map +1 -1
  181. package/dist/esm/views/Navigator.native.js +8 -2
  182. package/dist/esm/views/Navigator.native.js.map +1 -1
  183. package/dist/esm/vite/one.js +6 -1
  184. package/dist/esm/vite/one.js.map +1 -1
  185. package/dist/esm/vite/one.mjs +6 -1
  186. package/dist/esm/vite/one.mjs.map +1 -1
  187. package/dist/esm/vite/one.native.js +9 -2
  188. package/dist/esm/vite/one.native.js.map +1 -1
  189. package/dist/esm/vite/plugins/virtualEntryPlugin.js +2 -0
  190. package/dist/esm/vite/plugins/virtualEntryPlugin.js.map +1 -1
  191. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs +2 -0
  192. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs.map +1 -1
  193. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js +2 -0
  194. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  195. package/package.json +13 -10
  196. package/src/Root.tsx +12 -2
  197. package/src/createApp.native.tsx +8 -2
  198. package/src/createApp.tsx +18 -3
  199. package/src/fork/__tests__/README.md +8 -0
  200. package/src/fork/__tests__/getPathFromState.test.tsx +1809 -0
  201. package/src/fork/__tests__/getStateFromPath.test.tsx +3188 -0
  202. package/src/fork/getPathFromState.test.ts +146 -0
  203. package/src/fork/getPathFromState.ts +1 -1
  204. package/src/fork/getStateFromPath.test.ts +345 -0
  205. package/src/render.tsx +3 -3
  206. package/src/router/FlagsContext.ts +4 -0
  207. package/src/router/getRoutes.ts +14 -2
  208. package/src/router/matchers.test.ts +120 -0
  209. package/src/router/router.ts +1 -113
  210. package/src/router/utils/getNavigateAction.test.ts +334 -0
  211. package/src/router/utils/getNavigateAction.ts +120 -0
  212. package/src/testing-utils.ts +56 -0
  213. package/src/views/Navigator.tsx +34 -10
  214. package/src/vite/one.ts +5 -0
  215. package/src/vite/plugins/virtualEntryPlugin.ts +4 -1
  216. package/src/vite/types.ts +18 -0
  217. package/types/Root.d.ts +1 -0
  218. package/types/Root.d.ts.map +1 -1
  219. package/types/createApp.d.ts +2 -0
  220. package/types/createApp.d.ts.map +1 -1
  221. package/types/createApp.native.d.ts +2 -0
  222. package/types/createApp.native.d.ts.map +1 -1
  223. package/types/fork/getPathFromState.test.d.ts +2 -0
  224. package/types/fork/getPathFromState.test.d.ts.map +1 -0
  225. package/types/fork/getStateFromPath.test.d.ts +2 -0
  226. package/types/fork/getStateFromPath.test.d.ts.map +1 -0
  227. package/types/router/FlagsContext.d.ts +3 -0
  228. package/types/router/FlagsContext.d.ts.map +1 -0
  229. package/types/router/getRoutes.d.ts.map +1 -1
  230. package/types/router/matchers.test.d.ts +2 -0
  231. package/types/router/matchers.test.d.ts.map +1 -0
  232. package/types/router/router.d.ts.map +1 -1
  233. package/types/router/utils/getNavigateAction.d.ts +17 -0
  234. package/types/router/utils/getNavigateAction.d.ts.map +1 -0
  235. package/types/router/utils/getNavigateAction.test.d.ts +2 -0
  236. package/types/router/utils/getNavigateAction.test.d.ts.map +1 -0
  237. package/types/testing-utils.d.ts +26 -0
  238. package/types/testing-utils.d.ts.map +1 -0
  239. package/types/views/Navigator.d.ts +1 -1
  240. package/types/views/Navigator.d.ts.map +1 -1
  241. package/types/vite/one.d.ts.map +1 -1
  242. package/types/vite/plugins/virtualEntryPlugin.d.ts +2 -0
  243. package/types/vite/plugins/virtualEntryPlugin.d.ts.map +1 -1
  244. package/types/vite/types.d.ts +16 -0
  245. package/types/vite/types.d.ts.map +1 -1
@@ -0,0 +1,146 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import type { PathConfigMap } from '@react-navigation/core'
3
+
4
+ import { getPathFromState, type State } from './getPathFromState'
5
+
6
+ describe('hash support', () => {
7
+ it('appends hash to the path', () => {
8
+ const state = {
9
+ index: 0,
10
+ key: 'key',
11
+ routes: [
12
+ {
13
+ name: 'index',
14
+ path: '/',
15
+ params: {
16
+ '#': 'hash1',
17
+ },
18
+ },
19
+ ],
20
+ stale: true,
21
+ type: 'stack',
22
+ }
23
+
24
+ const config = {
25
+ screens: {
26
+ index: '',
27
+ _sitemap: '_sitemap',
28
+ },
29
+ }
30
+
31
+ expect(getPathFromState(state, config)).toBe('/#hash1')
32
+ })
33
+
34
+ it('works with nested state, existing router and path params', () => {
35
+ const state = {
36
+ index: 1,
37
+ key: 'key',
38
+ routeNames: ['index', '[test]', '_sitemap', '+not-found'],
39
+ routes: [
40
+ {
41
+ key: 'key',
42
+ name: 'index',
43
+ params: undefined,
44
+ path: '/',
45
+ },
46
+ {
47
+ key: 'key',
48
+ name: '[test]',
49
+ params: {
50
+ test: 'hello-world',
51
+ query: 'true',
52
+ '#': 'a',
53
+ },
54
+ path: undefined,
55
+ },
56
+ ],
57
+ stale: false,
58
+ type: 'stack',
59
+ }
60
+
61
+ const config = {
62
+ screens: {
63
+ '[test]': ':test',
64
+ index: '',
65
+ _sitemap: '_sitemap',
66
+ },
67
+ }
68
+
69
+ expect(getPathFromState(state, config)).toBe('/hello-world?query=true#a')
70
+ })
71
+ })
72
+
73
+ // TODO
74
+ it.skip(`handles url search params params`, () => {
75
+ const state = {
76
+ routes: [
77
+ {
78
+ name: 'index',
79
+ params: {
80
+ test: 'true',
81
+ hello: 'world',
82
+ array: ['1', '2'],
83
+ },
84
+ path: '/?test=true&hello=world&array=1&array=2',
85
+ },
86
+ ],
87
+ }
88
+
89
+ const config = {
90
+ screens: {
91
+ index: '',
92
+ _sitemap: '_sitemap',
93
+ },
94
+ }
95
+
96
+ expect(getPathFromState(state, config)).toBe('/?test=true&hello=world&array=1&array=2')
97
+ })
98
+
99
+ it(`handles uninitialized state on nested navigation with route params`, () => {
100
+ const config = {
101
+ screens: {
102
+ index: '',
103
+ '[folderSlugL1]': {
104
+ path: ':folderSlugL1',
105
+ screens: {
106
+ '[folderSlugL2]': {
107
+ path: ':folderSlugL2',
108
+ screens: {
109
+ '[folderSlugL3]': {
110
+ path: ':folderSlugL3',
111
+ screens: {
112
+ page: 'page',
113
+ },
114
+ },
115
+ },
116
+ },
117
+ },
118
+ },
119
+ },
120
+ } satisfies { screens: PathConfigMap<any> }
121
+
122
+ const state = {
123
+ routes: [
124
+ {
125
+ name: '[folderSlugL1]',
126
+ params: {
127
+ folderSlugL1: 'foo',
128
+ screen: '[folderSlugL2]',
129
+ params: {
130
+ folderSlugL1: 'foo',
131
+ folderSlugL2: 'bar',
132
+ screen: '[folderSlugL3]',
133
+ params: {
134
+ folderSlugL1: 'foo',
135
+ folderSlugL2: 'bar',
136
+ folderSlugL3: 'baz',
137
+ screen: 'page',
138
+ },
139
+ },
140
+ },
141
+ },
142
+ ],
143
+ } satisfies State
144
+
145
+ expect(getPathFromState(state, config)).toBe('/foo/bar/baz/page')
146
+ })
@@ -233,7 +233,7 @@ export function getPathDataFromState<ParamList extends {}>(
233
233
  : undefined
234
234
 
235
235
  if (screen && screens && currentOptions[route.name].screens?.[screen]) {
236
- route = { ...screens[screen], name: screen, key: screen }
236
+ route = { ...screens[screen], name: screen, key: screen, params: (route.params as any)?.params }
237
237
  currentOptions = screens
238
238
  } else {
239
239
  hasNext = false
@@ -0,0 +1,345 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest'
2
+ import { getMockConfig } from '../testing-utils'
3
+ import { getPathFromState } from './getPathFromState'
4
+ import { getStateFromPath } from './getStateFromPath'
5
+ import { getUrlWithReactNavigationConcessions, stripBaseUrl } from './getStateFromPath-mods'
6
+
7
+
8
+
9
+ describe(stripBaseUrl, () => {
10
+ ;[
11
+ [
12
+ // Input
13
+ '/',
14
+ // Base Path
15
+ '',
16
+ // Result
17
+ '/',
18
+ ],
19
+ ['/one/two', '/one', '/two'],
20
+ ['/one/two', '/one/two', ''],
21
+ ['/one/two/', '/one/two', '/'],
22
+ ['///one/', '/one', '/'],
23
+ ['one/', '/one', 'one/'],
24
+ ['/a/b', '/one', '/a/b'],
25
+ ].forEach(([path, baseUrl, result]) => {
26
+ it(`strips baseUrl "${path}"`, () => {
27
+ expect(stripBaseUrl(path, baseUrl)).toBe(result)
28
+ })
29
+ })
30
+ })
31
+
32
+ describe('baseUrl', () => {
33
+ beforeEach(() => {
34
+ process.env.ONE_DEFAULT_RENDER_MODE = 'spa'
35
+ })
36
+
37
+ it('accounts for baseUrl', () => {
38
+ process.env.EXPO_BASE_URL = '/expo/prefix'
39
+
40
+ const path = '/expo/prefix/bar'
41
+ const config = getMockConfig(['_layout.tsx', 'bar.tsx', 'index.tsx'])
42
+
43
+ expect(getStateFromPath<object>(path, config)).toEqual({
44
+ routes: [{ name: 'bar', path: '/bar' }],
45
+ })
46
+
47
+ expect(getPathFromState(getStateFromPath<object>(path, config)!, config)).toBe(
48
+ '/expo/prefix/bar'
49
+ )
50
+ })
51
+
52
+ it('has baseUrl and state that does not match', () => {
53
+ process.env.EXPO_BASE_URL = '/expo'
54
+ const path = '/bar'
55
+ const config = getMockConfig(['_layout.tsx', 'bar.tsx', 'index.tsx'])
56
+
57
+ expect(getStateFromPath<object>(path, config)).toEqual({
58
+ routes: [{ name: 'bar', path: '/bar' }],
59
+ })
60
+ expect(getPathFromState(getStateFromPath<object>(path, config)!, config)).toBe('/expo/bar')
61
+ })
62
+ })
63
+
64
+ describe(getUrlWithReactNavigationConcessions, () => {
65
+ beforeEach(() => {
66
+ delete process.env.EXPO_BASE_URL
67
+ })
68
+
69
+ ;['/', 'foo/', 'foo/bar/', 'foo/bar/baz/'].forEach((path) => {
70
+ it(`returns the pathname for ${path}`, () => {
71
+ expect(getUrlWithReactNavigationConcessions(path).nonstandardPathname).toBe(path)
72
+ })
73
+ })
74
+
75
+ ;[
76
+ ['', '/'],
77
+ ['https://acme.com/hello/world?foo=bar#123', 'hello/world/'],
78
+ ['https://acme.com/hello/world/?foo=bar#123', 'hello/world/'],
79
+ ].forEach(([url, expected]) => {
80
+ it(`returns the pathname for ${url}`, () => {
81
+ expect(getUrlWithReactNavigationConcessions(url).nonstandardPathname).toBe(expected)
82
+ })
83
+ })
84
+
85
+ ;[
86
+ ['/gh-pages/', '/'],
87
+ ['https://acme.com/gh-pages/hello/world?foo=bar#123', 'hello/world/'],
88
+ ['https://acme.com/gh-pages/hello/world/?foo=bar#123', 'hello/world/'],
89
+ ].forEach(([url, expected]) => {
90
+ it(`returns the pathname for ${url}`, () => {
91
+ expect(getUrlWithReactNavigationConcessions(url, 'gh-pages').nonstandardPathname).toBe(
92
+ expected
93
+ )
94
+ })
95
+ })
96
+ })
97
+
98
+ describe('hash', () => {
99
+ it(`parses hashes`, () => {
100
+ expect(
101
+ getStateFromPath('/hello#123', {
102
+ screens: {
103
+ hello: 'hello',
104
+ },
105
+ } as any)
106
+ ).toEqual({
107
+ routes: [
108
+ {
109
+ name: 'hello',
110
+ path: '/hello#123',
111
+ params: {
112
+ '#': '123',
113
+ },
114
+ },
115
+ ],
116
+ })
117
+ })
118
+
119
+ it('parses hashes with dynamic routes', () => {
120
+ expect(getStateFromPath('/hello#123', getMockConfig(['[hello]']))).toEqual({
121
+ routes: [
122
+ {
123
+ name: '[hello]',
124
+ params: {
125
+ hello: 'hello',
126
+ '#': '123',
127
+ },
128
+ path: '/hello#123',
129
+ },
130
+ ],
131
+ })
132
+ })
133
+
134
+ it('parses hashes with query params', () => {
135
+ expect(getStateFromPath('/?#123', getMockConfig(['index']))).toEqual({
136
+ routes: [
137
+ {
138
+ name: 'index',
139
+ path: '/?#123',
140
+ params: {
141
+ '#': '123',
142
+ },
143
+ },
144
+ ],
145
+ })
146
+
147
+ // TODO: Test rest params
148
+ })
149
+ })
150
+
151
+ it(`supports spaces`, () => {
152
+ expect(
153
+ getStateFromPath('/hello%20world', {
154
+ screens: {
155
+ 'hello world': 'hello world',
156
+ },
157
+ } as any)
158
+ ).toEqual({
159
+ routes: [
160
+ {
161
+ name: 'hello world',
162
+ path: '/hello%20world',
163
+ },
164
+ ],
165
+ })
166
+
167
+ expect(getStateFromPath('/hello%20world', getMockConfig(['[hello world]']))).toEqual({
168
+ routes: [
169
+ {
170
+ name: '[hello world]',
171
+ params: {
172
+ 'hello world': 'hello world',
173
+ },
174
+ path: '/hello%20world',
175
+ },
176
+ ],
177
+ })
178
+
179
+ // TODO: Test rest params
180
+ })
181
+
182
+ // TODO
183
+ it.skip(`matches against dynamic groups`, () => {
184
+ /*
185
+ * This will match (app)/([user])/[user]/index with a user = '(explore)'
186
+ * It may appear that '(explore)' is a group name but there is not value to match '[user]'
187
+ * So it doesn't match any routes in the '(explore)' group
188
+ * Therefore, '(explore)' is used as the value for '[user]'
189
+ */
190
+ expect(
191
+ getStateFromPath(
192
+ '/(app)/(explore)',
193
+ getMockConfig([
194
+ '+not-found',
195
+ '(app)/_layout',
196
+ '(app)/(explore)/_layout',
197
+ '(app)/(explore)/[user]/index',
198
+ '(app)/(explore)/explore',
199
+
200
+ '(app)/([user])/_layout',
201
+ '(app)/([user])/[user]/index',
202
+ '(app)/([user])/explore',
203
+ ])
204
+ )
205
+ ).toEqual({
206
+ routes: [
207
+ {
208
+ name: '(app)',
209
+ params: { user: '(explore)' },
210
+ state: {
211
+ routes: [
212
+ {
213
+ name: '([user])',
214
+ params: { user: '(explore)' },
215
+ state: {
216
+ routes: [
217
+ {
218
+ name: '[user]/index',
219
+ params: { user: '(explore)' },
220
+ path: '',
221
+ },
222
+ ],
223
+ },
224
+ },
225
+ ],
226
+ },
227
+ },
228
+ ],
229
+ })
230
+ })
231
+
232
+ it(`adds dynamic route params from all levels of the path`, () => {
233
+ // A route at `app/[foo]/bar/[baz]/other` should get all of the params from the path.
234
+ expect(
235
+ getStateFromPath(
236
+ '/foo/bar/baz/other',
237
+
238
+ getMockConfig([
239
+ '[foo]/_layout.tsx',
240
+ '[foo]/bar/_layout.tsx',
241
+ '[foo]/bar/[baz]/_layout.tsx',
242
+ '[foo]/bar/[baz]/other.tsx',
243
+ ])
244
+ )
245
+ ).toEqual({
246
+ routes: [
247
+ {
248
+ name: '[foo]',
249
+ params: { baz: 'baz', foo: 'foo' },
250
+ state: {
251
+ routes: [
252
+ {
253
+ name: 'bar',
254
+ params: { baz: 'baz', foo: 'foo' },
255
+ state: {
256
+ routes: [
257
+ {
258
+ name: '[baz]',
259
+ params: { baz: 'baz', foo: 'foo' },
260
+ state: {
261
+ routes: [
262
+ {
263
+ name: 'other',
264
+ params: {
265
+ baz: 'baz',
266
+ foo: 'foo',
267
+ },
268
+ path: '/foo/bar/baz/other',
269
+ },
270
+ ],
271
+ },
272
+ },
273
+ ],
274
+ },
275
+ },
276
+ ],
277
+ },
278
+ },
279
+ ],
280
+ })
281
+ })
282
+
283
+ it(`handles not-found routes`, () => {
284
+ expect(getStateFromPath('/missing-page', getMockConfig(['+not-found', 'index']))).toEqual({
285
+ routes: [
286
+ {
287
+ name: '+not-found',
288
+ params: {
289
+ 'not-found': ['missing-page'],
290
+ },
291
+ path: '/missing-page',
292
+ },
293
+ ],
294
+ })
295
+ })
296
+
297
+ it(`handles query params`, () => {
298
+ expect(
299
+ getStateFromPath('/?test=true&hello=world&array=1&array=2', getMockConfig(['index.tsx']))
300
+ ).toEqual({
301
+ routes: [
302
+ {
303
+ name: 'index',
304
+ params: {
305
+ test: 'true',
306
+ hello: 'world',
307
+ array: ['1', '2'],
308
+ },
309
+ path: '/?test=true&hello=world&array=1&array=2',
310
+ },
311
+ ],
312
+ })
313
+ })
314
+
315
+ it(`handles query params`, () => {
316
+ expect(
317
+ getStateFromPath('/?test=true&hello=world&array=1&array=2', getMockConfig(['index.tsx']))
318
+ ).toEqual({
319
+ routes: [
320
+ {
321
+ name: 'index',
322
+ params: {
323
+ test: 'true',
324
+ hello: 'world',
325
+ array: ['1', '2'],
326
+ },
327
+ path: '/?test=true&hello=world&array=1&array=2',
328
+ },
329
+ ],
330
+ })
331
+ })
332
+
333
+ // TODO
334
+ it.skip(`prioritizes hoisted index routes over dynamic groups`, () => {
335
+ expect(
336
+ getStateFromPath('/(one)', getMockConfig(['(one,two)/index.tsx', '(one,two)/[slug].tsx']))
337
+ ).toEqual({
338
+ routes: [
339
+ {
340
+ name: '(one)/index',
341
+ path: '',
342
+ },
343
+ ],
344
+ })
345
+ })
package/src/render.tsx CHANGED
@@ -14,9 +14,9 @@ export function render(element: React.ReactNode) {
14
14
  globalThis['__vxrnRoot'].render(element)
15
15
  } else {
16
16
  startTransition(() => {
17
- const rootElement = process.env.ONE_FIX_REACT_PORTAL_BUG
18
- ? (document as any)
19
- : document.documentElement
17
+ const rootElement = process.env.ONE_USE_FASTER_DOCUMENT
18
+ ? document.documentElement
19
+ : (document as any)
20
20
 
21
21
  if (globalThis['__vxrnIsSPA']) {
22
22
  const root = createRoot(rootElement)
@@ -0,0 +1,4 @@
1
+ import { createContext } from 'react'
2
+ import type { One } from '../vite/types'
3
+
4
+ export const FlagsContext = createContext<One.Flags>({})
@@ -242,8 +242,20 @@ function getDirectoryTree(contextModule: One.RouteContext, options: Options) {
242
242
  {
243
243
  type: 'layout',
244
244
  loadRoute: () => ({
245
- default: (require('../views/Navigator') as typeof import('../views/Navigator'))
246
- .DefaultNavigator,
245
+ default: (
246
+ (() => {
247
+ try {
248
+ return require('../views/Navigator')
249
+ } catch (e) {
250
+ // This can happen during unit testing with vitest, where we cannot just require TypeScript files. Currently we will not actually render the navigator in tests, so it's fine to mock it this way but still bring awareness of what's happening if it happens in actual runtime.
251
+ return {
252
+ DefaultNavigator: () => {
253
+ throw e
254
+ },
255
+ }
256
+ }
257
+ })() as typeof import('../views/Navigator')
258
+ ).DefaultNavigator,
247
259
  }),
248
260
  // Generate a fake file name for the directory
249
261
  contextKey: 'router/build/views/Navigator.js',
@@ -0,0 +1,120 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import {
3
+ matchDynamicName,
4
+ matchDeepDynamicRouteName,
5
+ getNameFromFilePath,
6
+ matchGroupName,
7
+ stripGroupSegmentsFromPath,
8
+ matchArrayGroupName,
9
+ } from './matchers'
10
+
11
+ describe(stripGroupSegmentsFromPath, () => {
12
+ it(`strips group segments, preserving initial slash`, () => {
13
+ expect(stripGroupSegmentsFromPath('/[[...foobar]]/(foo)/bar/[bax]/(other)')).toBe(
14
+ '/[[...foobar]]/bar/[bax]'
15
+ )
16
+ expect(stripGroupSegmentsFromPath('(foo)/(bar)')).toBe('')
17
+ })
18
+ })
19
+
20
+ describe(matchGroupName, () => {
21
+ it(`matches`, () => {
22
+ expect(matchGroupName('[[...foobar]]')).toEqual(undefined)
23
+ expect(matchGroupName('[[foobar]]')).toEqual(undefined)
24
+ expect(matchGroupName('[...foobar]')).toEqual(undefined)
25
+ expect(matchGroupName('[foobar]')).toEqual(undefined)
26
+ expect(matchGroupName('(foobar)')).toEqual('foobar')
27
+ expect(matchGroupName('(foo,bar)')).toEqual('foo,bar')
28
+ expect(matchGroupName('((foobar))')).toEqual('(foobar)')
29
+ expect(matchGroupName('(...foobar)')).toEqual('...foobar')
30
+ expect(matchGroupName('foobar')).toEqual(undefined)
31
+ expect(matchGroupName('leading/foobar')).toEqual(undefined)
32
+ expect(matchGroupName('leading/(foobar)')).toEqual('foobar')
33
+ expect(matchGroupName('leading/((foobar))')).toEqual('(foobar)')
34
+ expect(matchGroupName('leading/(...foobar)')).toEqual('...foobar')
35
+ expect(matchGroupName('leading/(foo,bar)')).toEqual('foo,bar')
36
+ expect(matchGroupName('leading/foobar/trailing')).toEqual(undefined)
37
+ expect(matchGroupName('leading/(foobar)/trailing')).toEqual('foobar')
38
+ expect(matchGroupName('leading/((foobar))/trailing')).toEqual('(foobar)')
39
+ expect(matchGroupName('leading/(...foobar)/trailing')).toEqual('...foobar')
40
+ expect(matchGroupName('leading/(foo,bar)/trailing)')).toEqual('foo,bar')
41
+ expect(matchGroupName('leading/(foo,bar)/(fruit,apple)')).toEqual('foo,bar')
42
+ })
43
+ })
44
+
45
+ describe(matchDynamicName, () => {
46
+ it(`matches`, () => {
47
+ expect(matchDynamicName('[[...foobar]]')).toEqual(undefined)
48
+ expect(matchDynamicName('[[foobar]]')).toEqual(undefined)
49
+ expect(matchDynamicName('[...foobar]')).toEqual(undefined)
50
+ expect(matchDynamicName('[foobar]')).toEqual('foobar')
51
+ expect(matchDynamicName('foobar')).toEqual(undefined)
52
+ })
53
+ })
54
+
55
+ describe(matchDeepDynamicRouteName, () => {
56
+ it(`matches`, () => {
57
+ expect(matchDeepDynamicRouteName('[[...foobar]]')).toEqual(undefined)
58
+ expect(matchDeepDynamicRouteName('[[foobar]]')).toEqual(undefined)
59
+ expect(matchDeepDynamicRouteName('[...foobar]')).toEqual('foobar')
60
+ expect(matchDeepDynamicRouteName('[foobar]')).toEqual(undefined)
61
+ expect(matchDeepDynamicRouteName('foobar')).toEqual(undefined)
62
+ })
63
+ })
64
+
65
+ describe(getNameFromFilePath, () => {
66
+ it(`should return the name of the file`, () => {
67
+ expect(getNameFromFilePath('./pages/home.tsx')).toBe('pages/home')
68
+ expect(getNameFromFilePath('../pages/home.js')).toBe('pages/home')
69
+ expect(getNameFromFilePath('./(home).jsx')).toBe('(home)')
70
+ expect(getNameFromFilePath('../../../(pages)/[any]/[...home].ts')).toBe(
71
+ '(pages)/[any]/[...home]'
72
+ )
73
+ })
74
+ })
75
+
76
+ describe(matchArrayGroupName, () => {
77
+ it(`should not match routes without groups`, () => {
78
+ expect(matchArrayGroupName('[[...foobar]]')).toEqual(undefined)
79
+ expect(matchArrayGroupName('[[foobar]]')).toEqual(undefined)
80
+ expect(matchArrayGroupName('[...foobar]')).toEqual(undefined)
81
+ expect(matchArrayGroupName('[foobar]')).toEqual(undefined)
82
+ expect(matchArrayGroupName('foobar')).toEqual(undefined)
83
+ expect(matchArrayGroupName('leading/foobar')).toEqual(undefined)
84
+ expect(matchArrayGroupName('leading/foobar/trailing')).toEqual(undefined)
85
+ })
86
+ it(`should not match routes with a single group`, () => {
87
+ expect(matchArrayGroupName('(foobar)')).toEqual(undefined)
88
+ expect(matchArrayGroupName('((foobar))')).toEqual(undefined)
89
+ expect(matchArrayGroupName('(...foobar)')).toEqual(undefined)
90
+ expect(matchArrayGroupName('leading/(foobar)')).toEqual(undefined)
91
+ expect(matchArrayGroupName('leading/((foobar))')).toEqual(undefined)
92
+ expect(matchArrayGroupName('leading/(...foobar)')).toEqual(undefined)
93
+ expect(matchArrayGroupName('leading/(foobar)/trailing')).toEqual(undefined)
94
+ expect(matchArrayGroupName('leading/((foobar))/trailing')).toEqual(undefined)
95
+ expect(matchArrayGroupName('leading/(...foobar)/trailing')).toEqual(undefined)
96
+ expect(matchArrayGroupName('(leading)/foobar')).toEqual(undefined)
97
+ expect(matchArrayGroupName('(leading)/(foobar)')).toEqual(undefined)
98
+ expect(matchArrayGroupName('(leading)/((foobar))')).toEqual(undefined)
99
+ expect(matchArrayGroupName('(leading)/(...foobar)')).toEqual(undefined)
100
+ expect(matchArrayGroupName('(leading)/foobar/trailing')).toEqual(undefined)
101
+ expect(matchArrayGroupName('(leading)/(foobar)/trailing')).toEqual(undefined)
102
+ expect(matchArrayGroupName('(leading)/((foobar))/trailing')).toEqual(undefined)
103
+ expect(matchArrayGroupName('(leading)/(...foobar)/trailing')).toEqual(undefined)
104
+ })
105
+ it.skip(`should match routes with array group syntax`, () => {
106
+ expect(matchArrayGroupName('(foo,bar)')).toEqual('foo,bar')
107
+ expect(matchArrayGroupName('leading/(foo,bar)')).toEqual('foo,bar')
108
+ expect(matchArrayGroupName('leading/(foo,bar)/trailing)')).toEqual('foo,bar')
109
+ expect(matchArrayGroupName('leading/((foo),(bar))/trailing)')).toEqual('(foo),(bar)')
110
+ expect(matchArrayGroupName('leading/(foo,bar)/(fruit,apple)')).toEqual('foo,bar')
111
+ expect(matchArrayGroupName('(leading)/(foo,bar)')).toEqual('foo,bar')
112
+ expect(matchArrayGroupName('(leading)/(foo,bar)/trailing)')).toEqual('foo,bar')
113
+ expect(matchArrayGroupName('(leading)/((foo),(bar))/trailing)')).toEqual('(foo),(bar)')
114
+ })
115
+ it.skip(`should only match the first group with array group syntax`, () => {
116
+ expect(matchArrayGroupName('(leading)/(foo,bar)/(fruit,apple)')).toEqual('foo,bar')
117
+ expect(matchArrayGroupName('(leading)/((foo),bar)/(fruit,apple)')).toEqual('(foo),bar')
118
+ expect(matchArrayGroupName('(leading)/(foo,bar)/((fruit),apple)')).toEqual('foo,bar')
119
+ })
120
+ })