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