1import spawnAsync, { SpawnOptions, SpawnResult } from '@expo/spawn-async';
2import { spawnSync } from 'child_process';
3import { join } from 'path';
4
5export const AUTOLINKINNG_CLI = join(__dirname, '../bin/expo-modules-autolinking.js');
6
7function isSpawnResult(errorOrResult: Error): errorOrResult is Error & SpawnResult {
8  return 'pid' in errorOrResult && 'stdout' in errorOrResult && 'stderr' in errorOrResult;
9}
10
11export async function autolinkingRunAsync(
12  args: string[],
13  options?: SpawnOptions
14): Promise<SpawnResult> {
15  const promise = spawnAsync(AUTOLINKINNG_CLI, args, {
16    ...options,
17    env: { ...process.env, EXPO_SHOULD_USE_LEGACY_PACKAGE_INTERFACE: '1' },
18  });
19
20  try {
21    return await promise;
22  } catch (error) {
23    if (isSpawnResult(error)) {
24      if (error.stdout) error.message += `\n------\nSTDOUT:\n${error.stdout}`;
25      if (error.stderr) error.message += `\n------\nSTDERR:\n${error.stderr}`;
26    }
27    throw error;
28  }
29}
30
31// For some reason, it can't be async, cause otherwise we will get `yarn did not print valid JSON:` error
32export function yarnSync(options?: SpawnOptions) {
33  spawnSync('yarn', ['install', '--silent'], options);
34}
35
36export function combinations<T, U>(
37  aKey: string,
38  a: T[],
39  bKey: string,
40  b: U[]
41): { [key: string]: T | U }[] {
42  const result = [];
43  a.forEach(aValue => {
44    b.forEach(bValue => {
45      result.push({
46        [aKey]: aValue,
47        [bKey]: bValue,
48      });
49    });
50  });
51
52  return result;
53}
54