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