xref: /expo/packages/@expo/cli/bin/cli.ts (revision 98ecfc87)
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  start: () => import('../src/start').then((i) => i.expoStart),
12  prebuild: () => import('../src/prebuild').then((i) => i.expoPrebuild),
13  config: () => import('../src/config').then((i) => i.expoConfig),
14  // Auth
15  login: () => import('../src/login').then((i) => i.expoLogin),
16  logout: () => import('../src/logout').then((i) => i.expoLogout),
17  register: () => import('../src/register').then((i) => i.expoRegister),
18  whoami: () => import('../src/whoami').then((i) => i.expoWhoami),
19};
20
21const args = arg(
22  {
23    // Types
24    '--version': Boolean,
25    '--help': Boolean,
26
27    // Aliases
28    '-v': '--version',
29    '-h': '--help',
30  },
31  {
32    permissive: true,
33  }
34);
35
36if (args['--version']) {
37  // Version is added in the build script.
38  console.log(process.env.__EXPO_VERSION);
39  process.exit(0);
40}
41
42// Check if we are running `npx expo <subcommand>` or `npx expo`
43const isSubcommand = Boolean(commands[args._[0]]);
44
45// Handle `--help` flag
46if (!isSubcommand && args['--help']) {
47  console.log(chalk`
48    {bold Usage}
49      {bold $} npx expo <command>
50
51    {bold Available commands}
52      ${Object.keys(commands).sort().join(', ')}
53
54    {bold Options}
55      --version, -v   Version number
56      --help, -h      Displays this message
57
58    For more information run a command with the --help flag
59      {bold $} expo start --help
60  `);
61  process.exit(0);
62}
63
64const command = isSubcommand ? args._[0] : defaultCmd;
65const commandArgs = isSubcommand ? args._.slice(1) : args._;
66
67// Push the help flag to the subcommand args.
68if (args['--help']) {
69  commandArgs.push('--help');
70}
71
72// Install exit hooks
73process.on('SIGINT', () => process.exit(0));
74process.on('SIGTERM', () => process.exit(0));
75
76commands[command]().then((exec) => exec(commandArgs));
77