1import path from 'path';
2import resolveFrom from 'resolve-from';
3
4const debug = require('debug')('expo:start:server:metro:router') as typeof console.log;
5
6/**
7 * Get the relative path for requiring the `/app` folder relative to the `expo-router/entry` file.
8 * This mechanism does require the server to restart after the `expo-router` package is installed.
9 */
10export function getAppRouterRelativeEntryPath(projectRoot: string): string | undefined {
11  // Auto pick App entry
12  const routerEntry =
13    resolveFrom.silent(projectRoot, 'expo-router/entry') ?? getFallbackEntryRoot(projectRoot);
14  if (!routerEntry) {
15    return undefined;
16  }
17  // It doesn't matter if the app folder exists.
18  const appFolder = path.join(projectRoot, 'app');
19  const appRoot = path.relative(path.dirname(routerEntry), appFolder);
20  debug('routerEntry', routerEntry, appFolder, appRoot);
21  return appRoot;
22}
23
24/** If the `expo-router` package is not installed, then use the `expo` package to determine where the node modules are relative to the project. */
25function getFallbackEntryRoot(projectRoot: string): string {
26  const expoRoot = resolveFrom.silent(projectRoot, 'expo/package.json');
27  if (expoRoot) {
28    return path.join(path.dirname(path.dirname(expoRoot)), 'expo-router/entry');
29  }
30  return path.join(projectRoot, 'node_modules/expo-router/entry');
31}
32