expo-modules-autolinking 1.1.2 → 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,12 @@
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
+
13
19
  ## 1.1.2 — 2023-02-14
14
20
 
15
21
  ### 💡 Others
@@ -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":"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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 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.2",
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": "c8107d57eabaedff5d53bc8036d062db12a473c8"
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
 
@@ -138,12 +160,16 @@ class ExpoAutolinkingManager {
138
160
 
139
161
  class Colors {
140
162
  static final String GREEN = "\u001B[32m"
163
+ static final String YELLOW = "\u001B[33m"
141
164
  static final String RESET = "\u001B[0m"
142
165
  }
166
+ class Emojis {
167
+ static final String INFORMATION = "\u2139\uFE0F"
168
+ }
143
169
 
144
- // We can't cast a manager that is created in `settings.gradle` to the `ExpoAutolinkingManager`
145
- // because if someone is using `buildSrc`, the `ExpoAutolinkingManager` class
146
- // 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.
147
173
  // In the JVM, classes are equal only if were loaded by the same loader.
148
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.
149
175
  def validateExpoAutolinkingManager(manager) {
@@ -166,6 +192,33 @@ if (rootProject instanceof ProjectDescriptor) {
166
192
  include(":${moduleProject.name}")
167
193
  project(":${moduleProject.name}").projectDir = new File(moduleProject.sourceDir)
168
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
+ }
169
222
  }
170
223
 
171
224
  // Save the manager in the shared context, so that we can later use it in `build.gradle`.
@@ -251,7 +304,7 @@ if (rootProject instanceof ProjectDescriptor) {
251
304
  ExpoAutolinkingManager.generatePackageList(project, options)
252
305
  }
253
306
 
254
- ext.ensureDependeciesWereEvaluated = { Project project ->
307
+ ext.ensureDependeciesWereEvaluated = { Project project ->
255
308
  if (!gradle.ext.has('expoAutolinkingManager')) {
256
309
  return
257
310
  }
@@ -269,7 +322,7 @@ if (rootProject instanceof ProjectDescriptor) {
269
322
  if (moduleProject.name == project.name) {
270
323
  continue
271
324
  }
272
-
325
+
273
326
  project.evaluationDependsOn(":${moduleProject.name}")
274
327
  }
275
328
  }
@@ -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
  }