expo-router 5.0.0-sdk-52-router-patches → 5.0.1-preview.0-canary-20250408-7f0ab53

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 (85) hide show
  1. package/_async-server-import.js +11 -7
  2. package/build/Route.d.ts +7 -1
  3. package/build/Route.d.ts.map +1 -1
  4. package/build/Route.js.map +1 -1
  5. package/build/exports.d.ts +1 -0
  6. package/build/exports.d.ts.map +1 -1
  7. package/build/exports.js.map +1 -1
  8. package/build/fork/getStateFromPath-forks.d.ts +3 -2
  9. package/build/fork/getStateFromPath-forks.d.ts.map +1 -1
  10. package/build/fork/getStateFromPath-forks.js +24 -27
  11. package/build/fork/getStateFromPath-forks.js.map +1 -1
  12. package/build/fork/getStateFromPath.js +24 -19
  13. package/build/fork/getStateFromPath.js.map +1 -1
  14. package/build/getLinkingConfig.d.ts +3 -1
  15. package/build/getLinkingConfig.d.ts.map +1 -1
  16. package/build/getLinkingConfig.js +11 -7
  17. package/build/getLinkingConfig.js.map +1 -1
  18. package/build/getReactNavigationConfig.d.ts +1 -0
  19. package/build/getReactNavigationConfig.d.ts.map +1 -1
  20. package/build/getReactNavigationConfig.js +2 -1
  21. package/build/getReactNavigationConfig.js.map +1 -1
  22. package/build/getRoutes.d.ts.map +1 -1
  23. package/build/getRoutes.js +9 -1
  24. package/build/getRoutes.js.map +1 -1
  25. package/build/getRoutesCore.d.ts +16 -1
  26. package/build/getRoutesCore.d.ts.map +1 -1
  27. package/build/getRoutesCore.js +134 -11
  28. package/build/getRoutesCore.js.map +1 -1
  29. package/build/getRoutesRedirects.d.ts +12 -0
  30. package/build/getRoutesRedirects.d.ts.map +1 -0
  31. package/build/getRoutesRedirects.js +71 -0
  32. package/build/getRoutesRedirects.js.map +1 -0
  33. package/build/getRoutesSSR.d.ts.map +1 -1
  34. package/build/getRoutesSSR.js +9 -1
  35. package/build/getRoutesSSR.js.map +1 -1
  36. package/build/getServerManifest.d.ts +13 -1
  37. package/build/getServerManifest.d.ts.map +1 -1
  38. package/build/getServerManifest.js +27 -2
  39. package/build/getServerManifest.js.map +1 -1
  40. package/build/global-state/router-store.d.ts +4 -0
  41. package/build/global-state/router-store.d.ts.map +1 -1
  42. package/build/global-state/router-store.js +44 -2
  43. package/build/global-state/router-store.js.map +1 -1
  44. package/build/global-state/routing.d.ts +1 -1
  45. package/build/global-state/routing.d.ts.map +1 -1
  46. package/build/global-state/routing.js +7 -1
  47. package/build/global-state/routing.js.map +1 -1
  48. package/build/link/linking.d.ts +2 -1
  49. package/build/link/linking.d.ts.map +1 -1
  50. package/build/link/linking.js +14 -8
  51. package/build/link/linking.js.map +1 -1
  52. package/build/matchers.d.ts +3 -1
  53. package/build/matchers.d.ts.map +1 -1
  54. package/build/matchers.js +7 -2
  55. package/build/matchers.js.map +1 -1
  56. package/build/routes-manifest.d.ts +6 -2
  57. package/build/routes-manifest.d.ts.map +1 -1
  58. package/build/routes-manifest.js +1 -0
  59. package/build/routes-manifest.js.map +1 -1
  60. package/build/rsc/middleware.d.ts.map +1 -1
  61. package/build/rsc/middleware.js +6 -1
  62. package/build/rsc/middleware.js.map +1 -1
  63. package/build/rsc/router/create-expo-pages.d.ts +20 -0
  64. package/build/rsc/router/create-expo-pages.d.ts.map +1 -0
  65. package/build/rsc/router/create-expo-pages.js +22 -0
  66. package/build/rsc/router/create-expo-pages.js.map +1 -0
  67. package/build/rsc/router/expo-definedRouter.d.ts +1 -5
  68. package/build/rsc/router/expo-definedRouter.d.ts.map +1 -1
  69. package/build/rsc/router/expo-definedRouter.js +3 -2
  70. package/build/rsc/router/expo-definedRouter.js.map +1 -1
  71. package/build/rsc/router/noopRouter.d.ts +1 -5
  72. package/build/rsc/router/noopRouter.d.ts.map +1 -1
  73. package/build/rsc/router/noopRouter.js +2 -2
  74. package/build/rsc/router/noopRouter.js.map +1 -1
  75. package/build/static/getServerManifest.d.ts.map +1 -1
  76. package/build/static/getServerManifest.js +1 -0
  77. package/build/static/getServerManifest.js.map +1 -1
  78. package/build/useScreens.d.ts +4 -1
  79. package/build/useScreens.d.ts.map +1 -1
  80. package/build/useScreens.js +39 -34
  81. package/build/useScreens.js.map +1 -1
  82. package/build/views/Navigator.d.ts +1 -1
  83. package/build/views/Navigator.d.ts.map +1 -1
  84. package/package.json +13 -14
  85. package/plugin/options.json +33 -0
@@ -29,7 +29,7 @@ function getServerManifest(route) {
29
29
  // An HTML route can be different based on parent segments due to layout routes, therefore multiple
30
30
  // copies should be rendered. However, an API route is always the same regardless of parent segments.
31
31
  let key;
32
- if (route.type === 'api') {
32
+ if (route.type.includes('api')) {
33
33
  key = (0, matchers_1.getContextKey)(route.contextKey).replace(/\/index$/, '') ?? '/';
34
34
  }
35
35
  else {
@@ -42,13 +42,32 @@ function getServerManifest(route) {
42
42
  .sort(([, , a], [, , b]) => (0, sortRoutes_1.sortRoutes)(b, a))
43
43
  .reverse();
44
44
  const apiRoutes = uniqueBy(flat.filter(([, , route]) => route.type === 'api'), ([path]) => path);
45
- const otherRoutes = uniqueBy(flat.filter(([, , route]) => route.type === 'route'), ([path]) => path);
45
+ const otherRoutes = uniqueBy(flat.filter(([, , route]) => route.type === 'route' ||
46
+ (route.type === 'rewrite' && (route.methods === undefined || route.methods.includes('GET')))), ([path]) => path);
47
+ const redirects = uniqueBy(flat.filter(([, , route]) => route.type === 'redirect'), ([path]) => path)
48
+ .map((redirect) => {
49
+ redirect[1] =
50
+ flat.find(([, , route]) => route.contextKey === redirect[2].destinationContextKey)?.[0] ??
51
+ '/';
52
+ return redirect;
53
+ })
54
+ .reverse();
55
+ const rewrites = uniqueBy(flat.filter(([, , route]) => route.type === 'rewrite'), ([path]) => path)
56
+ .map((rewrite) => {
57
+ rewrite[1] =
58
+ flat.find(([, , route]) => route.contextKey === rewrite[2].destinationContextKey)?.[0] ??
59
+ '/';
60
+ return rewrite;
61
+ })
62
+ .reverse();
46
63
  const standardRoutes = otherRoutes.filter(([, , route]) => !isNotFoundRoute(route));
47
64
  const notFoundRoutes = otherRoutes.filter(([, , route]) => isNotFoundRoute(route));
48
65
  return {
49
66
  apiRoutes: getMatchableManifestForPaths(apiRoutes),
50
67
  htmlRoutes: getMatchableManifestForPaths(standardRoutes),
51
68
  notFoundRoutes: getMatchableManifestForPaths(notFoundRoutes),
69
+ redirects: getMatchableManifestForPaths(redirects),
70
+ rewrites: getMatchableManifestForPaths(rewrites),
52
71
  };
53
72
  }
54
73
  exports.getServerManifest = getServerManifest;
@@ -58,6 +77,12 @@ function getMatchableManifestForPaths(paths) {
58
77
  if (node.generated) {
59
78
  matcher.generated = true;
60
79
  }
80
+ if (node.permanent) {
81
+ matcher.permanent = true;
82
+ }
83
+ if (node.methods) {
84
+ matcher.methods = node.methods;
85
+ }
61
86
  return matcher;
62
87
  });
63
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getServerManifest.js","sourceRoot":"","sources":["../src/getServerManifest.ts"],"names":[],"mappings":";;;AAUA,yCAA2D;AAC3D,6CAA0C;AA6C1C,SAAS,eAAe,CAAC,KAAgB;IACvC,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3E,CAAC;AAED,SAAS,QAAQ,CAAI,GAAQ,EAAE,GAAwB;IACrD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAChB,OAAO,KAAK,CAAC;SACd;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yFAAyF;AACzF,SAAgB,iBAAiB,CAAC,KAAgB;IAChD,SAAS,YAAY,CAAC,KAAgB,EAAE,cAAsB,EAAE;QAC9D,kGAAkG;QAClG,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE3E,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE;YACzB,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACjF;QAED,0FAA0F;QAC1F,mGAAmG;QACnG,qGAAqG;QACrG,IAAI,GAAW,CAAC;QAChB,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE;YACxB,GAAG,GAAG,IAAA,wBAAa,EAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;SACtE;aAAM;YACL,GAAG,GAAG,IAAA,wBAAa,EAAC,aAAa,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;SACnE;QACD,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,0EAA0E;IAC1E,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC;SAC7B,IAAI,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,CAAC,CAAC,EAAE,CAAC,EAAE,AAAD,EAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,uBAAU,EAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SAC5C,OAAO,EAAE,CAAC;IAEb,MAAM,SAAS,GAAG,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,EAClD,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CACjB,CAAC;IACF,MAAM,WAAW,GAAG,QAAQ,CAC1B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,EACpD,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CACjB,CAAC;IACF,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IACpF,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,KAAK,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAEnF,OAAO;QACL,SAAS,EAAE,4BAA4B,CAAC,SAAS,CAAC;QAClD,UAAU,EAAE,4BAA4B,CAAC,cAAc,CAAC;QACxD,cAAc,EAAE,4BAA4B,CAAC,cAAc,CAAC;KAC7D,CAAC;AACJ,CAAC;AA1CD,8CA0CC;AAED,SAAS,4BAA4B,CACnC,KAAoC;IAEpC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9D,MAAM,OAAO,GAAoC,kBAAkB,CACjE,mBAAmB,EACnB,aAAa,EACb,IAAI,CAAC,UAAU,CAChB,CAAC;QACF,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;SAC1B;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CACzB,eAAuB,EACvB,IAAY,EACZ,IAAY;IAEZ,MAAM,MAAM,GAAG,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAC1D,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,UAAU,EAAE,IAAI,MAAM,CAAC,uBAAuB,SAAS;QACvD,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB;IAC3B,IAAI,eAAe,GAAG,EAAE,CAAC,CAAC,8DAA8D;IACxF,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,OAAO,GAAG,EAAE;QACV,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,aAAa,GAAG,IAAI,CAAC;QAEzB,8CAA8C;QAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE;YACtC,IAAI,aAAa,EAAE;gBACjB,eAAe,EAAE,CAAC;gBAClB,IAAI,eAAe,GAAG,GAAG,EAAE;oBACzB,eAAe,GAAG,EAAE,CAAC,CAAC,eAAe;oBACrC,aAAa,GAAG,IAAI,CAAC,CAAC,2CAA2C;iBAClE;qBAAM;oBACL,aAAa,GAAG,KAAK,CAAC;iBACvB;aACF;YACD,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC;SACxD;QAED,4DAA4D;QAC5D,IAAI,aAAa,EAAE;YACjB,aAAa,EAAE,CAAC;YAChB,eAAe,GAAG,EAAE,CAAC,CAAC,6CAA6C;SACpE;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;AACzC,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAa;IAC9C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChE,MAAM,eAAe,GAAG,oBAAoB,EAAE,CAAC;IAC/C,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,OAAO;QACL,uBAAuB,EAAE,QAAQ;aAC9B,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YACtB,IAAI,OAAO,KAAK,YAAY,IAAI,KAAK,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC7D,OAAO,GAAG,gBAAgB,CAAC;aAC5B;YACD,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBAC5B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;gBAC3D,uDAAuD;gBACvD,kBAAkB;gBAClB,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACzC,IAAI,UAAU,GAAG,KAAK,CAAC;gBAEvB,kEAAkE;gBAClE,WAAW;gBACX,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,EAAE,EAAE;oBACrD,UAAU,GAAG,IAAI,CAAC;iBACnB;gBACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;oBAChD,UAAU,GAAG,IAAI,CAAC;iBACnB;gBAED,8CAA8C;gBAC9C,IAAI,UAAU,IAAI,SAAS,EAAE;oBAC3B,UAAU,GAAG,IAAI,CAAC;iBACnB;gBAED,IAAI,UAAU,EAAE;oBACd,UAAU,GAAG,eAAe,EAAE,CAAC;iBAChC;gBAED,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;gBAC7B,OAAO,MAAM;oBACX,CAAC,CAAC,QAAQ;wBACR,CAAC,CAAC,UAAU,UAAU,SAAS;wBAC/B,CAAC,CAAC,OAAO,UAAU,OAAO;oBAC5B,CAAC,CAAC,OAAO,UAAU,UAAU,CAAC;aACjC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBACnC,MAAM,SAAS,GAAG,IAAA,yBAAc,EAAC,OAAO,CAAE;qBACvC,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;qBAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;gBACnB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;oBACxB,MAAM,eAAe,GAAG,SAAS,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;oBACnF,wBAAwB;oBACxB,OAAO,OAAO,eAAe,IAAI,CAAC;iBACnC;qBAAM;oBACL,sCAAsC;oBACtC,OAAO,OAAO,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC;iBAC/C;aACF;iBAAM;gBACL,OAAO,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;aAC1C;QACH,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC;QACX,SAAS;KACV,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAC1C,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAE/C,SAAS,kBAAkB,CAAC,GAAW;IACrC,+GAA+G;IAC/G,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACzB,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;KAC7C;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,cAAc,CAAC,KAAa;IAC1C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACzB,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;KAC1B;IAED,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACxB,MAAM,GAAG,IAAI,CAAC;QACd,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACtB;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AACpC,CAAC;AAhBD,wCAgBC","sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n * Copyright © 2023 Vercel, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on https://github.com/vercel/next.js/blob/1df2686bc9964f1a86c444701fa5cbf178669833/packages/next/src/shared/lib/router/utils/route-regex.ts\n */\nimport type { RouteNode } from './Route';\nimport { getContextKey, matchGroupName } from './matchers';\nimport { sortRoutes } from './sortRoutes';\n\n// TODO: Share these types across cli, server, router, etc.\nexport type ExpoRouterServerManifestV1Route<TRegex = string> = {\n file: string;\n page: string;\n /**\n * Keys are route param names that have been normalized for a regex named-matcher, values are the original route param names.\n */\n routeKeys: Record<string, string>;\n /**\n * Regex for matching a path against the route.\n * The regex is normalized for named matchers so keys must be looked up against the `routeKeys` object to collect the original route param names.\n * Regex matching alone cannot accurately route to a file, the order in which routes are matched is equally important to ensure correct priority.\n */\n namedRegex: TRegex;\n /** Indicates that the route was generated and does not map to any file in the project's routes directory. */\n generated?: boolean;\n};\n\nexport type ExpoRouterServerManifestV1<TRegex = string> = {\n /**\n * Routes that are matched first and return static HTML files for a given path.\n * These are only matched against requests with method `GET` and `HEAD`.\n */\n htmlRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n /**\n * Routes that are matched after HTML routes and invoke WinterCG-compliant functions.\n */\n apiRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n /** List of routes that are matched last and return with status code 404. */\n notFoundRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n};\n\nexport interface Group {\n pos: number;\n repeat: boolean;\n optional: boolean;\n}\n\nexport interface RouteRegex {\n groups: Record<string, Group>;\n re: RegExp;\n}\n\nfunction isNotFoundRoute(route: RouteNode) {\n return route.dynamic && route.dynamic[route.dynamic.length - 1].notFound;\n}\n\nfunction uniqueBy<T>(arr: T[], key: (item: T) => string): T[] {\n const seen = new Set<string>();\n return arr.filter((item) => {\n const id = key(item);\n if (seen.has(id)) {\n return false;\n }\n seen.add(id);\n return true;\n });\n}\n\n// Given a nested route tree, return a flattened array of all routes that can be matched.\nexport function getServerManifest(route: RouteNode): ExpoRouterServerManifestV1 {\n function getFlatNodes(route: RouteNode, parentRoute: string = ''): [string, string, RouteNode][] {\n // Use a recreated route instead of contextKey because we duplicate nodes to support array syntax.\n const absoluteRoute = [parentRoute, route.route].filter(Boolean).join('/');\n\n if (route.children.length) {\n return route.children.map((child) => getFlatNodes(child, absoluteRoute)).flat();\n }\n\n // API Routes are handled differently to HTML routes because they have no nested behavior.\n // An HTML route can be different based on parent segments due to layout routes, therefore multiple\n // copies should be rendered. However, an API route is always the same regardless of parent segments.\n let key: string;\n if (route.type === 'api') {\n key = getContextKey(route.contextKey).replace(/\\/index$/, '') ?? '/';\n } else {\n key = getContextKey(absoluteRoute).replace(/\\/index$/, '') ?? '/';\n }\n return [[key, '/' + absoluteRoute, route]];\n }\n\n // Remove duplicates from the runtime manifest which expands array syntax.\n const flat = getFlatNodes(route)\n .sort(([, , a], [, , b]) => sortRoutes(b, a))\n .reverse();\n\n const apiRoutes = uniqueBy(\n flat.filter(([, , route]) => route.type === 'api'),\n ([path]) => path\n );\n const otherRoutes = uniqueBy(\n flat.filter(([, , route]) => route.type === 'route'),\n ([path]) => path\n );\n const standardRoutes = otherRoutes.filter(([, , route]) => !isNotFoundRoute(route));\n const notFoundRoutes = otherRoutes.filter(([, , route]) => isNotFoundRoute(route));\n\n return {\n apiRoutes: getMatchableManifestForPaths(apiRoutes),\n htmlRoutes: getMatchableManifestForPaths(standardRoutes),\n notFoundRoutes: getMatchableManifestForPaths(notFoundRoutes),\n };\n}\n\nfunction getMatchableManifestForPaths(\n paths: [string, string, RouteNode][]\n): ExpoRouterServerManifestV1Route[] {\n return paths.map(([normalizedRoutePath, absoluteRoute, node]) => {\n const matcher: ExpoRouterServerManifestV1Route = getNamedRouteRegex(\n normalizedRoutePath,\n absoluteRoute,\n node.contextKey\n );\n if (node.generated) {\n matcher.generated = true;\n }\n return matcher;\n });\n}\n\nfunction getNamedRouteRegex(\n normalizedRoute: string,\n page: string,\n file: string\n): ExpoRouterServerManifestV1Route {\n const result = getNamedParametrizedRoute(normalizedRoute);\n return {\n file,\n page,\n namedRegex: `^${result.namedParameterizedRoute}(?:/)?$`,\n routeKeys: result.routeKeys,\n };\n}\n\n/**\n * Builds a function to generate a minimal routeKey using only a-z and minimal\n * number of characters.\n */\nfunction buildGetSafeRouteKey() {\n let currentCharCode = 96; // Starting one before 'a' to make the increment logic simpler\n let currentLength = 1;\n\n return () => {\n let result = '';\n let incrementNext = true;\n\n // Iterate from right to left to build the key\n for (let i = 0; i < currentLength; i++) {\n if (incrementNext) {\n currentCharCode++;\n if (currentCharCode > 122) {\n currentCharCode = 97; // Reset to 'a'\n incrementNext = true; // Continue to increment the next character\n } else {\n incrementNext = false;\n }\n }\n result = String.fromCharCode(currentCharCode) + result;\n }\n\n // If all characters are 'z', increase the length of the key\n if (incrementNext) {\n currentLength++;\n currentCharCode = 96; // This will make the next key start with 'a'\n }\n\n return result;\n };\n}\n\nfunction removeTrailingSlash(route: string): string {\n return route.replace(/\\/$/, '') || '/';\n}\n\nfunction getNamedParametrizedRoute(route: string) {\n const segments = removeTrailingSlash(route).slice(1).split('/');\n const getSafeRouteKey = buildGetSafeRouteKey();\n const routeKeys: Record<string, string> = {};\n return {\n namedParameterizedRoute: segments\n .map((segment, index) => {\n if (segment === '+not-found' && index === segments.length - 1) {\n segment = '[...not-found]';\n }\n if (/^\\[.*\\]$/.test(segment)) {\n const { name, optional, repeat } = parseParameter(segment);\n // replace any non-word characters since they can break\n // the named regex\n let cleanedKey = name.replace(/\\W/g, '');\n let invalidKey = false;\n\n // check if the key is still invalid and fallback to using a known\n // safe key\n if (cleanedKey.length === 0 || cleanedKey.length > 30) {\n invalidKey = true;\n }\n if (!isNaN(parseInt(cleanedKey.slice(0, 1), 10))) {\n invalidKey = true;\n }\n\n // Prevent duplicates after sanitizing the key\n if (cleanedKey in routeKeys) {\n invalidKey = true;\n }\n\n if (invalidKey) {\n cleanedKey = getSafeRouteKey();\n }\n\n routeKeys[cleanedKey] = name;\n return repeat\n ? optional\n ? `(?:/(?<${cleanedKey}>.+?))?`\n : `/(?<${cleanedKey}>.+?)`\n : `/(?<${cleanedKey}>[^/]+?)`;\n } else if (/^\\(.*\\)$/.test(segment)) {\n const groupName = matchGroupName(segment)!\n .split(',')\n .map((group) => group.trim())\n .filter(Boolean);\n if (groupName.length > 1) {\n const optionalSegment = `\\\\((?:${groupName.map(escapeStringRegexp).join('|')})\\\\)`;\n // Make section optional\n return `(?:/${optionalSegment})?`;\n } else {\n // Use simpler regex for single groups\n return `(?:/${escapeStringRegexp(segment)})?`;\n }\n } else {\n return `/${escapeStringRegexp(segment)}`;\n }\n })\n .join(''),\n routeKeys,\n };\n}\n\n// regexp is based on https://github.com/sindresorhus/escape-string-regexp\nconst reHasRegExp = /[|\\\\{}()[\\]^$+*?.-]/;\nconst reReplaceRegExp = /[|\\\\{}()[\\]^$+*?.-]/g;\n\nfunction escapeStringRegexp(str: string) {\n // see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23\n if (reHasRegExp.test(str)) {\n return str.replace(reReplaceRegExp, '\\\\$&');\n }\n return str;\n}\n\nexport function parseParameter(param: string) {\n let repeat = false;\n let optional = false;\n let name = param;\n\n if (/^\\[.*\\]$/.test(name)) {\n optional = true;\n name = name.slice(1, -1);\n }\n\n if (/^\\.\\.\\./.test(name)) {\n repeat = true;\n name = name.slice(3);\n }\n\n return { name, repeat, optional };\n}\n"]}
1
+ {"version":3,"file":"getServerManifest.js","sourceRoot":"","sources":["../src/getServerManifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n * Copyright © 2023 Vercel, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on https://github.com/vercel/next.js/blob/1df2686bc9964f1a86c444701fa5cbf178669833/packages/next/src/shared/lib/router/utils/route-regex.ts\n */\nimport type { RouteNode } from './Route';\nimport { getContextKey, matchGroupName } from './matchers';\nimport { sortRoutes } from './sortRoutes';\n\n// TODO: Share these types across cli, server, router, etc.\nexport type ExpoRouterServerManifestV1Route<TRegex = string> = {\n file: string;\n page: string;\n /**\n * Keys are route param names that have been normalized for a regex named-matcher, values are the original route param names.\n */\n routeKeys: Record<string, string>;\n /**\n * Regex for matching a path against the route.\n * The regex is normalized for named matchers so keys must be looked up against the `routeKeys` object to collect the original route param names.\n * Regex matching alone cannot accurately route to a file, the order in which routes are matched is equally important to ensure correct priority.\n */\n namedRegex: TRegex;\n /** Indicates that the route was generated and does not map to any file in the project's routes directory. */\n generated?: boolean;\n /** Indicates that this is a redirect that should use 301 instead of 307 */\n permanent?: boolean;\n /** If a redirect, which methods are allowed. Undefined represents all methods */\n methods?: string[];\n};\n\nexport type ExpoRouterServerManifestV1<TRegex = string> = {\n /**\n * Rewrites. These occur first\n */\n rewrites: ExpoRouterServerManifestV1Route<TRegex>[];\n /**\n * List of routes that match second. Returns 301 and redirects to another path.\n */\n redirects: ExpoRouterServerManifestV1Route<TRegex>[];\n /**\n * Routes that return static HTML files for a given path.\n * These are only matched against requests with method `GET` and `HEAD`.\n */\n htmlRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n /**\n * Routes that are matched after HTML routes and invoke WinterCG-compliant functions.\n */\n apiRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n /** List of routes that are matched last and return with status code 404. */\n notFoundRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n};\n\nexport interface Group {\n pos: number;\n repeat: boolean;\n optional: boolean;\n}\n\nexport interface RouteRegex {\n groups: Record<string, Group>;\n re: RegExp;\n}\n\nfunction isNotFoundRoute(route: RouteNode) {\n return route.dynamic && route.dynamic[route.dynamic.length - 1].notFound;\n}\n\nfunction uniqueBy<T>(arr: T[], key: (item: T) => string): T[] {\n const seen = new Set<string>();\n return arr.filter((item) => {\n const id = key(item);\n if (seen.has(id)) {\n return false;\n }\n seen.add(id);\n return true;\n });\n}\n\n// Given a nested route tree, return a flattened array of all routes that can be matched.\nexport function getServerManifest(route: RouteNode): ExpoRouterServerManifestV1 {\n function getFlatNodes(route: RouteNode, parentRoute: string = ''): [string, string, RouteNode][] {\n // Use a recreated route instead of contextKey because we duplicate nodes to support array syntax.\n const absoluteRoute = [parentRoute, route.route].filter(Boolean).join('/');\n\n if (route.children.length) {\n return route.children.map((child) => getFlatNodes(child, absoluteRoute)).flat();\n }\n\n // API Routes are handled differently to HTML routes because they have no nested behavior.\n // An HTML route can be different based on parent segments due to layout routes, therefore multiple\n // copies should be rendered. However, an API route is always the same regardless of parent segments.\n let key: string;\n if (route.type.includes('api')) {\n key = getContextKey(route.contextKey).replace(/\\/index$/, '') ?? '/';\n } else {\n key = getContextKey(absoluteRoute).replace(/\\/index$/, '') ?? '/';\n }\n return [[key, '/' + absoluteRoute, route]];\n }\n\n // Remove duplicates from the runtime manifest which expands array syntax.\n const flat = getFlatNodes(route)\n .sort(([, , a], [, , b]) => sortRoutes(b, a))\n .reverse();\n\n const apiRoutes = uniqueBy(\n flat.filter(([, , route]) => route.type === 'api'),\n ([path]) => path\n );\n\n const otherRoutes = uniqueBy(\n flat.filter(\n ([, , route]) =>\n route.type === 'route' ||\n (route.type === 'rewrite' && (route.methods === undefined || route.methods.includes('GET')))\n ),\n ([path]) => path\n );\n\n const redirects = uniqueBy(\n flat.filter(([, , route]) => route.type === 'redirect'),\n ([path]) => path\n )\n .map((redirect) => {\n redirect[1] =\n flat.find(([, , route]) => route.contextKey === redirect[2].destinationContextKey)?.[0] ??\n '/';\n\n return redirect;\n })\n .reverse();\n\n const rewrites = uniqueBy(\n flat.filter(([, , route]) => route.type === 'rewrite'),\n ([path]) => path\n )\n .map((rewrite) => {\n rewrite[1] =\n flat.find(([, , route]) => route.contextKey === rewrite[2].destinationContextKey)?.[0] ??\n '/';\n\n return rewrite;\n })\n .reverse();\n\n const standardRoutes = otherRoutes.filter(([, , route]) => !isNotFoundRoute(route));\n const notFoundRoutes = otherRoutes.filter(([, , route]) => isNotFoundRoute(route));\n\n return {\n apiRoutes: getMatchableManifestForPaths(apiRoutes),\n htmlRoutes: getMatchableManifestForPaths(standardRoutes),\n notFoundRoutes: getMatchableManifestForPaths(notFoundRoutes),\n redirects: getMatchableManifestForPaths(redirects),\n rewrites: getMatchableManifestForPaths(rewrites),\n };\n}\n\nfunction getMatchableManifestForPaths(\n paths: [string, string, RouteNode][]\n): ExpoRouterServerManifestV1Route[] {\n return paths.map(([normalizedRoutePath, absoluteRoute, node]) => {\n const matcher: ExpoRouterServerManifestV1Route = getNamedRouteRegex(\n normalizedRoutePath,\n absoluteRoute,\n node.contextKey\n );\n if (node.generated) {\n matcher.generated = true;\n }\n\n if (node.permanent) {\n matcher.permanent = true;\n }\n\n if (node.methods) {\n matcher.methods = node.methods;\n }\n\n return matcher;\n });\n}\n\nfunction getNamedRouteRegex(\n normalizedRoute: string,\n page: string,\n file: string\n): ExpoRouterServerManifestV1Route {\n const result = getNamedParametrizedRoute(normalizedRoute);\n return {\n file,\n page,\n namedRegex: `^${result.namedParameterizedRoute}(?:/)?$`,\n routeKeys: result.routeKeys,\n };\n}\n\n/**\n * Builds a function to generate a minimal routeKey using only a-z and minimal\n * number of characters.\n */\nfunction buildGetSafeRouteKey() {\n let currentCharCode = 96; // Starting one before 'a' to make the increment logic simpler\n let currentLength = 1;\n\n return () => {\n let result = '';\n let incrementNext = true;\n\n // Iterate from right to left to build the key\n for (let i = 0; i < currentLength; i++) {\n if (incrementNext) {\n currentCharCode++;\n if (currentCharCode > 122) {\n currentCharCode = 97; // Reset to 'a'\n incrementNext = true; // Continue to increment the next character\n } else {\n incrementNext = false;\n }\n }\n result = String.fromCharCode(currentCharCode) + result;\n }\n\n // If all characters are 'z', increase the length of the key\n if (incrementNext) {\n currentLength++;\n currentCharCode = 96; // This will make the next key start with 'a'\n }\n\n return result;\n };\n}\n\nfunction removeTrailingSlash(route: string): string {\n return route.replace(/\\/$/, '') || '/';\n}\n\nfunction getNamedParametrizedRoute(route: string) {\n const segments = removeTrailingSlash(route).slice(1).split('/');\n const getSafeRouteKey = buildGetSafeRouteKey();\n const routeKeys: Record<string, string> = {};\n return {\n namedParameterizedRoute: segments\n .map((segment, index) => {\n if (segment === '+not-found' && index === segments.length - 1) {\n segment = '[...not-found]';\n }\n if (/^\\[.*\\]$/.test(segment)) {\n const { name, optional, repeat } = parseParameter(segment);\n // replace any non-word characters since they can break\n // the named regex\n let cleanedKey = name.replace(/\\W/g, '');\n let invalidKey = false;\n\n // check if the key is still invalid and fallback to using a known\n // safe key\n if (cleanedKey.length === 0 || cleanedKey.length > 30) {\n invalidKey = true;\n }\n if (!isNaN(parseInt(cleanedKey.slice(0, 1), 10))) {\n invalidKey = true;\n }\n\n // Prevent duplicates after sanitizing the key\n if (cleanedKey in routeKeys) {\n invalidKey = true;\n }\n\n if (invalidKey) {\n cleanedKey = getSafeRouteKey();\n }\n\n routeKeys[cleanedKey] = name;\n return repeat\n ? optional\n ? `(?:/(?<${cleanedKey}>.+?))?`\n : `/(?<${cleanedKey}>.+?)`\n : `/(?<${cleanedKey}>[^/]+?)`;\n } else if (/^\\(.*\\)$/.test(segment)) {\n const groupName = matchGroupName(segment)!\n .split(',')\n .map((group) => group.trim())\n .filter(Boolean);\n if (groupName.length > 1) {\n const optionalSegment = `\\\\((?:${groupName.map(escapeStringRegexp).join('|')})\\\\)`;\n // Make section optional\n return `(?:/${optionalSegment})?`;\n } else {\n // Use simpler regex for single groups\n return `(?:/${escapeStringRegexp(segment)})?`;\n }\n } else {\n return `/${escapeStringRegexp(segment)}`;\n }\n })\n .join(''),\n routeKeys,\n };\n}\n\n// regexp is based on https://github.com/sindresorhus/escape-string-regexp\nconst reHasRegExp = /[|\\\\{}()[\\]^$+*?.-]/;\nconst reReplaceRegExp = /[|\\\\{}()[\\]^$+*?.-]/g;\n\nfunction escapeStringRegexp(str: string) {\n // see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23\n if (reHasRegExp.test(str)) {\n return str.replace(reReplaceRegExp, '\\\\$&');\n }\n return str;\n}\n\nexport function parseParameter(param: string) {\n let repeat = false;\n let optional = false;\n let name = param;\n\n if (/^\\[.*\\]$/.test(name)) {\n optional = true;\n name = name.slice(1, -1);\n }\n\n if (/^\\.\\.\\./.test(name)) {\n repeat = true;\n name = name.slice(3);\n }\n\n return { name, repeat, optional };\n}\n"]}
@@ -4,6 +4,7 @@ import { LinkToOptions } from './routing';
4
4
  import { UrlObject } from '../LocationProvider';
5
5
  import { RouteNode } from '../Route';
6
6
  import { ExpoLinkingOptions, LinkingConfigOptions } from '../getLinkingConfig';
7
+ import { RedirectConfig } from '../getRoutesCore';
7
8
  import { Href, RequireContext } from '../types';
8
9
  type ResultState = any;
9
10
  /**
@@ -21,6 +22,8 @@ export declare class RouterStore {
21
22
  nextState?: ResultState;
22
23
  routeInfo?: UrlObject;
23
24
  splashScreenAnimationFrame?: number;
25
+ config: any;
26
+ redirects?: (readonly [RegExp, RedirectConfig, boolean])[];
24
27
  navigationRef: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;
25
28
  navigationRefSubscription: () => void;
26
29
  rootStateSubscribers: Set<() => void>;
@@ -74,6 +77,7 @@ export declare class RouterStore {
74
77
  routes: import("@react-navigation/native").PartialRoute<import("@react-navigation/native").Route<string, object | undefined>>[];
75
78
  }> & any) | undefined;
76
79
  }) | undefined;
80
+ applyRedirects<T extends string | null | undefined>(url: T): T | undefined;
77
81
  }
78
82
  export declare const store: RouterStore;
79
83
  export declare function useExpoRouter(): RouterStore;
@@ -1 +1 @@
1
- {"version":3,"file":"router-store.d.ts","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,iCAAiC,EAElC,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAiC,aAAa,EAAY,MAAM,OAAO,CAAC;AAG/E,OAAO,EAaL,aAAa,EACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAoB,MAAM,qBAAqB,CAAC;AAGjG,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAIhD,KAAK,WAAW,GAAG,GAAG,CAAC;AAEvB;;;;GAIG;AACH,qBAAa,WAAW;IACtB,SAAS,EAAG,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAG,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,OAAO,CAAC,wBAAwB,CAAkB;IAElD,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAEpC,aAAa,EAAG,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACjF,yBAAyB,EAAG,MAAM,IAAI,CAAC;IAEvC,oBAAoB,YAAiB,IAAI,EAAI;IAC7C,gBAAgB,YAAiB,IAAI,EAAI;IAEzC,MAAM,MAAqB;IAC3B,eAAe,MAA8B;IAC7C,MAAM,MAAqB;IAC3B,SAAS,MAAwB;IACjC,IAAI,MAAmB;IACvB,OAAO,MAAsB;IAC7B,SAAS,MAAwB;IACjC,OAAO,MAAsB;IAC7B,UAAU,MAAyB;IACnC,UAAU,MAAyB;IACnC,SAAS,MAAwB;IACjC,QAAQ,MAAuB;IAC/B,MAAM,MAAqB;IAE3B,UAAU,CACR,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,EAC/E,oBAAoB,GAAE,oBAAyB;IAqGjD,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,MAAQ;IAWjD,YAAY,CAAC,KAAK,EAAE,WAAW;IAiB/B,kBAAkB;IAIlB,uEAAuE;IACvE,oBAAoB,eAAgB,MAAM,IAAI,mBAG5C;IACF,gBAAgB,eAAgB,MAAM,IAAI,mBAGxC;IACF,QAAQ,aAEN;IACF,iBAAiB,YAEf;IACF,iBAAiB,kBAEf;IAEF,OAAO;IAMP,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB;;;;;;;;;;;;;;;;;;;;;;;;;CAKzD;AAED,eAAO,MAAM,KAAK,aAAoB,CAAC;AAEvC,wBAAgB,aAAa,gBAE5B;AAYD,wBAAgB,iBAAiB,QAOhC;AAED,wBAAgB,iBAAiB,cAOhC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,eAK7F"}
1
+ {"version":3,"file":"router-store.d.ts","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,iCAAiC,EAElC,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAiC,aAAa,EAAY,MAAM,OAAO,CAAC;AAG/E,OAAO,EAaL,aAAa,EACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAoB,MAAM,qBAAqB,CAAC;AAGjG,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAKhD,KAAK,WAAW,GAAG,GAAG,CAAC;AAEvB;;;;GAIG;AACH,qBAAa,WAAW;IACtB,SAAS,EAAG,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAG,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,OAAO,CAAC,wBAAwB,CAAkB;IAElD,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAGpC,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IAE3D,aAAa,EAAG,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACjF,yBAAyB,EAAG,MAAM,IAAI,CAAC;IAEvC,oBAAoB,YAAiB,IAAI,EAAI;IAC7C,gBAAgB,YAAiB,IAAI,EAAI;IAEzC,MAAM,MAAqB;IAC3B,eAAe,MAA8B;IAC7C,MAAM,MAAqB;IAC3B,SAAS,MAAwB;IACjC,IAAI,MAAmB;IACvB,OAAO,MAAsB;IAC7B,SAAS,MAAwB;IACjC,OAAO,MAAsB;IAC7B,UAAU,MAAyB;IACnC,UAAU,MAAyB;IACnC,SAAS,MAAwB;IACjC,QAAQ,MAAuB;IAC/B,MAAM,MAAqB;IAE3B,UAAU,CACR,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,EAC/E,oBAAoB,GAAE,oBAAyB;IAoHjD,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,MAAQ;IAWjD,YAAY,CAAC,KAAK,EAAE,WAAW;IAiB/B,kBAAkB;IAIlB,uEAAuE;IACvE,oBAAoB,eAAgB,MAAM,IAAI,mBAG5C;IACF,gBAAgB,eAAgB,MAAM,IAAI,mBAGxC;IACF,QAAQ,aAEN;IACF,iBAAiB,YAEf;IACF,iBAAiB,kBAEf;IAEF,OAAO;IAMP,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB;;;;;;;;;;;;;;;;;;;;;;;;;IAMxD,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;CAyB3E;AAED,eAAO,MAAM,KAAK,aAAoB,CAAC;AAEvC,wBAAgB,aAAa,gBAE5B;AAYD,wBAAgB,iBAAiB,QAOhC;AAED,wBAAgB,iBAAiB,cAOhC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,eAK7F"}
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.useInitializeExpoRouter = exports.useStoreRouteInfo = exports.useStoreRootState = exports.useExpoRouter = exports.store = exports.RouterStore = void 0;
31
31
  const native_1 = require("@react-navigation/native");
32
32
  const expo_constants_1 = __importDefault(require("expo-constants"));
33
+ const Linking = __importStar(require("expo-linking"));
33
34
  const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
34
35
  const react_1 = require("react");
35
36
  const react_native_1 = require("react-native");
@@ -37,11 +38,14 @@ const routing_1 = require("./routing");
37
38
  const sort_routes_1 = require("./sort-routes");
38
39
  const LocationProvider_1 = require("../LocationProvider");
39
40
  const getPathFromState_1 = require("../fork/getPathFromState");
40
- // import { ResultState } from '../fork/getStateFromPath';
41
+ const getStateFromPath_forks_1 = require("../fork/getStateFromPath-forks");
41
42
  const getLinkingConfig_1 = require("../getLinkingConfig");
43
+ const getReactNavigationConfig_1 = require("../getReactNavigationConfig");
42
44
  const getRoutes_1 = require("../getRoutes");
45
+ const getRoutesRedirects_1 = require("../getRoutesRedirects");
43
46
  const href_1 = require("../link/href");
44
47
  const useScreens_1 = require("../useScreens");
48
+ const url_1 = require("../utils/url");
45
49
  const SplashScreen = __importStar(require("../views/Splash"));
46
50
  /**
47
51
  * This is the global state for the router. It is used to keep track of the current route, and to provide a way to navigate to other routes.
@@ -58,6 +62,9 @@ class RouterStore {
58
62
  nextState;
59
63
  routeInfo;
60
64
  splashScreenAnimationFrame;
65
+ // The expo-router config plugin
66
+ config;
67
+ redirects;
61
68
  navigationRef;
62
69
  navigationRefSubscription;
63
70
  rootStateSubscribers = new Set();
@@ -84,6 +91,18 @@ class RouterStore {
84
91
  this.navigationRefSubscription?.();
85
92
  this.rootStateSubscribers.clear();
86
93
  this.storeSubscribers.clear();
94
+ this.config = expo_constants_1.default.expoConfig?.extra?.router;
95
+ // On the client, there is no difference between redirects and rewrites
96
+ this.redirects = [this.config?.redirects, this.config?.rewrites]
97
+ .filter(Boolean)
98
+ .flat()
99
+ .map((route) => {
100
+ return [
101
+ (0, getStateFromPath_forks_1.routePatternToRegex)((0, getReactNavigationConfig_1.parseRouteSegments)(route.source)),
102
+ route,
103
+ (0, url_1.shouldLinkExternally)(route.destination),
104
+ ];
105
+ });
87
106
  this.routeNode = (0, getRoutes_1.getRoutes)(context, {
88
107
  ...expo_constants_1.default.expoConfig?.extra?.router,
89
108
  ignoreEntryPoints: true,
@@ -101,7 +120,10 @@ class RouterStore {
101
120
  };
102
121
  if (this.routeNode) {
103
122
  // We have routes, so get the linking config and the root component
104
- this.linking = (0, getLinkingConfig_1.getLinkingConfig)(this, this.routeNode, context, linkingConfigOptions);
123
+ this.linking = (0, getLinkingConfig_1.getLinkingConfig)(this, this.routeNode, context, {
124
+ ...expo_constants_1.default.expoConfig?.extra?.router,
125
+ ...linkingConfigOptions,
126
+ });
105
127
  this.rootComponent = (0, useScreens_1.getQualifiedRouteComponent)(this.routeNode);
106
128
  // By default React Navigation is async and does not render anything in the first pass as it waits for `getInitialURL`
107
129
  // This will cause static rendering to fail, which once performs a single pass.
@@ -215,6 +237,26 @@ class RouterStore {
215
237
  href = (0, href_1.resolveHrefStringWithSegments)(href, this.routeInfo, options);
216
238
  return this.linking?.getStateFromPath?.(href, this.linking.config);
217
239
  }
240
+ applyRedirects(url) {
241
+ if (typeof url !== 'string') {
242
+ return url;
243
+ }
244
+ const nextUrl = (0, getStateFromPath_forks_1.cleanPath)(url);
245
+ const redirect = this.redirects?.find(([regex]) => regex.test(nextUrl));
246
+ if (!redirect) {
247
+ return url;
248
+ }
249
+ // If the redirect is external, open the URL
250
+ if (redirect[2]) {
251
+ let href = redirect[1].destination;
252
+ if (href.startsWith('//') && react_native_1.Platform.OS !== 'web') {
253
+ href = `https:${href}`;
254
+ }
255
+ Linking.openURL(href);
256
+ return;
257
+ }
258
+ return this.applyRedirects((0, getRoutesRedirects_1.convertRedirect)(url, redirect[1]));
259
+ }
218
260
  }
219
261
  exports.RouterStore = RouterStore;
220
262
  exports.store = new RouterStore();
@@ -1 +1 @@
1
- {"version":3,"file":"router-store.js","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n NavigationContainerRefWithCurrent,\n useNavigationContainerRef,\n} from '@react-navigation/native';\nimport Constants from 'expo-constants';\nimport equal from 'fast-deep-equal';\nimport { useSyncExternalStore, useMemo, ComponentType, Fragment } from 'react';\nimport { Platform } from 'react-native';\n\nimport {\n canGoBack,\n canDismiss,\n goBack,\n linkTo,\n navigate,\n dismiss,\n dismissAll,\n push,\n reload,\n replace,\n setParams,\n dismissTo,\n LinkToOptions,\n} from './routing';\nimport { getSortedRoutes } from './sort-routes';\nimport { UrlObject, getRouteInfoFromState } from '../LocationProvider';\nimport { RouteNode } from '../Route';\nimport { getPathDataFromState, getPathFromState } from '../fork/getPathFromState';\n// import { ResultState } from '../fork/getStateFromPath';\nimport { ExpoLinkingOptions, LinkingConfigOptions, getLinkingConfig } from '../getLinkingConfig';\nimport { getRoutes } from '../getRoutes';\nimport { resolveHref, resolveHrefStringWithSegments } from '../link/href';\nimport { Href, RequireContext } from '../types';\nimport { getQualifiedRouteComponent } from '../useScreens';\nimport * as SplashScreen from '../views/Splash';\n\ntype ResultState = any;\n\n/**\n * This is the global state for the router. It is used to keep track of the current route, and to provide a way to navigate to other routes.\n *\n * There should only be one instance of this class and be initialized via `useInitializeExpoRouter`\n */\nexport class RouterStore {\n routeNode!: RouteNode | null;\n rootComponent!: ComponentType;\n linking?: ExpoLinkingOptions;\n private hasAttemptedToHideSplash: boolean = false;\n\n initialState?: ResultState;\n rootState?: ResultState;\n nextState?: ResultState;\n routeInfo?: UrlObject;\n splashScreenAnimationFrame?: number;\n\n navigationRef!: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;\n navigationRefSubscription!: () => void;\n\n rootStateSubscribers = new Set<() => void>();\n storeSubscribers = new Set<() => void>();\n\n linkTo = linkTo.bind(this);\n getSortedRoutes = getSortedRoutes.bind(this);\n goBack = goBack.bind(this);\n canGoBack = canGoBack.bind(this);\n push = push.bind(this);\n dismiss = dismiss.bind(this);\n dismissTo = dismissTo.bind(this);\n replace = replace.bind(this);\n dismissAll = dismissAll.bind(this);\n canDismiss = canDismiss.bind(this);\n setParams = setParams.bind(this);\n navigate = navigate.bind(this);\n reload = reload.bind(this);\n\n initialize(\n context: RequireContext,\n navigationRef: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>,\n linkingConfigOptions: LinkingConfigOptions = {}\n ) {\n // Clean up any previous state\n this.initialState = undefined;\n this.rootState = undefined;\n this.nextState = undefined;\n this.linking = undefined;\n this.navigationRefSubscription?.();\n this.rootStateSubscribers.clear();\n this.storeSubscribers.clear();\n\n this.routeNode = getRoutes(context, {\n ...Constants.expoConfig?.extra?.router,\n ignoreEntryPoints: true,\n platform: Platform.OS,\n });\n\n // We always needs routeInfo, even if there are no routes. This can happen if:\n // - there are no routes (we are showing the onboarding screen)\n // - getInitialURL() is async\n this.routeInfo = {\n unstable_globalHref: '',\n pathname: '',\n isIndex: false,\n params: {},\n segments: [],\n };\n\n if (this.routeNode) {\n // We have routes, so get the linking config and the root component\n this.linking = getLinkingConfig(this, this.routeNode, context, linkingConfigOptions);\n\n this.rootComponent = getQualifiedRouteComponent(this.routeNode);\n\n // By default React Navigation is async and does not render anything in the first pass as it waits for `getInitialURL`\n // This will cause static rendering to fail, which once performs a single pass.\n // If the initialURL is a string, we can preload the state and routeInfo, skipping React Navigation's async behavior.\n const initialURL = this.linking?.getInitialURL?.();\n if (typeof initialURL === 'string') {\n this.rootState = this.linking.getStateFromPath?.(initialURL, this.linking.config);\n this.initialState = this.rootState;\n if (this.rootState) {\n this.routeInfo = this.getRouteInfo(this.rootState);\n }\n }\n } else {\n // Only error in production, in development we will show the onboarding screen\n if (process.env.NODE_ENV === 'production') {\n throw new Error('No routes found');\n }\n\n // In development, we will show the onboarding screen\n this.rootComponent = Fragment;\n }\n\n /**\n * Counter intuitively - this fires AFTER both React Navigation's state changes and the subsequent paint.\n * This poses a couple of issues for Expo Router,\n * - Ensuring hooks (e.g. useSearchParams()) have data in the initial render\n * - Reacting to state changes after a navigation event\n *\n * This is why the initial render renders a Fragment and we wait until `onReady()` is called\n * Additionally, some hooks compare the state from both the store and the navigationRef. If the store it stale,\n * that hooks will manually update the store.\n *\n */\n this.navigationRef = navigationRef;\n this.navigationRefSubscription = navigationRef.addListener('state', (data) => {\n const state = data.data.state as ResultState;\n\n if (!this.hasAttemptedToHideSplash) {\n this.hasAttemptedToHideSplash = true;\n // NOTE(EvanBacon): `navigationRef.isReady` is sometimes not true when state is called initially.\n this.splashScreenAnimationFrame = requestAnimationFrame(() => {\n SplashScreen._internal_maybeHideAsync?.();\n });\n }\n\n let shouldUpdateSubscribers = this.nextState === state;\n this.nextState = undefined;\n\n // This can sometimes be undefined when an error is thrown in the Root Layout Route.\n // Additionally that state may already equal the rootState if it was updated within a hook\n if (state && state !== this.rootState) {\n store.updateState(state, undefined);\n shouldUpdateSubscribers = true;\n }\n\n // If the state has changed, or was changed inside a hook we need to update the subscribers\n if (shouldUpdateSubscribers) {\n for (const subscriber of this.rootStateSubscribers) {\n subscriber();\n }\n }\n });\n\n for (const subscriber of this.storeSubscribers) {\n subscriber();\n }\n }\n\n updateState(state: ResultState, nextState = state) {\n store.rootState = state;\n store.nextState = nextState;\n\n const nextRouteInfo = store.getRouteInfo(state);\n\n if (!equal(this.routeInfo, nextRouteInfo)) {\n store.routeInfo = nextRouteInfo;\n }\n }\n\n getRouteInfo(state: ResultState) {\n return getRouteInfoFromState(\n (state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {\n return getPathDataFromState(state, {\n screens: {},\n ...this.linking?.config,\n preserveDynamicRoutes: asPath,\n preserveGroups: asPath,\n shouldEncodeURISegment: false,\n });\n },\n state\n );\n }\n\n // This is only used in development, to show the onboarding screen\n // In production we should have errored during the initialization\n shouldShowTutorial() {\n return !this.routeNode && process.env.NODE_ENV === 'development';\n }\n\n /** Make sure these are arrow functions so `this` is correctly bound */\n subscribeToRootState = (subscriber: () => void) => {\n this.rootStateSubscribers.add(subscriber);\n return () => this.rootStateSubscribers.delete(subscriber);\n };\n subscribeToStore = (subscriber: () => void) => {\n this.storeSubscribers.add(subscriber);\n return () => this.storeSubscribers.delete(subscriber);\n };\n snapshot = () => {\n return this;\n };\n rootStateSnapshot = () => {\n return this.rootState!;\n };\n routeInfoSnapshot = () => {\n return this.routeInfo!;\n };\n\n cleanup() {\n if (this.splashScreenAnimationFrame) {\n cancelAnimationFrame(this.splashScreenAnimationFrame);\n }\n }\n\n getStateFromPath(href: Href, options: LinkToOptions = {}) {\n href = resolveHref(href);\n href = resolveHrefStringWithSegments(href, this.routeInfo, options);\n return this.linking?.getStateFromPath?.(href, this.linking.config);\n }\n}\n\nexport const store = new RouterStore();\n\nexport function useExpoRouter() {\n return useSyncExternalStore(store.subscribeToStore, store.snapshot, store.snapshot);\n}\n\nfunction syncStoreRootState() {\n if (store.navigationRef.isReady()) {\n const currentState = store.navigationRef.getRootState() as unknown as ResultState;\n\n if (store.rootState !== currentState) {\n store.updateState(currentState);\n }\n }\n}\n\nexport function useStoreRootState() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.rootStateSnapshot,\n store.rootStateSnapshot\n );\n}\n\nexport function useStoreRouteInfo() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.routeInfoSnapshot,\n store.routeInfoSnapshot\n );\n}\n\nexport function useInitializeExpoRouter(context: RequireContext, options: LinkingConfigOptions) {\n const navigationRef = useNavigationContainerRef();\n useMemo(() => store.initialize(context, navigationRef, options), [context]);\n useExpoRouter();\n return store;\n}\n"]}
1
+ {"version":3,"file":"router-store.js","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n NavigationContainerRefWithCurrent,\n useNavigationContainerRef,\n} from '@react-navigation/native';\nimport Constants from 'expo-constants';\nimport * as Linking from 'expo-linking';\nimport equal from 'fast-deep-equal';\nimport { useSyncExternalStore, useMemo, ComponentType, Fragment } from 'react';\nimport { Platform } from 'react-native';\n\nimport {\n canGoBack,\n canDismiss,\n goBack,\n linkTo,\n navigate,\n dismiss,\n dismissAll,\n push,\n reload,\n replace,\n setParams,\n dismissTo,\n LinkToOptions,\n} from './routing';\nimport { getSortedRoutes } from './sort-routes';\nimport { UrlObject, getRouteInfoFromState } from '../LocationProvider';\nimport { RouteNode } from '../Route';\nimport { getPathDataFromState, getPathFromState } from '../fork/getPathFromState';\nimport { cleanPath, routePatternToRegex } from '../fork/getStateFromPath-forks';\nimport { ExpoLinkingOptions, LinkingConfigOptions, getLinkingConfig } from '../getLinkingConfig';\nimport { parseRouteSegments } from '../getReactNavigationConfig';\nimport { getRoutes } from '../getRoutes';\nimport { RedirectConfig } from '../getRoutesCore';\nimport { convertRedirect } from '../getRoutesRedirects';\nimport { resolveHref, resolveHrefStringWithSegments } from '../link/href';\nimport { Href, RequireContext } from '../types';\nimport { getQualifiedRouteComponent } from '../useScreens';\nimport { shouldLinkExternally } from '../utils/url';\nimport * as SplashScreen from '../views/Splash';\n\ntype ResultState = any;\n\n/**\n * This is the global state for the router. It is used to keep track of the current route, and to provide a way to navigate to other routes.\n *\n * There should only be one instance of this class and be initialized via `useInitializeExpoRouter`\n */\nexport class RouterStore {\n routeNode!: RouteNode | null;\n rootComponent!: ComponentType;\n linking?: ExpoLinkingOptions;\n private hasAttemptedToHideSplash: boolean = false;\n\n initialState?: ResultState;\n rootState?: ResultState;\n nextState?: ResultState;\n routeInfo?: UrlObject;\n splashScreenAnimationFrame?: number;\n\n // The expo-router config plugin\n config: any;\n redirects?: (readonly [RegExp, RedirectConfig, boolean])[];\n\n navigationRef!: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;\n navigationRefSubscription!: () => void;\n\n rootStateSubscribers = new Set<() => void>();\n storeSubscribers = new Set<() => void>();\n\n linkTo = linkTo.bind(this);\n getSortedRoutes = getSortedRoutes.bind(this);\n goBack = goBack.bind(this);\n canGoBack = canGoBack.bind(this);\n push = push.bind(this);\n dismiss = dismiss.bind(this);\n dismissTo = dismissTo.bind(this);\n replace = replace.bind(this);\n dismissAll = dismissAll.bind(this);\n canDismiss = canDismiss.bind(this);\n setParams = setParams.bind(this);\n navigate = navigate.bind(this);\n reload = reload.bind(this);\n\n initialize(\n context: RequireContext,\n navigationRef: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>,\n linkingConfigOptions: LinkingConfigOptions = {}\n ) {\n // Clean up any previous state\n this.initialState = undefined;\n this.rootState = undefined;\n this.nextState = undefined;\n this.linking = undefined;\n this.navigationRefSubscription?.();\n this.rootStateSubscribers.clear();\n this.storeSubscribers.clear();\n\n this.config = Constants.expoConfig?.extra?.router;\n // On the client, there is no difference between redirects and rewrites\n this.redirects = [this.config?.redirects, this.config?.rewrites]\n .filter(Boolean)\n .flat()\n .map((route) => {\n return [\n routePatternToRegex(parseRouteSegments(route.source)),\n route,\n shouldLinkExternally(route.destination),\n ] as const;\n });\n\n this.routeNode = getRoutes(context, {\n ...Constants.expoConfig?.extra?.router,\n ignoreEntryPoints: true,\n platform: Platform.OS,\n });\n\n // We always needs routeInfo, even if there are no routes. This can happen if:\n // - there are no routes (we are showing the onboarding screen)\n // - getInitialURL() is async\n this.routeInfo = {\n unstable_globalHref: '',\n pathname: '',\n isIndex: false,\n params: {},\n segments: [],\n };\n\n if (this.routeNode) {\n // We have routes, so get the linking config and the root component\n this.linking = getLinkingConfig(this, this.routeNode, context, {\n ...Constants.expoConfig?.extra?.router,\n ...linkingConfigOptions,\n });\n this.rootComponent = getQualifiedRouteComponent(this.routeNode);\n\n // By default React Navigation is async and does not render anything in the first pass as it waits for `getInitialURL`\n // This will cause static rendering to fail, which once performs a single pass.\n // If the initialURL is a string, we can preload the state and routeInfo, skipping React Navigation's async behavior.\n const initialURL = this.linking?.getInitialURL?.();\n if (typeof initialURL === 'string') {\n this.rootState = this.linking.getStateFromPath?.(initialURL, this.linking.config);\n this.initialState = this.rootState;\n if (this.rootState) {\n this.routeInfo = this.getRouteInfo(this.rootState);\n }\n }\n } else {\n // Only error in production, in development we will show the onboarding screen\n if (process.env.NODE_ENV === 'production') {\n throw new Error('No routes found');\n }\n\n // In development, we will show the onboarding screen\n this.rootComponent = Fragment;\n }\n\n /**\n * Counter intuitively - this fires AFTER both React Navigation's state changes and the subsequent paint.\n * This poses a couple of issues for Expo Router,\n * - Ensuring hooks (e.g. useSearchParams()) have data in the initial render\n * - Reacting to state changes after a navigation event\n *\n * This is why the initial render renders a Fragment and we wait until `onReady()` is called\n * Additionally, some hooks compare the state from both the store and the navigationRef. If the store it stale,\n * that hooks will manually update the store.\n *\n */\n this.navigationRef = navigationRef;\n this.navigationRefSubscription = navigationRef.addListener('state', (data) => {\n const state = data.data.state as ResultState;\n\n if (!this.hasAttemptedToHideSplash) {\n this.hasAttemptedToHideSplash = true;\n // NOTE(EvanBacon): `navigationRef.isReady` is sometimes not true when state is called initially.\n this.splashScreenAnimationFrame = requestAnimationFrame(() => {\n SplashScreen._internal_maybeHideAsync?.();\n });\n }\n\n let shouldUpdateSubscribers = this.nextState === state;\n this.nextState = undefined;\n\n // This can sometimes be undefined when an error is thrown in the Root Layout Route.\n // Additionally that state may already equal the rootState if it was updated within a hook\n if (state && state !== this.rootState) {\n store.updateState(state, undefined);\n shouldUpdateSubscribers = true;\n }\n\n // If the state has changed, or was changed inside a hook we need to update the subscribers\n if (shouldUpdateSubscribers) {\n for (const subscriber of this.rootStateSubscribers) {\n subscriber();\n }\n }\n });\n\n for (const subscriber of this.storeSubscribers) {\n subscriber();\n }\n }\n\n updateState(state: ResultState, nextState = state) {\n store.rootState = state;\n store.nextState = nextState;\n\n const nextRouteInfo = store.getRouteInfo(state);\n\n if (!equal(this.routeInfo, nextRouteInfo)) {\n store.routeInfo = nextRouteInfo;\n }\n }\n\n getRouteInfo(state: ResultState) {\n return getRouteInfoFromState(\n (state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {\n return getPathDataFromState(state, {\n screens: {},\n ...this.linking?.config,\n preserveDynamicRoutes: asPath,\n preserveGroups: asPath,\n shouldEncodeURISegment: false,\n });\n },\n state\n );\n }\n\n // This is only used in development, to show the onboarding screen\n // In production we should have errored during the initialization\n shouldShowTutorial() {\n return !this.routeNode && process.env.NODE_ENV === 'development';\n }\n\n /** Make sure these are arrow functions so `this` is correctly bound */\n subscribeToRootState = (subscriber: () => void) => {\n this.rootStateSubscribers.add(subscriber);\n return () => this.rootStateSubscribers.delete(subscriber);\n };\n subscribeToStore = (subscriber: () => void) => {\n this.storeSubscribers.add(subscriber);\n return () => this.storeSubscribers.delete(subscriber);\n };\n snapshot = () => {\n return this;\n };\n rootStateSnapshot = () => {\n return this.rootState!;\n };\n routeInfoSnapshot = () => {\n return this.routeInfo!;\n };\n\n cleanup() {\n if (this.splashScreenAnimationFrame) {\n cancelAnimationFrame(this.splashScreenAnimationFrame);\n }\n }\n\n getStateFromPath(href: Href, options: LinkToOptions = {}) {\n href = resolveHref(href);\n href = resolveHrefStringWithSegments(href, this.routeInfo, options);\n return this.linking?.getStateFromPath?.(href, this.linking.config);\n }\n\n applyRedirects<T extends string | null | undefined>(url: T): T | undefined {\n if (typeof url !== 'string') {\n return url;\n }\n\n const nextUrl = cleanPath(url);\n const redirect = this.redirects?.find(([regex]) => regex.test(nextUrl));\n\n if (!redirect) {\n return url;\n }\n\n // If the redirect is external, open the URL\n if (redirect[2]) {\n let href = redirect[1].destination as T & string;\n if (href.startsWith('//') && Platform.OS !== 'web') {\n href = `https:${href}` as T & string;\n }\n\n Linking.openURL(href);\n return;\n }\n\n return this.applyRedirects<T>(convertRedirect(url, redirect[1]) as T);\n }\n}\n\nexport const store = new RouterStore();\n\nexport function useExpoRouter() {\n return useSyncExternalStore(store.subscribeToStore, store.snapshot, store.snapshot);\n}\n\nfunction syncStoreRootState() {\n if (store.navigationRef.isReady()) {\n const currentState = store.navigationRef.getRootState() as unknown as ResultState;\n\n if (store.rootState !== currentState) {\n store.updateState(currentState);\n }\n }\n}\n\nexport function useStoreRootState() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.rootStateSnapshot,\n store.rootStateSnapshot\n );\n}\n\nexport function useStoreRouteInfo() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.routeInfoSnapshot,\n store.routeInfoSnapshot\n );\n}\n\nexport function useInitializeExpoRouter(context: RequireContext, options: LinkingConfigOptions) {\n const navigationRef = useNavigationContainerRef();\n useMemo(() => store.initialize(context, navigationRef, options), [context]);\n useExpoRouter();\n return store;\n}\n"]}
@@ -31,5 +31,5 @@ export type LinkToOptions = {
31
31
  */
32
32
  dangerouslySingular?: SingularOptions;
33
33
  };
34
- export declare function linkTo(this: RouterStore, href: string, options?: LinkToOptions): void;
34
+ export declare function linkTo(this: RouterStore, originalHref: string, options?: LinkToOptions): void;
35
35
  //# sourceMappingURL=routing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAWhD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAE7D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAEjF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,QAGvC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAE7E;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,QAKxD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAEnF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAEhF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,QAK3C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,QAMvC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAepD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAmBrD;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,WAAW,EACjB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAM,OAOnE;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,eAAe,CAAC;CACvC,CAAC;AAEF,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,QAoDlF"}
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAWhD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAE7D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAEjF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,QAGvC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAE7E;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,QAKxD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAEnF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,OAEhF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,QAK3C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,QAMvC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAepD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAmBrD;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,WAAW,EACjB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAM,OAOnE;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,eAAe,CAAC;CACvC,CAAC;AAEF,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,QA4D1F"}
@@ -120,7 +120,8 @@ function setParams(params = {}) {
120
120
  return (this.navigationRef?.current?.setParams)(params);
121
121
  }
122
122
  exports.setParams = setParams;
123
- function linkTo(href, options = {}) {
123
+ function linkTo(originalHref, options = {}) {
124
+ let href = originalHref;
124
125
  if ((0, useDomComponentNavigation_1.emitDomLinkEvent)(href, options)) {
125
126
  return;
126
127
  }
@@ -145,6 +146,11 @@ function linkTo(href, options = {}) {
145
146
  }
146
147
  const rootState = navigationRef.getRootState();
147
148
  href = (0, href_1.resolveHrefStringWithSegments)(href, this.routeInfo, options);
149
+ href = this.applyRedirects(href);
150
+ // If the href is undefined, it means that the redirect has already been handled the navigation
151
+ if (!href) {
152
+ return;
153
+ }
148
154
  const state = this.linking.getStateFromPath(href, this.linking.config);
149
155
  if (!state || state.routes.length === 0) {
150
156
  console.error('Could not generate a valid navigation state for the given path: ' + href);
@@ -1 +1 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"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","sourcesContent":["import { StackActions, type NavigationState, PartialRoute } from '@react-navigation/native';\nimport { IS_DOM } from 'expo/dom';\nimport * as Linking from 'expo-linking';\nimport { Platform } from 'react-native';\n\nimport { type RouterStore } from './router-store';\nimport { ResultState } from '../fork/getStateFromPath';\nimport { resolveHref, resolveHrefStringWithSegments } from '../link/href';\nimport {\n emitDomDismiss,\n emitDomDismissAll,\n emitDomGoBack,\n emitDomLinkEvent,\n emitDomSetParams,\n} from '../link/useDomComponentNavigation';\nimport { matchDynamicName } from '../matchers';\nimport { Href } from '../types';\nimport { SingularOptions } from '../useScreens';\nimport { shouldLinkExternally } from '../utils/url';\n\nfunction assertIsReady(store: RouterStore) {\n if (!store.navigationRef.isReady()) {\n throw new Error(\n 'Attempted to navigate before mounting the Root Layout component. Ensure the Root Layout component is rendering a Slot, or other navigator on the first render.'\n );\n }\n}\n\nexport type NavigationOptions = Omit<LinkToOptions, 'event'>;\n\nexport function navigate(this: RouterStore, url: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(url), { ...options, event: 'NAVIGATE' });\n}\n\nexport function reload(this: RouterStore) {\n // TODO(EvanBacon): add `reload` support.\n throw new Error('The reload method is not implemented in the client-side router yet.');\n}\n\nexport function push(this: RouterStore, url: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(url), { ...options, event: 'PUSH' });\n}\n\nexport function dismiss(this: RouterStore, count?: number) {\n if (emitDomDismiss(count)) {\n return;\n }\n this.navigationRef?.dispatch(StackActions.pop(count));\n}\n\nexport function dismissTo(this: RouterStore, href: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(href), { ...options, event: 'POP_TO' });\n}\n\nexport function replace(this: RouterStore, url: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(url), { ...options, event: 'REPLACE' });\n}\n\nexport function dismissAll(this: RouterStore) {\n if (emitDomDismissAll()) {\n return;\n }\n this.navigationRef?.dispatch(StackActions.popToTop());\n}\n\nexport function goBack(this: RouterStore) {\n if (emitDomGoBack()) {\n return;\n }\n assertIsReady(this);\n this.navigationRef?.current?.goBack();\n}\n\nexport function canGoBack(this: RouterStore): boolean {\n if (IS_DOM) {\n throw new Error(\n 'canGoBack imperative method is not supported. Pass the property to the DOM component instead.'\n );\n }\n // Return a default value here if the navigation hasn't mounted yet.\n // This can happen if the user calls `canGoBack` from the Root Layout route\n // before mounting a navigator. This behavior exists due to React Navigation being dynamically\n // constructed at runtime. We can get rid of this in the future if we use\n // the static configuration internally.\n if (!this.navigationRef.isReady()) {\n return false;\n }\n return this.navigationRef?.current?.canGoBack() ?? false;\n}\n\nexport function canDismiss(this: RouterStore): boolean {\n if (IS_DOM) {\n throw new Error(\n 'canDismiss imperative method is not supported. Pass the property to the DOM component instead.'\n );\n }\n let state = this.rootState;\n\n // Keep traversing down the state tree until we find a stack navigator that we can pop\n while (state) {\n if (state.type === 'stack' && state.routes.length > 1) {\n return true;\n }\n if (state.index === undefined) return false;\n\n state = state.routes?.[state.index]?.state as any;\n }\n\n return false;\n}\n\nexport function setParams(\n this: RouterStore,\n params: Record<string, string | number | (string | number)[]> = {}\n) {\n if (emitDomSetParams(params)) {\n return;\n }\n assertIsReady(this);\n return (this.navigationRef?.current?.setParams as any)(params);\n}\n\nexport type LinkToOptions = {\n event?: string;\n\n /**\n * Relative URL references are either relative to the directory or the document. By default, relative paths are relative to the document.\n * @see: [MDN's documentation on Resolving relative references to a URL](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references).\n */\n relativeToDirectory?: boolean;\n\n /**\n * Include the anchor when navigating to a new navigator\n */\n withAnchor?: boolean;\n\n /**\n * When navigating in a Stack, remove all screen from the history that match the singular condition\n *\n * If used with `push`, the history will be filtered even if no navigation occurs.\n */\n dangerouslySingular?: SingularOptions;\n};\n\nexport function linkTo(this: RouterStore, href: string, options: LinkToOptions = {}) {\n if (emitDomLinkEvent(href, options)) {\n return;\n }\n\n if (shouldLinkExternally(href)) {\n if (href.startsWith('//') && Platform.OS !== 'web') {\n href = `https:${href}`;\n }\n\n Linking.openURL(href);\n return;\n }\n\n assertIsReady(this);\n const navigationRef = this.navigationRef.current;\n\n if (navigationRef == null) {\n throw new Error(\n \"Couldn't find a navigation object. Is your component inside NavigationContainer?\"\n );\n }\n\n if (!this.linking) {\n throw new Error('Attempted to link to route when no routes are present');\n }\n\n if (href === '..' || href === '../') {\n navigationRef.goBack();\n return;\n }\n\n const rootState = navigationRef.getRootState();\n\n href = resolveHrefStringWithSegments(href, this.routeInfo, options);\n\n const state = this.linking.getStateFromPath!(href, this.linking.config);\n\n if (!state || state.routes.length === 0) {\n console.error('Could not generate a valid navigation state for the given path: ' + href);\n return;\n }\n\n return navigationRef.dispatch(\n getNavigateAction(\n state,\n rootState,\n options.event,\n options.withAnchor,\n options.dangerouslySingular\n )\n );\n}\n\nfunction getNavigateAction(\n actionState: ResultState,\n navigationState: NavigationState,\n type = 'NAVIGATE',\n withAnchor?: boolean,\n singular?: SingularOptions\n) {\n /**\n * We need to find the deepest navigator where the action and current state diverge, If they do not diverge, the\n * lowest navigator is the target.\n *\n * By default React Navigation will target the current navigator, but this doesn't work for all actions\n * For example:\n * - /deeply/nested/route -> /top-level-route the target needs to be the top-level navigator\n * - /stack/nestedStack/page -> /stack1/nestedStack/other-page needs to target the nestedStack navigator\n *\n * This matching needs to done by comparing the route names and the dynamic path, for example\n * - /1/page -> /2/anotherPage needs to target the /[id] navigator\n *\n * Other parameters such as search params and hash are not evaluated.\n */\n let actionStateRoute: PartialRoute<any> | undefined;\n\n // Traverse the state tree comparing the current state and the action state until we find where they diverge\n while (actionState && navigationState) {\n const stateRoute = navigationState.routes[navigationState.index];\n\n actionStateRoute = actionState.routes[actionState.routes.length - 1];\n\n const childState: any = actionStateRoute.state;\n const nextNavigationState = stateRoute.state;\n\n const dynamicName = matchDynamicName(actionStateRoute.name);\n\n const didActionAndCurrentStateDiverge =\n actionStateRoute.name !== stateRoute.name ||\n !childState ||\n !nextNavigationState ||\n (dynamicName && actionStateRoute.params?.[dynamicName] !== stateRoute.params?.[dynamicName]);\n\n if (didActionAndCurrentStateDiverge) {\n break;\n }\n\n actionState = childState;\n navigationState = nextNavigationState as NavigationState;\n }\n\n /*\n * We found the target navigator, but the payload is in the incorrect format\n * We need to convert the action state to a payload that can be dispatched\n */\n const rootPayload: Record<string, any> = { params: {} };\n let payload = rootPayload;\n let params = payload.params;\n\n // The root level of payload is a bit weird, its params are in the child object\n while (actionStateRoute) {\n Object.assign(params, { ...payload.params, ...actionStateRoute.params });\n // Assign the screen name to the payload\n payload.screen = actionStateRoute.name;\n // Merge the params, ensuring that we create a new object\n payload.params = { ...params };\n\n // Params don't include the screen, thats a separate attribute\n delete payload.params['screen'];\n\n // Continue down the payload tree\n // Initially these values are separate, but React Nav merges them after the first layer\n payload = payload.params;\n params = payload;\n\n actionStateRoute = actionStateRoute.state?.routes[actionStateRoute.state?.routes.length - 1];\n }\n\n if (type === 'PUSH' && navigationState.type !== 'stack') {\n type = 'NAVIGATE';\n } else if (navigationState.type === 'expo-tab') {\n type = 'JUMP_TO';\n } else if (\n type === 'REPLACE' &&\n (navigationState.type === 'tab' || navigationState.type === 'drawer')\n ) {\n type = 'JUMP_TO';\n }\n\n if (withAnchor !== undefined) {\n if (rootPayload.params.initial) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`The parameter 'initial' is a reserved parameter name in React Navigation`);\n }\n }\n /*\n * The logic for initial can seen backwards depending on your perspective\n * True: The initialRouteName is not loaded. The incoming screen is the initial screen (default)\n * False: The initialRouteName is loaded. THe incoming screen is placed after the initialRouteName\n *\n * withAnchor flips the perspective.\n * True: You want the initialRouteName to load.\n * False: You do not want the initialRouteName to load.\n */\n rootPayload.params.initial = !withAnchor;\n }\n\n return {\n type,\n target: navigationState.key,\n payload: {\n // key: rootPayload.key,\n name: rootPayload.screen,\n params: rootPayload.params,\n singular,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"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","sourcesContent":["import { StackActions, type NavigationState, PartialRoute } from '@react-navigation/native';\nimport { IS_DOM } from 'expo/dom';\nimport * as Linking from 'expo-linking';\nimport { Platform } from 'react-native';\n\nimport { type RouterStore } from './router-store';\nimport { ResultState } from '../fork/getStateFromPath';\nimport { resolveHref, resolveHrefStringWithSegments } from '../link/href';\nimport {\n emitDomDismiss,\n emitDomDismissAll,\n emitDomGoBack,\n emitDomLinkEvent,\n emitDomSetParams,\n} from '../link/useDomComponentNavigation';\nimport { matchDynamicName } from '../matchers';\nimport { Href } from '../types';\nimport { SingularOptions } from '../useScreens';\nimport { shouldLinkExternally } from '../utils/url';\n\nfunction assertIsReady(store: RouterStore) {\n if (!store.navigationRef.isReady()) {\n throw new Error(\n 'Attempted to navigate before mounting the Root Layout component. Ensure the Root Layout component is rendering a Slot, or other navigator on the first render.'\n );\n }\n}\n\nexport type NavigationOptions = Omit<LinkToOptions, 'event'>;\n\nexport function navigate(this: RouterStore, url: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(url), { ...options, event: 'NAVIGATE' });\n}\n\nexport function reload(this: RouterStore) {\n // TODO(EvanBacon): add `reload` support.\n throw new Error('The reload method is not implemented in the client-side router yet.');\n}\n\nexport function push(this: RouterStore, url: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(url), { ...options, event: 'PUSH' });\n}\n\nexport function dismiss(this: RouterStore, count?: number) {\n if (emitDomDismiss(count)) {\n return;\n }\n this.navigationRef?.dispatch(StackActions.pop(count));\n}\n\nexport function dismissTo(this: RouterStore, href: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(href), { ...options, event: 'POP_TO' });\n}\n\nexport function replace(this: RouterStore, url: Href, options?: NavigationOptions) {\n return this.linkTo(resolveHref(url), { ...options, event: 'REPLACE' });\n}\n\nexport function dismissAll(this: RouterStore) {\n if (emitDomDismissAll()) {\n return;\n }\n this.navigationRef?.dispatch(StackActions.popToTop());\n}\n\nexport function goBack(this: RouterStore) {\n if (emitDomGoBack()) {\n return;\n }\n assertIsReady(this);\n this.navigationRef?.current?.goBack();\n}\n\nexport function canGoBack(this: RouterStore): boolean {\n if (IS_DOM) {\n throw new Error(\n 'canGoBack imperative method is not supported. Pass the property to the DOM component instead.'\n );\n }\n // Return a default value here if the navigation hasn't mounted yet.\n // This can happen if the user calls `canGoBack` from the Root Layout route\n // before mounting a navigator. This behavior exists due to React Navigation being dynamically\n // constructed at runtime. We can get rid of this in the future if we use\n // the static configuration internally.\n if (!this.navigationRef.isReady()) {\n return false;\n }\n return this.navigationRef?.current?.canGoBack() ?? false;\n}\n\nexport function canDismiss(this: RouterStore): boolean {\n if (IS_DOM) {\n throw new Error(\n 'canDismiss imperative method is not supported. Pass the property to the DOM component instead.'\n );\n }\n let state = this.rootState;\n\n // Keep traversing down the state tree until we find a stack navigator that we can pop\n while (state) {\n if (state.type === 'stack' && state.routes.length > 1) {\n return true;\n }\n if (state.index === undefined) return false;\n\n state = state.routes?.[state.index]?.state as any;\n }\n\n return false;\n}\n\nexport function setParams(\n this: RouterStore,\n params: Record<string, string | number | (string | number)[]> = {}\n) {\n if (emitDomSetParams(params)) {\n return;\n }\n assertIsReady(this);\n return (this.navigationRef?.current?.setParams as any)(params);\n}\n\nexport type LinkToOptions = {\n event?: string;\n\n /**\n * Relative URL references are either relative to the directory or the document. By default, relative paths are relative to the document.\n * @see: [MDN's documentation on Resolving relative references to a URL](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references).\n */\n relativeToDirectory?: boolean;\n\n /**\n * Include the anchor when navigating to a new navigator\n */\n withAnchor?: boolean;\n\n /**\n * When navigating in a Stack, remove all screen from the history that match the singular condition\n *\n * If used with `push`, the history will be filtered even if no navigation occurs.\n */\n dangerouslySingular?: SingularOptions;\n};\n\nexport function linkTo(this: RouterStore, originalHref: string, options: LinkToOptions = {}) {\n let href: string | undefined = originalHref;\n\n if (emitDomLinkEvent(href, options)) {\n return;\n }\n\n if (shouldLinkExternally(href)) {\n if (href.startsWith('//') && Platform.OS !== 'web') {\n href = `https:${href}`;\n }\n\n Linking.openURL(href);\n return;\n }\n\n assertIsReady(this);\n const navigationRef = this.navigationRef.current;\n\n if (navigationRef == null) {\n throw new Error(\n \"Couldn't find a navigation object. Is your component inside NavigationContainer?\"\n );\n }\n\n if (!this.linking) {\n throw new Error('Attempted to link to route when no routes are present');\n }\n\n if (href === '..' || href === '../') {\n navigationRef.goBack();\n return;\n }\n\n const rootState = navigationRef.getRootState();\n\n href = resolveHrefStringWithSegments(href, this.routeInfo, options);\n href = this.applyRedirects(href);\n\n // If the href is undefined, it means that the redirect has already been handled the navigation\n if (!href) {\n return;\n }\n\n const state = this.linking.getStateFromPath!(href, this.linking.config);\n\n if (!state || state.routes.length === 0) {\n console.error('Could not generate a valid navigation state for the given path: ' + href);\n return;\n }\n\n return navigationRef.dispatch(\n getNavigateAction(\n state,\n rootState,\n options.event,\n options.withAnchor,\n options.dangerouslySingular\n )\n );\n}\n\nfunction getNavigateAction(\n actionState: ResultState,\n navigationState: NavigationState,\n type = 'NAVIGATE',\n withAnchor?: boolean,\n singular?: SingularOptions\n) {\n /**\n * We need to find the deepest navigator where the action and current state diverge, If they do not diverge, the\n * lowest navigator is the target.\n *\n * By default React Navigation will target the current navigator, but this doesn't work for all actions\n * For example:\n * - /deeply/nested/route -> /top-level-route the target needs to be the top-level navigator\n * - /stack/nestedStack/page -> /stack1/nestedStack/other-page needs to target the nestedStack navigator\n *\n * This matching needs to done by comparing the route names and the dynamic path, for example\n * - /1/page -> /2/anotherPage needs to target the /[id] navigator\n *\n * Other parameters such as search params and hash are not evaluated.\n */\n let actionStateRoute: PartialRoute<any> | undefined;\n\n // Traverse the state tree comparing the current state and the action state until we find where they diverge\n while (actionState && navigationState) {\n const stateRoute = navigationState.routes[navigationState.index];\n\n actionStateRoute = actionState.routes[actionState.routes.length - 1];\n\n const childState: any = actionStateRoute.state;\n const nextNavigationState = stateRoute.state;\n\n const dynamicName = matchDynamicName(actionStateRoute.name);\n\n const didActionAndCurrentStateDiverge =\n actionStateRoute.name !== stateRoute.name ||\n !childState ||\n !nextNavigationState ||\n (dynamicName && actionStateRoute.params?.[dynamicName] !== stateRoute.params?.[dynamicName]);\n\n if (didActionAndCurrentStateDiverge) {\n break;\n }\n\n actionState = childState;\n navigationState = nextNavigationState as NavigationState;\n }\n\n /*\n * We found the target navigator, but the payload is in the incorrect format\n * We need to convert the action state to a payload that can be dispatched\n */\n const rootPayload: Record<string, any> = { params: {} };\n let payload = rootPayload;\n let params = payload.params;\n\n // The root level of payload is a bit weird, its params are in the child object\n while (actionStateRoute) {\n Object.assign(params, { ...payload.params, ...actionStateRoute.params });\n // Assign the screen name to the payload\n payload.screen = actionStateRoute.name;\n // Merge the params, ensuring that we create a new object\n payload.params = { ...params };\n\n // Params don't include the screen, thats a separate attribute\n delete payload.params['screen'];\n\n // Continue down the payload tree\n // Initially these values are separate, but React Nav merges them after the first layer\n payload = payload.params;\n params = payload;\n\n actionStateRoute = actionStateRoute.state?.routes[actionStateRoute.state?.routes.length - 1];\n }\n\n if (type === 'PUSH' && navigationState.type !== 'stack') {\n type = 'NAVIGATE';\n } else if (navigationState.type === 'expo-tab') {\n type = 'JUMP_TO';\n } else if (\n type === 'REPLACE' &&\n (navigationState.type === 'tab' || navigationState.type === 'drawer')\n ) {\n type = 'JUMP_TO';\n }\n\n if (withAnchor !== undefined) {\n if (rootPayload.params.initial) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`The parameter 'initial' is a reserved parameter name in React Navigation`);\n }\n }\n /*\n * The logic for initial can seen backwards depending on your perspective\n * True: The initialRouteName is not loaded. The incoming screen is the initial screen (default)\n * False: The initialRouteName is loaded. THe incoming screen is placed after the initialRouteName\n *\n * withAnchor flips the perspective.\n * True: You want the initialRouteName to load.\n * False: You do not want the initialRouteName to load.\n */\n rootPayload.params.initial = !withAnchor;\n }\n\n return {\n type,\n target: navigationState.key,\n payload: {\n // key: rootPayload.key,\n name: rootPayload.screen,\n params: rootPayload.params,\n singular,\n },\n };\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { LinkingOptions } from '@react-navigation/native';
2
2
  import { getPathFromState } from '../fork/getPathFromState';
3
3
  import { getStateFromPath } from '../fork/getStateFromPath';
4
+ import { RouterStore } from '../global-state/router-store';
4
5
  import { NativeIntent } from '../types';
5
6
  export declare function getInitialURL(): ReturnType<NonNullable<LinkingOptions<Record<string, unknown>>['getInitialURL']>>;
6
7
  export declare function getRootURL(): string;
7
- export declare function addEventListener(nativeLinking?: NativeIntent): (listener: (url: string) => void) => () => void;
8
+ export declare function addEventListener(nativeLinking: NativeIntent | undefined, store: RouterStore): (listener: (url: string) => void) => () => void;
8
9
  export { getStateFromPath, getPathFromState };
9
10
  //# sourceMappingURL=linking.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AASxC,wBAAgB,aAAa,IAAI,UAAU,CACzC,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CACtE,CA0BA;AAID,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAgBD,wBAAgB,gBAAgB,CAAC,aAAa,CAAC,EAAE,YAAY,oBACnC,MAAM,KAAK,IAAI,gBAiCxC;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AASxC,wBAAgB,aAAa,IAAI,UAAU,CACzC,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CACtE,CA0BA;AAID,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAgBD,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,YAAY,GAAG,SAAS,EAAE,KAAK,EAAE,WAAW,oBAClE,MAAM,KAAK,IAAI,gBAuCxC;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -84,26 +84,32 @@ function parseExpoGoUrlFromListener(url) {
84
84
  }
85
85
  return url;
86
86
  }
87
- function addEventListener(nativeLinking) {
87
+ function addEventListener(nativeLinking, store) {
88
88
  return (listener) => {
89
89
  let callback;
90
90
  const legacySubscription = nativeLinking?.legacy_subscribe?.(listener);
91
91
  if (isExpoGo) {
92
92
  // This extra work is only done in the Expo Go app.
93
93
  callback = async ({ url }) => {
94
- url = parseExpoGoUrlFromListener(url);
95
- if (url && nativeLinking?.redirectSystemPath) {
96
- url = await nativeLinking.redirectSystemPath({ path: url, initial: false });
94
+ let href = parseExpoGoUrlFromListener(url);
95
+ href = store.applyRedirects(href);
96
+ if (href && nativeLinking?.redirectSystemPath) {
97
+ href = await nativeLinking.redirectSystemPath({ path: href, initial: false });
98
+ }
99
+ if (href) {
100
+ listener(href);
97
101
  }
98
- listener(url);
99
102
  };
100
103
  }
101
104
  else {
102
105
  callback = async ({ url }) => {
103
- if (url && nativeLinking?.redirectSystemPath) {
104
- url = await nativeLinking.redirectSystemPath({ path: url, initial: false });
106
+ let href = store.applyRedirects(url);
107
+ if (href && nativeLinking?.redirectSystemPath) {
108
+ href = await nativeLinking.redirectSystemPath({ path: href, initial: false });
109
+ }
110
+ if (href) {
111
+ listener(href);
105
112
  }
106
- listener(url);
107
113
  };
108
114
  }
109
115
  const subscription = Linking.addEventListener('url', callback);
@@ -1 +1 @@
1
- {"version":3,"file":"linking.js","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"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","sourcesContent":["import { LinkingOptions } from '@react-navigation/native';\nimport * as Linking from 'expo-linking';\nimport { Platform } from 'react-native';\n\nimport {\n parsePathAndParamsFromExpoGoLink,\n parsePathFromExpoGoLink,\n} from '../fork/extractPathFromURL';\nimport { getPathFromState } from '../fork/getPathFromState';\nimport { getStateFromPath } from '../fork/getStateFromPath';\nimport { getInitialURLWithTimeout } from '../fork/useLinking';\nimport { NativeIntent } from '../types';\n\nconst isExpoGo = typeof expo !== 'undefined' && globalThis.expo?.modules?.ExpoGo;\n\n// A custom getInitialURL is used on native to ensure the app always starts at\n// the root path if it's launched from something other than a deep link.\n// This helps keep the native functionality working like the web functionality.\n// For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n// then `/index` would be used on web and `/settings` would be used on native.\nexport function getInitialURL(): ReturnType<\n NonNullable<LinkingOptions<Record<string, unknown>>['getInitialURL']>\n> {\n if (typeof window === 'undefined') {\n return '';\n }\n if (Platform.OS === 'web' && window.location?.href) {\n return window.location.href;\n }\n if (Platform.OS === 'ios') {\n // Use the new Expo API for iOS. This has better support for App Clips and handoff.\n const url = Linking.getLinkingURL();\n return (\n parseExpoGoUrlFromListener(url) ??\n // The path will be nullish in bare apps when the app is launched from the home screen.\n // TODO(EvanBacon): define some policy around notifications.\n getRootURL()\n );\n }\n\n // TODO: Figure out if expo-linking on Android has full interop with the React Native implementation.\n return Promise.resolve(getInitialURLWithTimeout()).then(\n (url) =>\n parseExpoGoUrlFromListener(url) ??\n // The path will be nullish in bare apps when the app is launched from the home screen.\n // TODO(EvanBacon): define some policy around notifications.\n getRootURL()\n );\n}\n\nlet _rootURL: string | undefined;\n\nexport function getRootURL(): string {\n if (_rootURL === undefined) {\n _rootURL = Linking.createURL('/');\n if (isExpoGo) {\n _rootURL = parsePathFromExpoGoLink(_rootURL);\n }\n }\n return _rootURL;\n}\n\n// Expo Go is weird and requires the root path to be `/--/`\nfunction parseExpoGoUrlFromListener<T extends string | null>(url: T): T {\n if (!url || !isExpoGo) {\n return url;\n }\n const { pathname, queryString } = parsePathAndParamsFromExpoGoLink(url);\n // If the URL is defined (default in Expo Go dev apps) and the URL has no path:\n // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/`\n if (!pathname || pathname === '/') {\n return (getRootURL() + queryString) as T;\n }\n return url;\n}\n\nexport function addEventListener(nativeLinking?: NativeIntent) {\n return (listener: (url: string) => void) => {\n let callback: (({ url }: { url: string }) => void) | undefined;\n\n const legacySubscription = nativeLinking?.legacy_subscribe?.(listener);\n\n if (isExpoGo) {\n // This extra work is only done in the Expo Go app.\n callback = async ({ url }) => {\n url = parseExpoGoUrlFromListener(url);\n\n if (url && nativeLinking?.redirectSystemPath) {\n url = await nativeLinking.redirectSystemPath({ path: url, initial: false });\n }\n\n listener(url);\n };\n } else {\n callback = async ({ url }) => {\n if (url && nativeLinking?.redirectSystemPath) {\n url = await nativeLinking.redirectSystemPath({ path: url, initial: false });\n }\n listener(url);\n };\n }\n\n const subscription = Linking.addEventListener('url', callback);\n\n return () => {\n // https://github.com/facebook/react-native/commit/6d1aca806cee86ad76de771ed3a1cc62982ebcd7\n subscription?.remove?.();\n legacySubscription?.();\n };\n };\n}\n\nexport { getStateFromPath, getPathFromState };\n"]}
1
+ {"version":3,"file":"linking.js","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,sDAAwC;AACxC,+CAAwC;AAExC,mEAGoC;AACpC,+DAA4D;AA+GjC,iGA/GlB,mCAAgB,OA+GkB;AA9G3C,+DAA4D;AA8GnD,iGA9GA,mCAAgB,OA8GA;AA7GzB,mDAA8D;AAI9D,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,WAAW,IAAI,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC;AAEjF,8EAA8E;AAC9E,wEAAwE;AACxE,+EAA+E;AAC/E,8GAA8G;AAC9G,8EAA8E;AAC9E,SAAgB,aAAa;IAG3B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,EAAE,CAAC;KACX;IACD,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE;QAClD,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;KAC7B;IACD,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,mFAAmF;QACnF,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;QACpC,OAAO,CACL,0BAA0B,CAAC,GAAG,CAAC;YAC/B,uFAAuF;YACvF,4DAA4D;YAC5D,UAAU,EAAE,CACb,CAAC;KACH;IAED,qGAAqG;IACrG,OAAO,OAAO,CAAC,OAAO,CAAC,IAAA,qCAAwB,GAAE,CAAC,CAAC,IAAI,CACrD,CAAC,GAAG,EAAE,EAAE,CACN,0BAA0B,CAAC,GAAG,CAAC;QAC/B,uFAAuF;QACvF,4DAA4D;QAC5D,UAAU,EAAE,CACf,CAAC;AACJ,CAAC;AA5BD,sCA4BC;AAED,IAAI,QAA4B,CAAC;AAEjC,SAAgB,UAAU;IACxB,IAAI,QAAQ,KAAK,SAAS,EAAE;QAC1B,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,EAAE;YACZ,QAAQ,GAAG,IAAA,4CAAuB,EAAC,QAAQ,CAAC,CAAC;SAC9C;KACF;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AARD,gCAQC;AAED,2DAA2D;AAC3D,SAAS,0BAA0B,CAA0B,GAAM;IACjE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;QACrB,OAAO,GAAG,CAAC;KACZ;IACD,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAA,qDAAgC,EAAC,GAAG,CAAC,CAAC;IACxE,+EAA+E;IAC/E,oFAAoF;IACpF,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,GAAG,EAAE;QACjC,OAAO,CAAC,UAAU,EAAE,GAAG,WAAW,CAAM,CAAC;KAC1C;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,gBAAgB,CAAC,aAAuC,EAAE,KAAkB;IAC1F,OAAO,CAAC,QAA+B,EAAE,EAAE;QACzC,IAAI,QAA0D,CAAC;QAE/D,MAAM,kBAAkB,GAAG,aAAa,EAAE,gBAAgB,EAAE,CAAC,QAAQ,CAAC,CAAC;QAEvE,IAAI,QAAQ,EAAE;YACZ,mDAAmD;YACnD,QAAQ,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC3B,IAAI,IAAI,GAAuB,0BAA0B,CAAC,GAAG,CAAC,CAAC;gBAC/D,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBAClC,IAAI,IAAI,IAAI,aAAa,EAAE,kBAAkB,EAAE;oBAC7C,IAAI,GAAG,MAAM,aAAa,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;iBAC/E;gBAED,IAAI,IAAI,EAAE;oBACR,QAAQ,CAAC,IAAI,CAAC,CAAC;iBAChB;YACH,CAAC,CAAC;SACH;aAAM;YACL,QAAQ,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC3B,IAAI,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;gBACrC,IAAI,IAAI,IAAI,aAAa,EAAE,kBAAkB,EAAE;oBAC7C,IAAI,GAAG,MAAM,aAAa,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;iBAC/E;gBAED,IAAI,IAAI,EAAE;oBACR,QAAQ,CAAC,IAAI,CAAC,CAAC;iBAChB;YACH,CAAC,CAAC;SACH;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAE/D,OAAO,GAAG,EAAE;YACV,2FAA2F;YAC3F,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;YACzB,kBAAkB,EAAE,EAAE,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAxCD,4CAwCC","sourcesContent":["import { LinkingOptions } from '@react-navigation/native';\nimport * as Linking from 'expo-linking';\nimport { Platform } from 'react-native';\n\nimport {\n parsePathAndParamsFromExpoGoLink,\n parsePathFromExpoGoLink,\n} from '../fork/extractPathFromURL';\nimport { getPathFromState } from '../fork/getPathFromState';\nimport { getStateFromPath } from '../fork/getStateFromPath';\nimport { getInitialURLWithTimeout } from '../fork/useLinking';\nimport { RouterStore } from '../global-state/router-store';\nimport { NativeIntent } from '../types';\n\nconst isExpoGo = typeof expo !== 'undefined' && globalThis.expo?.modules?.ExpoGo;\n\n// A custom getInitialURL is used on native to ensure the app always starts at\n// the root path if it's launched from something other than a deep link.\n// This helps keep the native functionality working like the web functionality.\n// For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n// then `/index` would be used on web and `/settings` would be used on native.\nexport function getInitialURL(): ReturnType<\n NonNullable<LinkingOptions<Record<string, unknown>>['getInitialURL']>\n> {\n if (typeof window === 'undefined') {\n return '';\n }\n if (Platform.OS === 'web' && window.location?.href) {\n return window.location.href;\n }\n if (Platform.OS === 'ios') {\n // Use the new Expo API for iOS. This has better support for App Clips and handoff.\n const url = Linking.getLinkingURL();\n return (\n parseExpoGoUrlFromListener(url) ??\n // The path will be nullish in bare apps when the app is launched from the home screen.\n // TODO(EvanBacon): define some policy around notifications.\n getRootURL()\n );\n }\n\n // TODO: Figure out if expo-linking on Android has full interop with the React Native implementation.\n return Promise.resolve(getInitialURLWithTimeout()).then(\n (url) =>\n parseExpoGoUrlFromListener(url) ??\n // The path will be nullish in bare apps when the app is launched from the home screen.\n // TODO(EvanBacon): define some policy around notifications.\n getRootURL()\n );\n}\n\nlet _rootURL: string | undefined;\n\nexport function getRootURL(): string {\n if (_rootURL === undefined) {\n _rootURL = Linking.createURL('/');\n if (isExpoGo) {\n _rootURL = parsePathFromExpoGoLink(_rootURL);\n }\n }\n return _rootURL;\n}\n\n// Expo Go is weird and requires the root path to be `/--/`\nfunction parseExpoGoUrlFromListener<T extends string | null>(url: T): T {\n if (!url || !isExpoGo) {\n return url;\n }\n const { pathname, queryString } = parsePathAndParamsFromExpoGoLink(url);\n // If the URL is defined (default in Expo Go dev apps) and the URL has no path:\n // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/`\n if (!pathname || pathname === '/') {\n return (getRootURL() + queryString) as T;\n }\n return url;\n}\n\nexport function addEventListener(nativeLinking: NativeIntent | undefined, store: RouterStore) {\n return (listener: (url: string) => void) => {\n let callback: (({ url }: { url: string }) => void) | undefined;\n\n const legacySubscription = nativeLinking?.legacy_subscribe?.(listener);\n\n if (isExpoGo) {\n // This extra work is only done in the Expo Go app.\n callback = async ({ url }) => {\n let href: string | undefined = parseExpoGoUrlFromListener(url);\n href = store.applyRedirects(href);\n if (href && nativeLinking?.redirectSystemPath) {\n href = await nativeLinking.redirectSystemPath({ path: href, initial: false });\n }\n\n if (href) {\n listener(href);\n }\n };\n } else {\n callback = async ({ url }) => {\n let href = store.applyRedirects(url);\n if (href && nativeLinking?.redirectSystemPath) {\n href = await nativeLinking.redirectSystemPath({ path: href, initial: false });\n }\n\n if (href) {\n listener(href);\n }\n };\n }\n\n const subscription = Linking.addEventListener('url', callback);\n\n return () => {\n // https://github.com/facebook/react-native/commit/6d1aca806cee86ad76de771ed3a1cc62982ebcd7\n subscription?.remove?.();\n legacySubscription?.();\n };\n };\n}\n\nexport { getStateFromPath, getPathFromState };\n"]}
@@ -12,8 +12,10 @@ export declare function matchLastGroupName(name: string): string | undefined;
12
12
  export declare function matchArrayGroupName(name: string): string | undefined;
13
13
  export declare function getNameFromFilePath(name: string): string;
14
14
  export declare function getContextKey(name: string): string;
15
- /** Remove `.js`, `.ts`, `.jsx`, `.tsx` */
15
+ /** Remove `.js`, `.ts`, `.jsx`, `.tsx`, and the +api suffix */
16
16
  export declare function removeSupportedExtensions(name: string): string;
17
+ /** Remove `.js`, `.ts`, `.jsx`, `.tsx` */
18
+ export declare function removeFileSystemExtensions(name: string): string;
17
19
  export declare function removeFileSystemDots(filePath: string): string;
18
20
  export declare function stripGroupSegmentsFromPath(path: string): string;
19
21
  export declare function stripInvisibleSegmentsFromPath(path: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../src/matchers.tsx"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIjE;AAED,kCAAkC;AAClC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,+BAA+B;AAC/B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED,qCAAqC;AACrC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,sBAE/C;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,0CAA0C;AAC1C,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAGD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,WAExC"}
1
+ {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../src/matchers.tsx"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIjE;AAED,kCAAkC;AAClC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,+BAA+B;AAC/B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED,qCAAqC;AACrC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,sBAE/C;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,+DAA+D;AAC/D,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,0CAA0C;AAC1C,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAGD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,WAExC"}