1// NOTE: Keep these types in-sync with expo-modules-autolinking
2
3export type SearchResults = {
4  [moduleName: string]: object;
5};
6
7export type SearchOptions = {
8  searchPaths: string[];
9  platform: 'ios' | 'android' | 'web';
10  silent?: boolean;
11};
12
13export type AutolinkingModule = {
14  resolveSearchPathsAsync(searchPaths: string[] | null, cwd: string): Promise<string[]>;
15  findModulesAsync(providedOptions: SearchOptions): Promise<SearchResults>;
16};
17
18/**
19 * Imports the `expo-modules-autolinking` package installed in the project at the given path.
20 */
21export function importExpoModulesAutolinking(projectRoot: string): AutolinkingModule {
22  const autolinking = tryRequireExpoModulesAutolinking(projectRoot);
23  assertAutolinkingCompatibility(autolinking);
24  return autolinking;
25}
26
27function tryRequireExpoModulesAutolinking(projectRoot: string): AutolinkingModule {
28  try {
29    const resolvedAutolinkingPath = require.resolve('expo-modules-autolinking/build/autolinking', {
30      paths: [projectRoot],
31    });
32    return require(resolvedAutolinkingPath);
33  } catch {
34    throw new Error(
35      "Cannot find 'expo-modules-autolinking' package in your project, make sure that you have 'expo' package installed"
36    );
37  }
38}
39
40function assertAutolinkingCompatibility(autolinking: AutolinkingModule): void {
41  if ('resolveSearchPathsAsync' in autolinking && 'findModulesAsync' in autolinking) {
42    return;
43  }
44  throw new Error(
45    "The 'expo-modules-autolinking' package has been found, but it seems to be incompatible with '@expo/prebuild-config'"
46  );
47}
48