1import * as PackageManager from '@expo/package-manager';
2
3import { CommandError } from '../utils/errors';
4import { assertUnexpectedObjectKeys, parseVariadicArguments } from '../utils/variadic';
5
6export type Options = Pick<PackageManager.CreateForProjectOptions, 'npm' | 'pnpm' | 'yarn'> & {
7  /** Check which packages need to be updated, does not install any provided packages. */
8  check?: boolean;
9  /** Should the dependencies be fixed automatically. */
10  fix?: boolean;
11  /** Should disable install output, used for commands like `prebuild` that run install internally. */
12  silent?: boolean;
13};
14
15function resolveOptions(options: Options): Options {
16  if (options.fix && options.check) {
17    throw new CommandError('BAD_ARGS', 'Specify at most one of: --check, --fix');
18  }
19  if ([options.npm, options.pnpm, options.yarn].filter(Boolean).length > 1) {
20    throw new CommandError('BAD_ARGS', 'Specify at most one of: --npm, --pnpm, --yarn');
21  }
22  return {
23    ...options,
24  };
25}
26
27export async function resolveArgsAsync(
28  argv: string[]
29): Promise<{ variadic: string[]; options: Options; extras: string[] }> {
30  const { variadic, extras, flags } = parseVariadicArguments(argv);
31
32  assertUnexpectedObjectKeys(['--check', '--fix', '--npm', '--pnpm', '--yarn'], flags);
33
34  return {
35    // Variadic arguments like `npx expo install react react-dom` -> ['react', 'react-dom']
36    variadic,
37    options: resolveOptions({
38      fix: !!flags['--fix'],
39      check: !!flags['--check'],
40      yarn: !!flags['--yarn'],
41      npm: !!flags['--npm'],
42      pnpm: !!flags['--pnpm'],
43    }),
44    extras,
45  };
46}
47