1import { CommandError } from '../utils/errors'; 2 3const debug = require('debug')('expo:utils:variadic') as typeof console.log; 4 5/** Given a list of CLI args, return a sorted set of args based on categories used in a complex command. */ 6export function parseVariadicArguments(argv: string[]): { 7 variadic: string[]; 8 extras: string[]; 9 flags: Record<string, boolean>; 10} { 11 const variadic: string[] = []; 12 const flags: Record<string, boolean> = {}; 13 14 for (const arg of argv) { 15 if (!arg.startsWith('-')) { 16 variadic.push(arg); 17 } else if (arg === '--') { 18 break; 19 } else { 20 flags[arg] = true; 21 } 22 } 23 24 // Everything after `--` that is not an option is passed to the underlying install command. 25 const extras: string[] = []; 26 27 const extraOperator = argv.indexOf('--'); 28 if (extraOperator > -1 && argv.length > extraOperator + 1) { 29 const extraArgs = argv.slice(extraOperator + 1); 30 if (extraArgs.includes('--')) { 31 throw new CommandError('BAD_ARGS', 'Unexpected multiple --'); 32 } 33 extras.push(...extraArgs); 34 debug('Extra arguments: ' + extras.join(', ')); 35 } 36 37 debug(`Parsed arguments (variadic: %O, flags: %O, extra: %O)`, variadic, flags, extras); 38 39 return { 40 variadic, 41 flags, 42 extras, 43 }; 44} 45 46export function assertUnexpectedObjectKeys(keys: string[], obj: Record<string, any>): void { 47 const unexpectedKeys = Object.keys(obj).filter((key) => !keys.includes(key)); 48 if (unexpectedKeys.length > 0) { 49 throw new CommandError('BAD_ARGS', `Unexpected: ${unexpectedKeys.join(', ')}`); 50 } 51} 52 53export function assertUnexpectedVariadicFlags( 54 expectedFlags: string[], 55 { extras, flags, variadic }: ReturnType<typeof parseVariadicArguments>, 56 prefixCommand = '' 57) { 58 const unexpectedFlags = Object.keys(flags).filter((key) => !expectedFlags.includes(key)); 59 60 if (unexpectedFlags.length > 0) { 61 const intendedFlags = Object.entries(flags) 62 .filter(([key]) => expectedFlags.includes(key)) 63 .map(([key]) => key); 64 65 const cmd = [ 66 prefixCommand, 67 ...variadic, 68 ...intendedFlags, 69 '--', 70 ...extras.concat(unexpectedFlags), 71 ].join(' '); 72 73 throw new CommandError( 74 'BAD_ARGS', 75 `Unexpected: ${unexpectedFlags.join(', ')}\nDid you mean: ${cmd.trim()}` 76 ); 77 } 78} 79