1import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';
2
3function arrayize<T>(value: T[] | T | undefined): T[] {
4  if (Array.isArray(value)) {
5    return value;
6  }
7  return value != null ? [value] : [];
8}
9
10/**
11 * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).
12 */
13export class ExpoModuleConfig {
14  constructor(readonly rawConfig: RawExpoModuleConfig) {}
15
16  /**
17   * Whether the module supports given platform.
18   */
19  supportsPlatform(platform: SupportedPlatform): boolean {
20    return this.rawConfig.platforms?.includes(platform) ?? false;
21  }
22
23  /**
24   * Returns a list of names of Swift native modules classes to put to the generated modules provider file.
25   */
26  iosModules() {
27    const iosConfig = this.rawConfig.ios;
28
29    // `modulesClassNames` is a legacy name for the same config.
30    return iosConfig?.modules ?? iosConfig?.modulesClassNames ?? [];
31  }
32
33  /**
34   * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.
35   */
36  iosAppDelegateSubscribers(): string[] {
37    return this.rawConfig.ios?.appDelegateSubscribers ?? [];
38  }
39
40  /**
41   * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.
42   */
43  iosReactDelegateHandlers(): string[] {
44    return this.rawConfig.ios?.reactDelegateHandlers ?? [];
45  }
46
47  /**
48   * Returns podspec paths defined by the module author.
49   */
50  iosPodspecPaths(): string[] {
51    return arrayize(this.rawConfig.ios?.podspecPath);
52  }
53
54  /**
55   * Returns the product module names, if defined by the module author.
56   */
57  iosSwiftModuleNames(): string[] {
58    return arrayize(this.rawConfig.ios?.swiftModuleName);
59  }
60
61  /**
62   * Returns whether this module will be added only to the debug configuration
63   */
64  iosDebugOnly(): boolean {
65    return this.rawConfig.ios?.debugOnly ?? false;
66  }
67
68  /**
69   * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
70   */
71  androidModules() {
72    const androidConfig = this.rawConfig.android;
73
74    // `modulesClassNames` is a legacy name for the same config.
75    return androidConfig?.modules ?? androidConfig?.modulesClassNames ?? [];
76  }
77
78  /**
79   * Returns build.gradle file paths defined by the module author.
80   */
81  androidGradlePaths(): string[] {
82    return arrayize(this.rawConfig.android?.gradlePath ?? []);
83  }
84
85  /**
86   * Returns gradle plugins descriptors defined by the module author.
87   */
88  androidGradlePlugins(): AndroidGradlePluginDescriptor[] {
89    return arrayize(this.rawConfig.android?.gradlePlugins ?? []);
90  }
91
92  /**
93   * Returns serializable raw config.
94   */
95  toJSON(): RawExpoModuleConfig {
96    return this.rawConfig;
97  }
98}
99
100/**
101 * Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.
102 */
103export function requireAndResolveExpoModuleConfig(path: string): ExpoModuleConfig {
104  // TODO: Validate the raw config against a schema.
105  // TODO: Support for `*.js` files, not only static `*.json`.
106  return new ExpoModuleConfig(require(path) as RawExpoModuleConfig);
107}
108