1import { ProjectConfig } from '@expo/config';
2import { getEntryPoint } from '@expo/config/paths';
3import chalk from 'chalk';
4import path from 'path';
5
6import { CommandError } from '../../../utils/errors';
7
8const supportedPlatforms = ['ios', 'android', 'web', 'none'];
9
10/** @returns the relative entry file for the project.  */
11export function resolveEntryPoint(
12  projectRoot: string,
13  platform?: string,
14  projectConfig?: ProjectConfig
15): string {
16  return path.relative(
17    projectRoot,
18    resolveAbsoluteEntryPoint(projectRoot, platform, projectConfig)
19  );
20}
21
22/** @returns the absolute entry file for the project.  */
23export function resolveAbsoluteEntryPoint(
24  projectRoot: string,
25  platform?: string,
26  projectConfig?: ProjectConfig
27): string {
28  if (platform && !supportedPlatforms.includes(platform)) {
29    throw new CommandError(
30      `Failed to resolve the project's entry file: The platform "${platform}" is not supported.`
31    );
32  }
33  // TODO(Bacon): support platform extension resolution like .ios, .native
34  // const platforms = [platform, 'native'].filter(Boolean) as string[];
35  const platforms: string[] = [];
36
37  const entry = getEntryPoint(projectRoot, ['./index'], platforms, projectConfig);
38  if (!entry) {
39    // NOTE(Bacon): I purposefully don't mention all possible resolutions here since the package.json is the most standard and users should opt towards that.
40    throw new CommandError(
41      chalk`The project entry file could not be resolved. Please define it in the {bold package.json} "main" field.`
42    );
43  }
44
45  return entry;
46}
47