xref: /expo/packages/@expo/cli/bin/cli.ts (revision bfcd021e)
1#!/usr/bin/env node
2import arg from 'arg';
3import chalk from 'chalk';
4
5const defaultCmd = 'start';
6
7export type Command = (argv?: string[]) => void;
8
9const commands: { [command: string]: () => Promise<Command> } = {
10  // Add a new command here
11  'run:ios': () => import('../src/run/ios').then((i) => i.expoRunIos),
12  'run:android': () => import('../src/run/android').then((i) => i.expoRunAndroid),
13  start: () => import('../src/start').then((i) => i.expoStart),
14  prebuild: () => import('../src/prebuild').then((i) => i.expoPrebuild),
15  config: () => import('../src/config').then((i) => i.expoConfig),
16  export: () => import('../src/export').then((i) => i.expoExport),
17
18  // Auxiliary commands
19  install: () => import('../src/install').then((i) => i.expoInstall),
20
21  // Auth
22  login: () => import('../src/login').then((i) => i.expoLogin),
23  logout: () => import('../src/logout').then((i) => i.expoLogout),
24  register: () => import('../src/register').then((i) => i.expoRegister),
25  whoami: () => import('../src/whoami').then((i) => i.expoWhoami),
26};
27
28const args = arg(
29  {
30    // Types
31    '--version': Boolean,
32    '--help': Boolean,
33
34    // Aliases
35    '-v': '--version',
36    '-h': '--help',
37  },
38  {
39    permissive: true,
40  }
41);
42
43if (args['--version']) {
44  // Version is added in the build script.
45  console.log(process.env.__EXPO_VERSION);
46  process.exit(0);
47}
48
49// Check if we are running `npx expo <subcommand>` or `npx expo`
50const isSubcommand = Boolean(commands[args._[0]]);
51
52// Handle `--help` flag
53if (!isSubcommand && args['--help']) {
54  const {
55    login,
56    logout,
57    whoami,
58    register,
59    start,
60    install,
61    export: _export,
62    config,
63    prebuild,
64    'run:ios': runIos,
65    'run:android': runAndroid,
66    ...others
67  } = commands;
68
69  console.log(chalk`
70  {bold Usage}
71    {dim $} npx expo <command>
72
73  {bold Commands}
74    ${Object.keys({ start, install, export: _export, config, ...others }).join(', ')}
75    ${Object.keys({ 'run:ios': runIos, 'run:android': runAndroid, prebuild }).join(', ')}
76    {dim ${Object.keys({ login, logout, whoami, register }).join(', ')}}
77
78  {bold Options}
79    --version, -v   Version number
80    --help, -h      Usage info
81
82  For more info run a command with the {bold --help} flag
83    {dim $} npx expo start --help
84`);
85  process.exit(0);
86}
87
88const command = isSubcommand ? args._[0] : defaultCmd;
89const commandArgs = isSubcommand ? args._.slice(1) : args._;
90
91// Push the help flag to the subcommand args.
92if (args['--help']) {
93  commandArgs.push('--help');
94}
95
96// Install exit hooks
97process.on('SIGINT', () => process.exit(0));
98process.on('SIGTERM', () => process.exit(0));
99
100commands[command]().then((exec) => exec(commandArgs));
101