11#!/usr/bin/env node
22
33import { loadSession } from './api' ;
4- import { getAppCommands } from './app' ;
5- import { bundleCommands } from './bundle' ;
6- import { cacheCommands } from './cache' ;
7- import { diffCommands } from './diff' ;
8- import { installCommands } from './install' ;
9- import { packageCommands } from './package' ;
10- import { symbolicateCommands } from './symbolicate' ;
11- import { userCommands } from './user' ;
4+ import { commandNames , loadCommandHandler } from './commands' ;
125import { printVersionCommand } from './utils' ;
136import { t } from './utils/i18n' ;
14- import { versionCommands } from './versions' ;
15-
16- type CliCommandHandler = ( argv : any ) => Promise < unknown > | unknown ;
177
188interface CliArgv {
199 command : string ;
@@ -29,7 +19,7 @@ function printUsage(exitCode = 1) {
2919 console . log ( 'React Native Update CLI' ) ;
3020 console . log ( '' ) ;
3121 console . log ( 'Commands:' ) ;
32- for ( const name of Object . keys ( commandHandlers ) ) {
22+ for ( const name of commandNames ) {
3323 console . log ( ` ${ name } ` ) ;
3424 }
3525
@@ -45,22 +35,24 @@ function printUsage(exitCode = 1) {
4535 process . exit ( exitCode ) ;
4636}
4737
48- const commandHandlers : Record < string , CliCommandHandler > = {
49- ...userCommands ,
50- ...bundleCommands ,
51- ...cacheCommands ,
52- ...diffCommands ,
53- ...getAppCommands ( ) ,
54- ...packageCommands ,
55- ...versionCommands ,
56- ...symbolicateCommands ,
57- ...installCommands ,
58- help : printUsage ,
59- } ;
38+ /**
39+ * Errors reaching the top level are almost always about the user's input,
40+ * project or network: print their message. The stack trace, which only helps
41+ * when the CLI itself is at fault, is printed on request (RNU_DEBUG=1).
42+ */
43+ function reportError ( err : unknown ) {
44+ if ( isTruthyEnv ( process . env . RNU_DEBUG ) ) {
45+ console . error ( err instanceof Error ? err . stack : err ) ;
46+ return ;
47+ }
48+ console . error ( err instanceof Error ? err . message : String ( err ) ) ;
49+ console . error ( t ( 'errorStackHint' ) ) ;
50+ }
6051
6152async function run ( ) {
62- const versionOnly =
63- process . argv . indexOf ( '-v' ) >= 0 || process . argv [ 2 ] === 'version' ;
53+ const versionOnly = [ '-v' , '--version' , 'version' ] . includes (
54+ process . argv [ 2 ] ?? '' ,
55+ ) ;
6456 // The registry check for newer versions runs alongside the command (from a
6557 // 1-day cache when possible) and only ever delays `-v`/`version` itself; its
6658 // hint is printed once the command is done, or at exit for commands that
@@ -77,37 +69,39 @@ async function run() {
7769 }
7870 } ) ;
7971
80- const argv : CliArgv = require ( 'cli-arguments' ) . parse ( require ( '../cli.json' ) ) ;
81- global . NO_INTERACTIVE =
82- Boolean ( argv . options [ 'no-interactive' ] ) ||
83- isTruthyEnv ( process . env . NO_INTERACTIVE ) ;
84- global . USE_ACC_OSS =
85- Boolean ( argv . options . acc ) || isTruthyEnv ( process . env . USE_ACC_OSS ) ;
86-
8772 try {
73+ // inside the try: an unknown command or option is reported like any other
74+ // error instead of crashing with an unhandled rejection
75+ const argv : CliArgv = require ( 'cli-arguments' ) . parse (
76+ require ( '../cli.json' ) ,
77+ ) ;
78+ global . NO_INTERACTIVE =
79+ Boolean ( argv . options [ 'no-interactive' ] ) ||
80+ isTruthyEnv ( process . env . NO_INTERACTIVE ) ;
81+ global . USE_ACC_OSS =
82+ Boolean ( argv . options . acc ) || isTruthyEnv ( process . env . USE_ACC_OSS ) ;
83+
8884 await loadSession ( ) ;
8985
90- if ( argv . command === 'help' ) {
86+ if ( argv . command === 'help' || argv . command === 'list' ) {
9187 printUsage ( 0 ) ;
92- } else if ( argv . command === 'list' ) {
93- printUsage ( 0 ) ;
94- } else if ( commandHandlers [ argv . command ] ) {
95- const handler = commandHandlers [ argv . command ] ;
96- await handler ( argv ) ;
97- // a check still in flight (cold cache) gets a short grace period; the
98- // registry request itself is unref'd, so exiting never waits on it
99- await versionCheck . settle ( 500 ) ;
100- versionCheck . printHints ( ) ;
101- versionCheck . startAutoUpdate ( ) ;
102- } else {
88+ }
89+ const handler = loadCommandHandler ( argv . command ) ;
90+ if ( ! handler ) {
10391 throw new Error ( t ( 'unknownCommand' , { command : argv . command } ) ) ;
10492 }
93+ await handler ( argv ) ;
94+ // a check still in flight (cold cache) gets a short grace period; the
95+ // registry request itself is unref'd, so exiting never waits on it
96+ await versionCheck . settle ( 500 ) ;
97+ versionCheck . printHints ( ) ;
98+ versionCheck . startAutoUpdate ( ) ;
10599 } catch ( err : any ) {
106- if ( err . status === 401 ) {
100+ if ( err ? .status === 401 ) {
107101 console . log ( t ( 'loginFirst' ) ) ;
108102 process . exit ( 1 ) ;
109103 }
110- console . error ( err . stack ) ;
104+ reportError ( err ) ;
111105 process . exit ( 1 ) ;
112106 }
113107}
0 commit comments