expo-modules-autolinking 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,18 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 1.2.0 — 2023-04-13
14
+
15
+ ### 🎉 New features
16
+
17
+ - Added Gradle plugin autolinking support for Android. ([#21377](https://github.com/expo/expo/pull/21377) by [@kudo](https://github.com/kudo))
18
+
19
+ ## 1.1.2 — 2023-02-14
20
+
21
+ ### 💡 Others
22
+
23
+ - Suppress node warnings about deprecated exports mapping in 3rd-party dependencies. ([#21222](https://github.com/expo/expo/pull/21222) by [@tsapeta](https://github.com/tsapeta))
24
+
13
25
  ## 1.1.1 — 2023-02-09
14
26
 
15
27
  _This version does not introduce any user-facing changes._
@@ -1,4 +1,4 @@
1
- import { RawExpoModuleConfig, SupportedPlatform } from './types';
1
+ import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';
2
2
  /**
3
3
  * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).
4
4
  */
@@ -41,6 +41,10 @@ export declare class ExpoModuleConfig {
41
41
  * Returns build.gradle file paths defined by the module author.
42
42
  */
43
43
  androidGradlePaths(): string[];
44
+ /**
45
+ * Returns gradle plugins descriptors defined by the module author.
46
+ */
47
+ androidGradlePlugins(): AndroidGradlePluginDescriptor[];
44
48
  /**
45
49
  * Returns serializable raw config.
46
50
  */
@@ -72,6 +72,12 @@ class ExpoModuleConfig {
72
72
  androidGradlePaths() {
73
73
  return arrayize(this.rawConfig.android?.gradlePath ?? []);
74
74
  }
75
+ /**
76
+ * Returns gradle plugins descriptors defined by the module author.
77
+ */
78
+ androidGradlePlugins() {
79
+ return arrayize(this.rawConfig.android?.gradlePlugins ?? []);
80
+ }
75
81
  /**
76
82
  * Returns serializable raw config.
77
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA,SAAS,QAAQ,CAAI,KAA0B;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IACD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAErC,4DAA4D;QAC5D,OAAO,SAAS,EAAE,OAAO,IAAI,SAAS,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,yBAAyB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,sBAAsB,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,qBAAqB,IAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,IAAI,KAAK,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAE7C,4DAA4D;QAC5D,OAAO,aAAa,EAAE,OAAO,IAAI,aAAa,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AA9ED,4CA8EC;AAED;;GAEG;AACH,SAAgB,iCAAiC,CAAC,IAAY;IAC5D,kDAAkD;IAClD,4DAA4D;IAC5D,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAwB,CAAC,CAAC;AACpE,CAAC;AAJD,8EAIC","sourcesContent":["import { RawExpoModuleConfig, SupportedPlatform } from './types';\n\nfunction arrayize<T>(value: T[] | T | undefined): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\n/**\n * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).\n */\nexport class ExpoModuleConfig {\n constructor(readonly rawConfig: RawExpoModuleConfig) {}\n\n /**\n * Whether the module supports given platform.\n */\n supportsPlatform(platform: SupportedPlatform): boolean {\n return this.rawConfig.platforms?.includes(platform) ?? false;\n }\n\n /**\n * Returns a list of names of Swift native modules classes to put to the generated modules provider file.\n */\n iosModules() {\n const iosConfig = this.rawConfig.ios;\n\n // `modulesClassNames` is a legacy name for the same config.\n return iosConfig?.modules ?? iosConfig?.modulesClassNames ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.\n */\n iosAppDelegateSubscribers(): string[] {\n return this.rawConfig.ios?.appDelegateSubscribers ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.\n */\n iosReactDelegateHandlers(): string[] {\n return this.rawConfig.ios?.reactDelegateHandlers ?? [];\n }\n\n /**\n * Returns podspec paths defined by the module author.\n */\n iosPodspecPaths(): string[] {\n return arrayize(this.rawConfig.ios?.podspecPath);\n }\n\n /**\n * Returns the product module names, if defined by the module author.\n */\n iosSwiftModuleNames(): string[] {\n return arrayize(this.rawConfig.ios?.swiftModuleName);\n }\n\n /**\n * Returns whether this module will be added only to the debug configuration\n */\n iosDebugOnly(): boolean {\n return this.rawConfig.ios?.debugOnly ?? false;\n }\n\n /**\n * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.\n */\n androidModules() {\n const androidConfig = this.rawConfig.android;\n\n // `modulesClassNames` is a legacy name for the same config.\n return androidConfig?.modules ?? androidConfig?.modulesClassNames ?? [];\n }\n\n /**\n * Returns build.gradle file paths defined by the module author.\n */\n androidGradlePaths(): string[] {\n return arrayize(this.rawConfig.android?.gradlePath ?? []);\n }\n\n /**\n * Returns serializable raw config.\n */\n toJSON(): RawExpoModuleConfig {\n return this.rawConfig;\n }\n}\n\n/**\n * Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.\n */\nexport function requireAndResolveExpoModuleConfig(path: string): ExpoModuleConfig {\n // TODO: Validate the raw config against a schema.\n // TODO: Support for `*.js` files, not only static `*.json`.\n return new ExpoModuleConfig(require(path) as RawExpoModuleConfig);\n}\n"]}
1
+ {"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA,SAAS,QAAQ,CAAI,KAA0B;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IACD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAErC,4DAA4D;QAC5D,OAAO,SAAS,EAAE,OAAO,IAAI,SAAS,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,yBAAyB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,sBAAsB,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,qBAAqB,IAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,IAAI,KAAK,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAE7C,4DAA4D;QAC5D,OAAO,aAAa,EAAE,OAAO,IAAI,aAAa,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,oBAAoB;QAClB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AArFD,4CAqFC;AAED;;GAEG;AACH,SAAgB,iCAAiC,CAAC,IAAY;IAC5D,kDAAkD;IAClD,4DAA4D;IAC5D,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAwB,CAAC,CAAC;AACpE,CAAC;AAJD,8EAIC","sourcesContent":["import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';\n\nfunction arrayize<T>(value: T[] | T | undefined): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\n/**\n * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).\n */\nexport class ExpoModuleConfig {\n constructor(readonly rawConfig: RawExpoModuleConfig) {}\n\n /**\n * Whether the module supports given platform.\n */\n supportsPlatform(platform: SupportedPlatform): boolean {\n return this.rawConfig.platforms?.includes(platform) ?? false;\n }\n\n /**\n * Returns a list of names of Swift native modules classes to put to the generated modules provider file.\n */\n iosModules() {\n const iosConfig = this.rawConfig.ios;\n\n // `modulesClassNames` is a legacy name for the same config.\n return iosConfig?.modules ?? iosConfig?.modulesClassNames ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.\n */\n iosAppDelegateSubscribers(): string[] {\n return this.rawConfig.ios?.appDelegateSubscribers ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.\n */\n iosReactDelegateHandlers(): string[] {\n return this.rawConfig.ios?.reactDelegateHandlers ?? [];\n }\n\n /**\n * Returns podspec paths defined by the module author.\n */\n iosPodspecPaths(): string[] {\n return arrayize(this.rawConfig.ios?.podspecPath);\n }\n\n /**\n * Returns the product module names, if defined by the module author.\n */\n iosSwiftModuleNames(): string[] {\n return arrayize(this.rawConfig.ios?.swiftModuleName);\n }\n\n /**\n * Returns whether this module will be added only to the debug configuration\n */\n iosDebugOnly(): boolean {\n return this.rawConfig.ios?.debugOnly ?? false;\n }\n\n /**\n * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.\n */\n androidModules() {\n const androidConfig = this.rawConfig.android;\n\n // `modulesClassNames` is a legacy name for the same config.\n return androidConfig?.modules ?? androidConfig?.modulesClassNames ?? [];\n }\n\n /**\n * Returns build.gradle file paths defined by the module author.\n */\n androidGradlePaths(): string[] {\n return arrayize(this.rawConfig.android?.gradlePath ?? []);\n }\n\n /**\n * Returns gradle plugins descriptors defined by the module author.\n */\n androidGradlePlugins(): AndroidGradlePluginDescriptor[] {\n return arrayize(this.rawConfig.android?.gradlePlugins ?? []);\n }\n\n /**\n * Returns serializable raw config.\n */\n toJSON(): RawExpoModuleConfig {\n return this.rawConfig;\n }\n}\n\n/**\n * Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.\n */\nexport function requireAndResolveExpoModuleConfig(path: string): ExpoModuleConfig {\n // TODO: Validate the raw config against a schema.\n // TODO: Support for `*.js` files, not only static `*.json`.\n return new ExpoModuleConfig(require(path) as RawExpoModuleConfig);\n}\n"]}
@@ -44,9 +44,15 @@ async function resolveModuleAsync(packageName, revision) {
44
44
  sourceDir: path_1.default.dirname(gradleFilePath),
45
45
  };
46
46
  });
47
+ const plugins = (revision.config?.androidGradlePlugins() ?? []).map(({ id, group, sourceDir }) => ({
48
+ id,
49
+ group,
50
+ sourceDir: path_1.default.join(revision.path, sourceDir),
51
+ }));
47
52
  return {
48
53
  packageName,
49
54
  projects,
55
+ ...(plugins.length > 0 ? { plugins } : {}),
50
56
  modules: revision.config?.androidModules() ?? [],
51
57
  };
52
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/platforms/android.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,wDAA0B;AAC1B,gDAAwB;AAIxB;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAC5C,OAAkC,EAClC,UAAkB,EAClB,SAAiB;IAEjB,MAAM,oBAAoB,GAAG,MAAM,mCAAmC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3F,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;AACxD,CAAC;AAPD,4DAOC;AAED,KAAK,UAAU,oBAAoB,CAAC,QAAyB;IAC3D,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAChE,IAAI,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,EAAE;QACjD,OAAO,iBAAiB,CAAC;KAC1B;IAED,MAAM,gBAAgB,GAAG,MAAM,IAAA,mBAAI,EAAC,gBAAgB,EAAE;QACpD,GAAG,EAAE,QAAQ,CAAC,IAAI;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB;IAEzB,8EAA8E;IAE9E,0BAA0B;IAC1B,IAAI,WAAW,KAAK,kCAAkC,EAAE;QACtD,OAAO,IAAI,CAAC;KACb;IAED,MAAM,gBAAgB,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC9D,qEAAqE;IACrE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE;QACxD,MAAM,cAAc,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACjE,OAAO;YACL,IAAI,EAAE,+BAA+B,CACnC,WAAW,EACX,cAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAC7C;YACD,SAAS,EAAE,cAAI,CAAC,OAAO,CAAC,cAAc,CAAC;SACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,WAAW;QACX,QAAQ;QACR,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE;KACjD,CAAC;AACJ,CAAC;AAjCD,gDAiCC;AAED;;GAEG;AACH,KAAK,UAAU,mCAAmC,CAChD,OAAkC,EAClC,SAAiB;IAEjB,mHAAmH;IACnH,MAAM,eAAe,GAAG,MAAM,wBAAwB,CACpD,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,CAC1D,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEzD,OAAO,WAAW,SAAS;;;;;;;;;;;EAW3B,eAAe,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,aAAa,YAAY,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;QAI1E,cAAc,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,SAAS,WAAW,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;CAapF,CAAC;AACF,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAkC;IAC5D,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAI,EAAe,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAChG,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,OAAkC;IACxE,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,sBAAsB,GAAa,EAAE,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE;YACrC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SAChD;KACF;IAED,MAAM,OAAO,CAAC,GAAG,CACf,sBAAsB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAI,EAAC,uBAAuB,EAAE;YAChD,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YAE1E,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE;gBACzB,IAAI,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE;oBACxD,OAAO,uEAAuE,CAAC;iBAChF;qBAAM;oBACL,OAAO,qEAAqE,CAAC;iBAC9E;YACH,CAAC,CAAC,EAAE,CAAC;YAEL,6CAA6C;YAC7C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;gBACnC,SAAS;aACV;YAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAEnE,IAAI,gBAAgB,EAAE;gBACpB,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACzD,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;aACpD;SACF;IACH,CAAC,CAAC,CACH,CAAC;IACF,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,+BAA+B,CAC7C,WAAmB,EACnB,eAAuB;IAEvB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClE,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;AAC7D,CAAC;AAPD,0EAOC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptorAndroid, PackageRevision } from '../types';\n\n/**\n * Generates Java file that contains all autolinked packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptorAndroid[],\n targetPath: string,\n namespace: string\n): Promise<void> {\n const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\nasync function findGradleFilesAsync(revision: PackageRevision): Promise<string[]> {\n const configGradlePaths = revision.config?.androidGradlePaths();\n if (configGradlePaths && configGradlePaths.length) {\n return configGradlePaths;\n }\n\n const buildGradleFiles = await glob('*/build.gradle', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n return buildGradleFiles;\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptorAndroid | null> {\n // TODO: Relative source dir should be configurable through the module config.\n\n // Don't link itself... :D\n if (packageName === '@unimodules/react-native-adapter') {\n return null;\n }\n\n const buildGradleFiles = await findGradleFilesAsync(revision);\n // Just in case where the module doesn't have its own `build.gradle`.\n if (!buildGradleFiles.length) {\n return null;\n }\n\n const projects = buildGradleFiles.map((buildGradleFile) => {\n const gradleFilePath = path.join(revision.path, buildGradleFile);\n return {\n name: convertPackageNameToProjectName(\n packageName,\n path.relative(revision.path, gradleFilePath)\n ),\n sourceDir: path.dirname(gradleFilePath),\n };\n });\n\n return {\n packageName,\n projects,\n modules: revision.config?.androidModules() ?? [],\n };\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptorAndroid[],\n namespace: string\n): Promise<string> {\n // TODO: Instead of ignoring `expo` here, make the package class paths configurable from `expo-module.config.json`.\n const packagesClasses = await findAndroidPackagesAsync(\n modules.filter((module) => module.packageName !== 'expo')\n );\n\n const modulesClasses = await findAndroidModules(modules);\n\n return `package ${namespace};\n\nimport java.util.Arrays;\nimport java.util.List;\nimport expo.modules.core.interfaces.Package;\nimport expo.modules.kotlin.modules.Module;\nimport expo.modules.kotlin.ModulesProvider;\n\npublic class ExpoModulesPackageList implements ModulesProvider {\n private static class LazyHolder {\n static final List<Package> packagesList = Arrays.<Package>asList(\n${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\\n')}\n );\n\n static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(\n ${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\\n')}\n );\n }\n\n public static List<Package> getPackageList() {\n return LazyHolder.packagesList;\n }\n\n @Override\n public List<Class<? extends Module>> getModulesList() {\n return LazyHolder.modulesList;\n }\n}\n`;\n}\n\nfunction findAndroidModules(modules: ModuleDescriptorAndroid[]): string[] {\n const modulesToProvide = modules.filter((module) => module.modules.length > 0);\n const classNames = ([] as string[]).concat(...modulesToProvide.map((module) => module.modules));\n return classNames;\n}\n\nasync function findAndroidPackagesAsync(modules: ModuleDescriptorAndroid[]): Promise<string[]> {\n const classes: string[] = [];\n\n const flattenedSourceDirList: string[] = [];\n for (const module of modules) {\n for (const project of module.projects) {\n flattenedSourceDirList.push(project.sourceDir);\n }\n }\n\n await Promise.all(\n flattenedSourceDirList.map(async (sourceDir) => {\n const files = await glob('**/*Package.{java,kt}', {\n cwd: sourceDir,\n });\n\n for (const file of files) {\n const fileContent = await fs.readFile(path.join(sourceDir, file), 'utf8');\n\n const packageRegex = (() => {\n if (process.env.EXPO_SHOULD_USE_LEGACY_PACKAGE_INTERFACE) {\n return /\\bimport\\s+org\\.unimodules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n } else {\n return /\\bimport\\s+expo\\.modules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n }\n })();\n\n // Very naive check to skip non-expo packages\n if (!packageRegex.test(fileContent)) {\n continue;\n }\n\n const classPathMatches = fileContent.match(/^package ([\\w.]+)\\b/m);\n\n if (classPathMatches) {\n const basename = path.basename(file, path.extname(file));\n classes.push(`${classPathMatches[1]}.${basename}`);\n }\n }\n })\n );\n return classes.sort();\n}\n\n/**\n * Converts the package name and gradle file path to Android's project name.\n * `$` to indicate subprojects\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n *\n * Example: multiple projects\n * - `expo-test` + `android/build.gradle` → `react-native-third-party`\n * - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`\n */\nexport function convertPackageNameToProjectName(\n packageName: string,\n buildGradleFile: string\n): string {\n const name = packageName.replace(/^@/g, '').replace(/\\W+/g, '-');\n const baseDir = path.dirname(buildGradleFile).replace(/\\//g, '-');\n return baseDir === 'android' ? name : `${name}$${baseDir}`;\n}\n"]}
1
+ {"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/platforms/android.ts"],"names":[],"mappings":"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","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptorAndroid, PackageRevision } from '../types';\n\n/**\n * Generates Java file that contains all autolinked packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptorAndroid[],\n targetPath: string,\n namespace: string\n): Promise<void> {\n const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\nasync function findGradleFilesAsync(revision: PackageRevision): Promise<string[]> {\n const configGradlePaths = revision.config?.androidGradlePaths();\n if (configGradlePaths && configGradlePaths.length) {\n return configGradlePaths;\n }\n\n const buildGradleFiles = await glob('*/build.gradle', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n return buildGradleFiles;\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptorAndroid | null> {\n // TODO: Relative source dir should be configurable through the module config.\n\n // Don't link itself... :D\n if (packageName === '@unimodules/react-native-adapter') {\n return null;\n }\n\n const buildGradleFiles = await findGradleFilesAsync(revision);\n // Just in case where the module doesn't have its own `build.gradle`.\n if (!buildGradleFiles.length) {\n return null;\n }\n\n const projects = buildGradleFiles.map((buildGradleFile) => {\n const gradleFilePath = path.join(revision.path, buildGradleFile);\n return {\n name: convertPackageNameToProjectName(\n packageName,\n path.relative(revision.path, gradleFilePath)\n ),\n sourceDir: path.dirname(gradleFilePath),\n };\n });\n\n const plugins = (revision.config?.androidGradlePlugins() ?? []).map(\n ({ id, group, sourceDir }) => ({\n id,\n group,\n sourceDir: path.join(revision.path, sourceDir),\n })\n );\n\n return {\n packageName,\n projects,\n ...(plugins.length > 0 ? { plugins } : {}),\n modules: revision.config?.androidModules() ?? [],\n };\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptorAndroid[],\n namespace: string\n): Promise<string> {\n // TODO: Instead of ignoring `expo` here, make the package class paths configurable from `expo-module.config.json`.\n const packagesClasses = await findAndroidPackagesAsync(\n modules.filter((module) => module.packageName !== 'expo')\n );\n\n const modulesClasses = await findAndroidModules(modules);\n\n return `package ${namespace};\n\nimport java.util.Arrays;\nimport java.util.List;\nimport expo.modules.core.interfaces.Package;\nimport expo.modules.kotlin.modules.Module;\nimport expo.modules.kotlin.ModulesProvider;\n\npublic class ExpoModulesPackageList implements ModulesProvider {\n private static class LazyHolder {\n static final List<Package> packagesList = Arrays.<Package>asList(\n${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\\n')}\n );\n\n static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(\n ${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\\n')}\n );\n }\n\n public static List<Package> getPackageList() {\n return LazyHolder.packagesList;\n }\n\n @Override\n public List<Class<? extends Module>> getModulesList() {\n return LazyHolder.modulesList;\n }\n}\n`;\n}\n\nfunction findAndroidModules(modules: ModuleDescriptorAndroid[]): string[] {\n const modulesToProvide = modules.filter((module) => module.modules.length > 0);\n const classNames = ([] as string[]).concat(...modulesToProvide.map((module) => module.modules));\n return classNames;\n}\n\nasync function findAndroidPackagesAsync(modules: ModuleDescriptorAndroid[]): Promise<string[]> {\n const classes: string[] = [];\n\n const flattenedSourceDirList: string[] = [];\n for (const module of modules) {\n for (const project of module.projects) {\n flattenedSourceDirList.push(project.sourceDir);\n }\n }\n\n await Promise.all(\n flattenedSourceDirList.map(async (sourceDir) => {\n const files = await glob('**/*Package.{java,kt}', {\n cwd: sourceDir,\n });\n\n for (const file of files) {\n const fileContent = await fs.readFile(path.join(sourceDir, file), 'utf8');\n\n const packageRegex = (() => {\n if (process.env.EXPO_SHOULD_USE_LEGACY_PACKAGE_INTERFACE) {\n return /\\bimport\\s+org\\.unimodules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n } else {\n return /\\bimport\\s+expo\\.modules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n }\n })();\n\n // Very naive check to skip non-expo packages\n if (!packageRegex.test(fileContent)) {\n continue;\n }\n\n const classPathMatches = fileContent.match(/^package ([\\w.]+)\\b/m);\n\n if (classPathMatches) {\n const basename = path.basename(file, path.extname(file));\n classes.push(`${classPathMatches[1]}.${basename}`);\n }\n }\n })\n );\n return classes.sort();\n}\n\n/**\n * Converts the package name and gradle file path to Android's project name.\n * `$` to indicate subprojects\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n *\n * Example: multiple projects\n * - `expo-test` + `android/build.gradle` → `react-native-third-party`\n * - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`\n */\nexport function convertPackageNameToProjectName(\n packageName: string,\n buildGradleFile: string\n): string {\n const name = packageName.replace(/^@/g, '').replace(/\\W+/g, '-');\n const baseDir = path.dirname(buildGradleFile).replace(/\\//g, '-');\n return baseDir === 'android' ? name : `${name}$${baseDir}`;\n}\n"]}
package/build/types.d.ts CHANGED
@@ -34,9 +34,14 @@ export interface ModuleAndroidProjectInfo {
34
34
  name: string;
35
35
  sourceDir: string;
36
36
  }
37
+ export interface ModuleAndroidPluginInfo {
38
+ id: string;
39
+ sourceDir: string;
40
+ }
37
41
  export interface ModuleDescriptorAndroid {
38
42
  packageName: string;
39
43
  projects: ModuleAndroidProjectInfo[];
44
+ plugins?: ModuleAndroidPluginInfo[];
40
45
  modules: string[];
41
46
  }
42
47
  export interface ModuleIosPodspecInfo {
@@ -54,6 +59,20 @@ export interface ModuleDescriptorIos {
54
59
  debugOnly: boolean;
55
60
  }
56
61
  export type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;
62
+ export interface AndroidGradlePluginDescriptor {
63
+ /**
64
+ * Gradle plugin ID
65
+ */
66
+ id: string;
67
+ /**
68
+ * Artifact group
69
+ */
70
+ group: string;
71
+ /**
72
+ * Relative path to the gradle plugin directory
73
+ */
74
+ sourceDir: string;
75
+ }
57
76
  /**
58
77
  * Represents a raw config from `expo-module.json`.
59
78
  */
@@ -117,5 +136,9 @@ export interface RawExpoModuleConfig {
117
136
  * To have multiple build.gradle projects, string array type is also supported.
118
137
  */
119
138
  gradlePath?: string | string[];
139
+ /**
140
+ * Gradle plugins.
141
+ */
142
+ gradlePlugins?: AndroidGradlePluginDescriptor[];
120
143
  };
121
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ExpoModuleConfig } from './ExpoModuleConfig';\n\nexport type SupportedPlatform = 'ios' | 'android' | 'web';\n\nexport interface SearchOptions {\n // Available in the CLI\n searchPaths: string[];\n ignorePaths?: string[] | null;\n exclude?: string[] | null;\n platform: SupportedPlatform;\n silent?: boolean;\n nativeModulesDir?: string | null;\n\n // Scratched from project's config\n flags?: Record<string, any>;\n}\n\nexport interface ResolveOptions extends SearchOptions {\n json?: boolean;\n}\n\nexport interface GenerateOptions extends ResolveOptions {\n target: string;\n namespace?: string;\n empty?: boolean;\n}\n\nexport interface PatchReactImportsOptions {\n podsRoot: string;\n dryRun: boolean;\n}\n\nexport type PackageRevision = {\n path: string;\n version: string;\n config?: ExpoModuleConfig;\n duplicates?: PackageRevision[];\n};\n\nexport type SearchResults = {\n [moduleName: string]: PackageRevision;\n};\n\nexport interface ModuleAndroidProjectInfo {\n name: string;\n sourceDir: string;\n}\n\nexport interface ModuleDescriptorAndroid {\n packageName: string;\n projects: ModuleAndroidProjectInfo[];\n modules: string[];\n}\n\nexport interface ModuleIosPodspecInfo {\n podName: string;\n podspecDir: string;\n}\nexport interface ModuleDescriptorIos {\n packageName: string;\n pods: ModuleIosPodspecInfo[];\n flags: Record<string, any> | undefined;\n swiftModuleNames: string[];\n modules: string[];\n appDelegateSubscribers: string[];\n reactDelegateHandlers: string[];\n debugOnly: boolean;\n}\n\nexport type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;\n\n/**\n * Represents a raw config from `expo-module.json`.\n */\nexport interface RawExpoModuleConfig {\n /**\n * An array of supported platforms.\n */\n platforms?: SupportedPlatform[];\n\n /**\n * iOS-specific config.\n */\n ios?: {\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n */\n modules?: string[];\n\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.\n */\n appDelegateSubscribers?: string[];\n\n /**\n * Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.\n */\n reactDelegateHandlers?: string[];\n\n /**\n * Podspec relative path.\n * To have multiple podspecs, string array type is also supported.\n */\n podspecPath?: string | string[];\n\n /**\n * Swift product module name. If empty, the pod name is used for Swift imports.\n * To have multiple modules, string array is also supported.\n */\n swiftModuleName?: string | string[];\n\n /**\n * Whether this module will be added only to the debug configuration.\n * Defaults to false.\n */\n debugOnly?: boolean;\n };\n\n /**\n * Android-specific config.\n */\n android?: {\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n */\n modules?: string[];\n\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * build.gradle relative path.\n * To have multiple build.gradle projects, string array type is also supported.\n */\n gradlePath?: string | string[];\n };\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ExpoModuleConfig } from './ExpoModuleConfig';\n\nexport type SupportedPlatform = 'ios' | 'android' | 'web';\n\nexport interface SearchOptions {\n // Available in the CLI\n searchPaths: string[];\n ignorePaths?: string[] | null;\n exclude?: string[] | null;\n platform: SupportedPlatform;\n silent?: boolean;\n nativeModulesDir?: string | null;\n\n // Scratched from project's config\n flags?: Record<string, any>;\n}\n\nexport interface ResolveOptions extends SearchOptions {\n json?: boolean;\n}\n\nexport interface GenerateOptions extends ResolveOptions {\n target: string;\n namespace?: string;\n empty?: boolean;\n}\n\nexport interface PatchReactImportsOptions {\n podsRoot: string;\n dryRun: boolean;\n}\n\nexport type PackageRevision = {\n path: string;\n version: string;\n config?: ExpoModuleConfig;\n duplicates?: PackageRevision[];\n};\n\nexport type SearchResults = {\n [moduleName: string]: PackageRevision;\n};\n\nexport interface ModuleAndroidProjectInfo {\n name: string;\n sourceDir: string;\n}\n\nexport interface ModuleAndroidPluginInfo {\n id: string;\n sourceDir: string;\n}\n\nexport interface ModuleDescriptorAndroid {\n packageName: string;\n projects: ModuleAndroidProjectInfo[];\n plugins?: ModuleAndroidPluginInfo[];\n modules: string[];\n}\n\nexport interface ModuleIosPodspecInfo {\n podName: string;\n podspecDir: string;\n}\nexport interface ModuleDescriptorIos {\n packageName: string;\n pods: ModuleIosPodspecInfo[];\n flags: Record<string, any> | undefined;\n swiftModuleNames: string[];\n modules: string[];\n appDelegateSubscribers: string[];\n reactDelegateHandlers: string[];\n debugOnly: boolean;\n}\n\nexport type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;\n\nexport interface AndroidGradlePluginDescriptor {\n /**\n * Gradle plugin ID\n */\n id: string;\n\n /**\n * Artifact group\n */\n group: string;\n\n /**\n * Relative path to the gradle plugin directory\n */\n sourceDir: string;\n}\n\n/**\n * Represents a raw config from `expo-module.json`.\n */\nexport interface RawExpoModuleConfig {\n /**\n * An array of supported platforms.\n */\n platforms?: SupportedPlatform[];\n\n /**\n * iOS-specific config.\n */\n ios?: {\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n */\n modules?: string[];\n\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.\n */\n appDelegateSubscribers?: string[];\n\n /**\n * Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.\n */\n reactDelegateHandlers?: string[];\n\n /**\n * Podspec relative path.\n * To have multiple podspecs, string array type is also supported.\n */\n podspecPath?: string | string[];\n\n /**\n * Swift product module name. If empty, the pod name is used for Swift imports.\n * To have multiple modules, string array is also supported.\n */\n swiftModuleName?: string | string[];\n\n /**\n * Whether this module will be added only to the debug configuration.\n * Defaults to false.\n */\n debugOnly?: boolean;\n };\n\n /**\n * Android-specific config.\n */\n android?: {\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n */\n modules?: string[];\n\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * build.gradle relative path.\n * To have multiple build.gradle projects, string array type is also supported.\n */\n gradlePath?: string | string[];\n\n /**\n * Gradle plugins.\n */\n gradlePlugins?: AndroidGradlePluginDescriptor[];\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-autolinking",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Scripts that autolink Expo modules.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -48,5 +48,5 @@
48
48
  "find-up": "^5.0.0",
49
49
  "fs-extra": "^9.1.0"
50
50
  },
51
- "gitHead": "1f8a6a09570fd451378565ca34933018ce48454e"
51
+ "gitHead": "362ed24e78a57e9839afd2925d2af4aff7e28437"
52
52
  }
@@ -16,6 +16,24 @@ class ExpoModuleGradleProject {
16
16
  }
17
17
  }
18
18
 
19
+ // Object representing a gradle plugin
20
+ class ExpoModuleGradlePlugin {
21
+ // ID of the gradle plugin
22
+ String id
23
+
24
+ // Artifact group
25
+ String group
26
+
27
+ // Path to the plugin folder
28
+ String sourceDir
29
+
30
+ ExpoModuleGradlePlugin(Object data) {
31
+ this.id = data.id
32
+ this.group = data.group
33
+ this.sourceDir = data.sourceDir
34
+ }
35
+ }
36
+
19
37
  // Object representing a module.
20
38
  class ExpoModule {
21
39
  // Name of the JavaScript package
@@ -27,10 +45,14 @@ class ExpoModule {
27
45
  // Gradle projects
28
46
  ExpoModuleGradleProject[] projects
29
47
 
48
+ // Gradle plugins
49
+ ExpoModuleGradlePlugin[] plugins
50
+
30
51
  ExpoModule(Object data) {
31
52
  this.name = data.packageName
32
53
  this.version = data.packageVersion
33
54
  this.projects = data.projects.collect { new ExpoModuleGradleProject(it) }
55
+ this.plugins = data.plugins.collect { new ExpoModuleGradlePlugin(it) }
34
56
  }
35
57
  }
36
58
 
@@ -108,6 +130,7 @@ class ExpoAutolinkingManager {
108
130
  static private String[] convertOptionsToCommandArgs(String command, Map options) {
109
131
  String[] args = [
110
132
  'node',
133
+ '--no-warnings',
111
134
  '--eval',
112
135
  'require(\'expo-modules-autolinking\')(process.argv.slice(1))',
113
136
  '--',
@@ -137,12 +160,16 @@ class ExpoAutolinkingManager {
137
160
 
138
161
  class Colors {
139
162
  static final String GREEN = "\u001B[32m"
163
+ static final String YELLOW = "\u001B[33m"
140
164
  static final String RESET = "\u001B[0m"
141
165
  }
166
+ class Emojis {
167
+ static final String INFORMATION = "\u2139\uFE0F"
168
+ }
142
169
 
143
- // We can't cast a manager that is created in `settings.gradle` to the `ExpoAutolinkingManager`
144
- // because if someone is using `buildSrc`, the `ExpoAutolinkingManager` class
145
- // will be loaded by two different class loader - `settings.gradle` will use a diffrent loader.
170
+ // We can't cast a manager that is created in `settings.gradle` to the `ExpoAutolinkingManager`
171
+ // because if someone is using `buildSrc`, the `ExpoAutolinkingManager` class
172
+ // will be loaded by two different class loader - `settings.gradle` will use a diffrent loader.
146
173
  // In the JVM, classes are equal only if were loaded by the same loader.
147
174
  // There is nothing that we can do in that case, but to make our code safer, we check if the class name is the same.
148
175
  def validateExpoAutolinkingManager(manager) {
@@ -165,6 +192,33 @@ if (rootProject instanceof ProjectDescriptor) {
165
192
  include(":${moduleProject.name}")
166
193
  project(":${moduleProject.name}").projectDir = new File(moduleProject.sourceDir)
167
194
  }
195
+ for (modulePlugin in module.plugins) {
196
+ includeBuild(new File(modulePlugin.sourceDir))
197
+ }
198
+ }
199
+
200
+ // Add plugin classpath to the root project
201
+ gradle.beforeProject { project ->
202
+ if (project === project.rootProject) {
203
+ for (module in modules) {
204
+ for (modulePlugin in module.plugins) {
205
+ project.buildscript.dependencies.add('classpath', "${modulePlugin.group}:${modulePlugin.id}")
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ // Apply plugins for all app projects
212
+ gradle.afterProject { project ->
213
+ if (!project.plugins.hasPlugin('com.android.application')) {
214
+ return
215
+ }
216
+ for (module in modules) {
217
+ for (modulePlugin in module.plugins) {
218
+ println " ${Emojis.INFORMATION} ${Colors.YELLOW}Applying gradle plugin${Colors.RESET} '${Colors.GREEN}${modulePlugin.id}${Colors.RESET}' (${module.name}@${module.version})"
219
+ project.plugins.apply(modulePlugin.id)
220
+ }
221
+ }
168
222
  }
169
223
 
170
224
  // Save the manager in the shared context, so that we can later use it in `build.gradle`.
@@ -250,7 +304,7 @@ if (rootProject instanceof ProjectDescriptor) {
250
304
  ExpoAutolinkingManager.generatePackageList(project, options)
251
305
  }
252
306
 
253
- ext.ensureDependeciesWereEvaluated = { Project project ->
307
+ ext.ensureDependeciesWereEvaluated = { Project project ->
254
308
  if (!gradle.ext.has('expoAutolinkingManager')) {
255
309
  return
256
310
  }
@@ -268,7 +322,7 @@ if (rootProject instanceof ProjectDescriptor) {
268
322
  if (moduleProject.name == project.name) {
269
323
  continue
270
324
  }
271
-
325
+
272
326
  project.evaluationDependsOn(":${moduleProject.name}")
273
327
  }
274
328
  }
@@ -133,6 +133,7 @@ module Expo
133
133
 
134
134
  args = [
135
135
  'node',
136
+ '--no-warnings',
136
137
  '--eval',
137
138
  'require(\'expo-modules-autolinking\')(process.argv.slice(1))',
138
139
  command_name,
@@ -12,6 +12,7 @@ module Expo
12
12
  public def run!
13
13
  args = [
14
14
  'node',
15
+ '--no-warnings',
15
16
  '--eval',
16
17
  'require(\'expo-modules-autolinking\')(process.argv.slice(1))',
17
18
  'patch-react-imports',
@@ -1,4 +1,4 @@
1
- import { RawExpoModuleConfig, SupportedPlatform } from './types';
1
+ import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';
2
2
 
3
3
  function arrayize<T>(value: T[] | T | undefined): T[] {
4
4
  if (Array.isArray(value)) {
@@ -82,6 +82,13 @@ export class ExpoModuleConfig {
82
82
  return arrayize(this.rawConfig.android?.gradlePath ?? []);
83
83
  }
84
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
+
85
92
  /**
86
93
  * Returns serializable raw config.
87
94
  */
@@ -58,9 +58,18 @@ export async function resolveModuleAsync(
58
58
  };
59
59
  });
60
60
 
61
+ const plugins = (revision.config?.androidGradlePlugins() ?? []).map(
62
+ ({ id, group, sourceDir }) => ({
63
+ id,
64
+ group,
65
+ sourceDir: path.join(revision.path, sourceDir),
66
+ })
67
+ );
68
+
61
69
  return {
62
70
  packageName,
63
71
  projects,
72
+ ...(plugins.length > 0 ? { plugins } : {}),
64
73
  modules: revision.config?.androidModules() ?? [],
65
74
  };
66
75
  }
package/src/types.ts CHANGED
@@ -46,9 +46,15 @@ export interface ModuleAndroidProjectInfo {
46
46
  sourceDir: string;
47
47
  }
48
48
 
49
+ export interface ModuleAndroidPluginInfo {
50
+ id: string;
51
+ sourceDir: string;
52
+ }
53
+
49
54
  export interface ModuleDescriptorAndroid {
50
55
  packageName: string;
51
56
  projects: ModuleAndroidProjectInfo[];
57
+ plugins?: ModuleAndroidPluginInfo[];
52
58
  modules: string[];
53
59
  }
54
60
 
@@ -69,6 +75,23 @@ export interface ModuleDescriptorIos {
69
75
 
70
76
  export type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;
71
77
 
78
+ export interface AndroidGradlePluginDescriptor {
79
+ /**
80
+ * Gradle plugin ID
81
+ */
82
+ id: string;
83
+
84
+ /**
85
+ * Artifact group
86
+ */
87
+ group: string;
88
+
89
+ /**
90
+ * Relative path to the gradle plugin directory
91
+ */
92
+ sourceDir: string;
93
+ }
94
+
72
95
  /**
73
96
  * Represents a raw config from `expo-module.json`.
74
97
  */
@@ -142,5 +165,10 @@ export interface RawExpoModuleConfig {
142
165
  * To have multiple build.gradle projects, string array type is also supported.
143
166
  */
144
167
  gradlePath?: string | string[];
168
+
169
+ /**
170
+ * Gradle plugins.
171
+ */
172
+ gradlePlugins?: AndroidGradlePluginDescriptor[];
145
173
  };
146
174
  }