expo-modules-autolinking 0.3.1 → 0.4.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 ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ ## Unpublished
4
+
5
+ ### 🛠 Breaking changes
6
+
7
+ ### 🎉 New features
8
+
9
+ ### 🐛 Bug fixes
10
+
11
+ ### 💡 Others
12
+
13
+ ## 0.4.0 — 2021-11-17
14
+
15
+ ### 🎉 New features
16
+
17
+ - Added "silent" property for silencing resolution warnings. ([#14891](https://github.com/expo/expo/pull/14891) by [@EvanBacon](https://github.com/EvanBacon))
18
+ - Listing module's app delegate subscribers in the generated `ExpoModulesProvider.swift`. ([#14867](https://github.com/expo/expo/pull/14867) by [@tsapeta](https://github.com/tsapeta))
19
+ - Search for Android package in the entire source code other than just `src` directory. ([#14883](https://github.com/expo/expo/pull/14883) by [@kudo](https://github.com/kudo))
20
+
21
+ ### 🐛 Bug fixes
22
+
23
+ - Fix Gradle error when running Gradle from outside of the project directory. ([#15109](https://github.com/expo/expo/pull/15109) by [@kudo](https://github.com/kudo))
24
+
25
+ ## 0.3.3 — 2021-10-21
26
+
27
+ ### 🐛 Bug fixes
28
+
29
+ - Resolved race condition when generating `ExpoModulesProvider.swift`. ([#14822](https://github.com/expo/expo/pull/14822) by [@awinograd](https://github.com/awinograd))
package/README.md CHANGED
@@ -13,7 +13,7 @@ For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-
13
13
 
14
14
  # Installation in bare React Native projects
15
15
 
16
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
17
 
18
18
  ### Add the package to your npm dependencies
19
19
 
@@ -13,6 +13,14 @@ export declare class ExpoModuleConfig {
13
13
  * Returns a list of names of Swift native modules classes to put to the generated modules provider file.
14
14
  */
15
15
  iosModulesClassNames(): string[];
16
+ /**
17
+ * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.
18
+ */
19
+ iosAppDelegateSubscribers(): string[];
20
+ /**
21
+ * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
22
+ */
23
+ androidModulesClassNames(): string[];
16
24
  /**
17
25
  * Returns serializable raw config.
18
26
  */
@@ -22,6 +22,20 @@ class ExpoModuleConfig {
22
22
  var _a, _b;
23
23
  return (_b = (_a = this.rawConfig.ios) === null || _a === void 0 ? void 0 : _a.modulesClassNames) !== null && _b !== void 0 ? _b : [];
24
24
  }
25
+ /**
26
+ * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.
27
+ */
28
+ iosAppDelegateSubscribers() {
29
+ var _a, _b;
30
+ return (_b = (_a = this.rawConfig.ios) === null || _a === void 0 ? void 0 : _a.appDelegateSubscribers) !== null && _b !== void 0 ? _b : [];
31
+ }
32
+ /**
33
+ * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
34
+ */
35
+ androidModulesClassNames() {
36
+ var _a, _b;
37
+ return (_b = (_a = this.rawConfig.android) === null || _a === void 0 ? void 0 : _a.modulesClassNames) !== null && _b !== void 0 ? _b : [];
38
+ }
25
39
  /**
26
40
  * Returns serializable raw config.
27
41
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;;QAC1C,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,SAAS,0CAAE,QAAQ,CAAC,QAAQ,CAAC,mCAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,oBAAoB;;QAClB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AAvBD,4CAuBC;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\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 iosModulesClassNames() {\n return this.rawConfig.ios?.modulesClassNames ?? [];\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;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;;QAC1C,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,SAAS,0CAAE,QAAQ,CAAC,QAAQ,CAAC,mCAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,oBAAoB;;QAClB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,yBAAyB;;QACvB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,sBAAsB,mCAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;;QACtB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,OAAO,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AArCD,4CAqCC;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\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 iosModulesClassNames() {\n return this.rawConfig.ios?.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 Kotlin native modules classes to put to the generated package provider file.\n */\n androidModulesClassNames() {\n return this.rawConfig.android?.modulesClassNames ?? [];\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"]}
@@ -25,7 +25,7 @@ if (!projectPackageJsonPath) {
25
25
  * Custom `require` that resolves from the current working dir instead of this script path.
26
26
  * **Requires Node v12.2.0**
27
27
  */
28
- const projectRequire = module_1.createRequire(projectPackageJsonPath);
28
+ const projectRequire = (0, module_1.createRequire)(projectPackageJsonPath);
29
29
  /**
30
30
  * Resolves autolinking search paths. If none is provided, it accumulates all node_modules when
31
31
  * going up through the path components. This makes workspaces work out-of-the-box without any configs.
@@ -43,7 +43,7 @@ async function findDefaultPathsAsync(cwd) {
43
43
  const paths = [];
44
44
  let dir = cwd;
45
45
  let pkgJsonPath;
46
- while ((pkgJsonPath = await find_up_1.default('package.json', { cwd: dir }))) {
46
+ while ((pkgJsonPath = await (0, find_up_1.default)('package.json', { cwd: dir }))) {
47
47
  dir = path_1.default.dirname(path_1.default.dirname(pkgJsonPath));
48
48
  paths.push(path_1.default.join(pkgJsonPath, '..', 'node_modules'));
49
49
  }
@@ -59,7 +59,7 @@ async function findModulesAsync(providedOptions) {
59
59
  const results = {};
60
60
  for (const searchPath of options.searchPaths) {
61
61
  const bracedFilenames = '{' + EXPO_MODULE_CONFIG_FILENAMES.join(',') + '}';
62
- const paths = await fast_glob_1.default([`*/${bracedFilenames}`, `@*/*/${bracedFilenames}`], {
62
+ const paths = await (0, fast_glob_1.default)([`*/${bracedFilenames}`, `@*/*/${bracedFilenames}`], {
63
63
  cwd: searchPath,
64
64
  });
65
65
  // If the package has multiple configs (e.g. `unimodule.json` and `expo-module.config.json` during the transition time)
@@ -73,7 +73,7 @@ async function findModulesAsync(providedOptions) {
73
73
  }, {}));
74
74
  for (const packageConfigPath of uniqueConfigPaths) {
75
75
  const packagePath = await fs_extra_1.default.realpath(path_1.default.join(searchPath, path_1.default.dirname(packageConfigPath)));
76
- const expoModuleConfig = ExpoModuleConfig_1.requireAndResolveExpoModuleConfig(path_1.default.join(packagePath, path_1.default.basename(packageConfigPath)));
76
+ const expoModuleConfig = (0, ExpoModuleConfig_1.requireAndResolveExpoModuleConfig)(path_1.default.join(packagePath, path_1.default.basename(packageConfigPath)));
77
77
  const { name, version } = require(path_1.default.join(packagePath, 'package.json'));
78
78
  if (((_a = options.exclude) === null || _a === void 0 ? void 0 : _a.includes(name)) || !expoModuleConfig.supportsPlatform(options.platform)) {
79
79
  continue;
@@ -103,13 +103,13 @@ async function findModulesAsync(providedOptions) {
103
103
  if (options.searchPaths.length <= 1) {
104
104
  return results;
105
105
  }
106
- return filterToProjectDependencies(results);
106
+ return filterToProjectDependencies(results, providedOptions);
107
107
  }
108
108
  exports.findModulesAsync = findModulesAsync;
109
109
  /**
110
110
  * Filters out packages that are not the dependencies of the project.
111
111
  */
112
- function filterToProjectDependencies(results) {
112
+ function filterToProjectDependencies(results, options = {}) {
113
113
  const filteredResults = {};
114
114
  const visitedPackages = new Set();
115
115
  // Helper for traversing the dependency hierarchy.
@@ -137,7 +137,7 @@ function filterToProjectDependencies(results) {
137
137
  // Some packages don't include package.json in its `exports` field,
138
138
  // but none of our packages do that, so it seems fine to just ignore that type of error.
139
139
  // Related issue: https://github.com/react-native-community/cli/issues/1168
140
- if (error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
140
+ if (!options.silent && error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
141
141
  console.warn(chalk_1.default.yellow(`⚠️ Cannot resolve the path to "${dependencyName}" package.`));
142
142
  }
143
143
  continue;
@@ -224,6 +224,7 @@ async function generatePackageListAsync(modules, options) {
224
224
  }
225
225
  catch (e) {
226
226
  console.error(chalk_1.default.red(`Generating package list is not available for platform: ${options.platform}`));
227
+ throw e;
227
228
  }
228
229
  }
229
230
  exports.generatePackageListAsync = generatePackageListAsync;
@@ -1 +1 @@
1
- {"version":3,"file":"autolinking.js","sourceRoot":"","sources":["../src/autolinking.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport glob from 'fast-glob';\nimport findUp from 'find-up';\nimport fs from 'fs-extra';\nimport { createRequire } from 'module';\nimport path from 'path';\n\nimport { requireAndResolveExpoModuleConfig } from './ExpoModuleConfig';\nimport {\n GenerateOptions,\n ModuleDescriptor,\n PackageRevision,\n ResolveOptions,\n SearchOptions,\n SearchResults,\n} from './types';\n\n// Names of the config files. From lowest to highest priority.\nconst EXPO_MODULE_CONFIG_FILENAMES = ['unimodule.json', 'expo-module.config.json'];\n\n/**\n * Path to the `package.json` of the closest project in the current working dir.\n */\nconst projectPackageJsonPath = findUp.sync('package.json', { cwd: process.cwd() }) as string;\n\n// This won't happen in usual scenarios, but we need to unwrap the optional path :)\nif (!projectPackageJsonPath) {\n throw new Error(`Couldn't find \"package.json\" up from path \"${process.cwd()}\"`);\n}\n\n/**\n * Custom `require` that resolves from the current working dir instead of this script path.\n * **Requires Node v12.2.0**\n */\nconst projectRequire = createRequire(projectPackageJsonPath);\n\n/**\n * Resolves autolinking search paths. If none is provided, it accumulates all node_modules when\n * going up through the path components. This makes workspaces work out-of-the-box without any configs.\n */\nexport async function resolveSearchPathsAsync(\n searchPaths: string[] | null,\n cwd: string\n): Promise<string[]> {\n return searchPaths && searchPaths.length > 0\n ? searchPaths.map((searchPath) => path.resolve(cwd, searchPath))\n : await findDefaultPathsAsync(cwd);\n}\n\n/**\n * Looks up for workspace's `node_modules` paths.\n */\nexport async function findDefaultPathsAsync(cwd: string): Promise<string[]> {\n const paths = [];\n let dir = cwd;\n let pkgJsonPath: string | undefined;\n\n while ((pkgJsonPath = await findUp('package.json', { cwd: dir }))) {\n dir = path.dirname(path.dirname(pkgJsonPath));\n paths.push(path.join(pkgJsonPath, '..', 'node_modules'));\n }\n return paths;\n}\n\n/**\n * Searches for modules to link based on given config.\n */\nexport async function findModulesAsync(providedOptions: SearchOptions): Promise<SearchResults> {\n const options = await mergeLinkingOptionsAsync(providedOptions);\n const results: SearchResults = {};\n\n for (const searchPath of options.searchPaths) {\n const bracedFilenames = '{' + EXPO_MODULE_CONFIG_FILENAMES.join(',') + '}';\n const paths = await glob([`*/${bracedFilenames}`, `@*/*/${bracedFilenames}`], {\n cwd: searchPath,\n });\n\n // If the package has multiple configs (e.g. `unimodule.json` and `expo-module.config.json` during the transition time)\n // then we want to give `expo-module.config.json` the priority.\n const uniqueConfigPaths: string[] = Object.values(\n paths.reduce<Record<string, string>>((acc, configPath) => {\n const dirname = path.dirname(configPath);\n\n if (!acc[dirname] || configPriority(configPath) > configPriority(acc[dirname])) {\n acc[dirname] = configPath;\n }\n return acc;\n }, {})\n );\n\n for (const packageConfigPath of uniqueConfigPaths) {\n const packagePath = await fs.realpath(path.join(searchPath, path.dirname(packageConfigPath)));\n const expoModuleConfig = requireAndResolveExpoModuleConfig(\n path.join(packagePath, path.basename(packageConfigPath))\n );\n const { name, version } = require(path.join(packagePath, 'package.json'));\n\n if (options.exclude?.includes(name) || !expoModuleConfig.supportsPlatform(options.platform)) {\n continue;\n }\n\n const currentRevision: PackageRevision = {\n path: packagePath,\n version,\n };\n\n if (!results[name]) {\n // The revision that was found first will be the main one.\n // An array of duplicates and the config are needed only here.\n results[name] = {\n ...currentRevision,\n config: expoModuleConfig,\n duplicates: [],\n };\n } else if (\n results[name].path !== packagePath &&\n results[name].duplicates?.every(({ path }) => path !== packagePath)\n ) {\n results[name].duplicates?.push(currentRevision);\n }\n }\n }\n\n // It doesn't make much sense to strip modules if there is only one search path.\n // Workspace root usually doesn't specify all its dependencies (see Expo Go),\n // so in this case we should link everything.\n if (options.searchPaths.length <= 1) {\n return results;\n }\n return filterToProjectDependencies(results);\n}\n\n/**\n * Filters out packages that are not the dependencies of the project.\n */\nfunction filterToProjectDependencies(results: SearchResults) {\n const filteredResults: SearchResults = {};\n const visitedPackages = new Set<string>();\n\n // Helper for traversing the dependency hierarchy.\n function visitPackage(packageJsonPath: string) {\n const packageJson = require(packageJsonPath);\n\n // Prevent getting into the recursive loop.\n if (visitedPackages.has(packageJson.name)) {\n return;\n }\n visitedPackages.add(packageJson.name);\n\n // Iterate over the dependencies to find transitive modules.\n for (const dependencyName in packageJson.dependencies) {\n const dependencyResult = results[dependencyName];\n\n if (!filteredResults[dependencyName]) {\n let dependencyPackageJsonPath: string;\n\n if (dependencyResult) {\n filteredResults[dependencyName] = dependencyResult;\n dependencyPackageJsonPath = path.join(dependencyResult.path, 'package.json');\n } else {\n try {\n dependencyPackageJsonPath = projectRequire.resolve(`${dependencyName}/package.json`);\n } catch (error) {\n // Some packages don't include package.json in its `exports` field,\n // but none of our packages do that, so it seems fine to just ignore that type of error.\n // Related issue: https://github.com/react-native-community/cli/issues/1168\n if (error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {\n console.warn(\n chalk.yellow(`⚠️ Cannot resolve the path to \"${dependencyName}\" package.`)\n );\n }\n continue;\n }\n }\n\n // Visit the dependency package.\n visitPackage(dependencyPackageJsonPath);\n }\n }\n }\n\n // Visit project's package.\n visitPackage(projectPackageJsonPath);\n\n return filteredResults;\n}\n\n/**\n * Merges autolinking options from different sources (the later the higher priority)\n * - options defined in package.json's `expoModules` field\n * - platform-specific options from the above (e.g. `expoModules.ios`)\n * - options provided to the CLI command\n */\nexport async function mergeLinkingOptionsAsync<OptionsType extends SearchOptions>(\n providedOptions: OptionsType\n): Promise<OptionsType> {\n const packageJson = require(projectPackageJsonPath);\n const baseOptions = packageJson.expo?.autolinking;\n const platformOptions = providedOptions.platform && baseOptions?.[providedOptions.platform];\n const finalOptions = Object.assign(\n {},\n baseOptions,\n platformOptions,\n providedOptions\n ) as OptionsType;\n\n // Makes provided paths absolute or falls back to default paths if none was provided.\n finalOptions.searchPaths = await resolveSearchPathsAsync(finalOptions.searchPaths, process.cwd());\n\n return finalOptions;\n}\n\n/**\n * Verifies the search results by checking whether there are no duplicates.\n */\nexport function verifySearchResults(searchResults: SearchResults): number {\n const cwd = process.cwd();\n const relativePath: (pkg: PackageRevision) => string = (pkg) => path.relative(cwd, pkg.path);\n let counter = 0;\n\n for (const moduleName in searchResults) {\n const revision = searchResults[moduleName];\n\n if (revision.duplicates?.length) {\n console.warn(`⚠️ Found multiple revisions of ${chalk.green(moduleName)}`);\n console.log(` - ${chalk.magenta(relativePath(revision))} (${chalk.cyan(revision.version)})`);\n\n for (const duplicate of revision.duplicates) {\n console.log(` - ${chalk.gray(relativePath(duplicate))} (${chalk.gray(duplicate.version)})`);\n }\n counter++;\n }\n }\n if (counter > 0) {\n console.warn(\n '⚠️ Please get rid of multiple revisions as it may introduce some side effects or compatibility issues'\n );\n }\n return counter;\n}\n\n/**\n * Resolves search results to a list of platform-specific configuration.\n */\nexport async function resolveModulesAsync(\n searchResults: SearchResults,\n options: ResolveOptions\n): Promise<ModuleDescriptor[]> {\n const platformLinking = require(`./platforms/${options.platform}`);\n\n return (\n await Promise.all(\n Object.entries(searchResults).map(async ([packageName, revision]) => {\n const resolvedModule = await platformLinking.resolveModuleAsync(\n packageName,\n revision,\n options\n );\n return resolvedModule\n ? {\n packageName,\n packageVersion: revision.version,\n ...resolvedModule,\n }\n : null;\n })\n )\n )\n .filter(Boolean)\n .sort((a, b) => a.packageName.localeCompare(b.packageName));\n}\n\n/**\n * Generates a source file listing all packages to link.\n * Right know it works only for Android platform.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n options: GenerateOptions\n) {\n try {\n const platformLinking = require(`./platforms/${options.platform}`);\n await platformLinking.generatePackageListAsync(modules, options.target, options.namespace);\n } catch (e) {\n console.error(\n chalk.red(`Generating package list is not available for platform: ${options.platform}`)\n );\n }\n}\n\n/**\n * Returns the priority of the config at given path. Higher number means higher priority.\n */\nfunction configPriority(fullpath: string): number {\n return EXPO_MODULE_CONFIG_FILENAMES.indexOf(path.basename(fullpath));\n}\n"]}
1
+ {"version":3,"file":"autolinking.js","sourceRoot":"","sources":["../src/autolinking.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,0DAA6B;AAC7B,sDAA6B;AAC7B,wDAA0B;AAC1B,mCAAuC;AACvC,gDAAwB;AAExB,yDAAuE;AAUvE,8DAA8D;AAC9D,MAAM,4BAA4B,GAAG,CAAC,gBAAgB,EAAE,yBAAyB,CAAC,CAAC;AAEnF;;GAEG;AACH,MAAM,sBAAsB,GAAG,iBAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAW,CAAC;AAE7F,mFAAmF;AACnF,IAAI,CAAC,sBAAsB,EAAE;IAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;CACjF;AAED;;;GAGG;AACH,MAAM,cAAc,GAAG,IAAA,sBAAa,EAAC,sBAAsB,CAAC,CAAC;AAE7D;;;GAGG;AACI,KAAK,UAAU,uBAAuB,CAC3C,WAA4B,EAC5B,GAAW;IAEX,OAAO,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAC1C,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAChE,CAAC,CAAC,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAPD,0DAOC;AAED;;GAEG;AACI,KAAK,UAAU,qBAAqB,CAAC,GAAW;IACrD,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,IAAI,WAA+B,CAAC;IAEpC,OAAO,CAAC,WAAW,GAAG,MAAM,IAAA,iBAAM,EAAC,cAAc,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE;QACjE,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;KAC1D;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAVD,sDAUC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB,CAAC,eAA8B;;IACnE,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,eAAe,CAAC,CAAC;IAChE,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE;QAC5C,MAAM,eAAe,GAAG,GAAG,GAAG,4BAA4B,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QAC3E,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAI,EAAC,CAAC,KAAK,eAAe,EAAE,EAAE,QAAQ,eAAe,EAAE,CAAC,EAAE;YAC5E,GAAG,EAAE,UAAU;SAChB,CAAC,CAAC;QAEH,uHAAuH;QACvH,+DAA+D;QAC/D,MAAM,iBAAiB,GAAa,MAAM,CAAC,MAAM,CAC/C,KAAK,CAAC,MAAM,CAAyB,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE;YACvD,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAEzC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE;gBAC9E,GAAG,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC;aAC3B;YACD,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAE,CAAC,CACP,CAAC;QAEF,KAAK,MAAM,iBAAiB,IAAI,iBAAiB,EAAE;YACjD,MAAM,WAAW,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YAC9F,MAAM,gBAAgB,GAAG,IAAA,oDAAiC,EACxD,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CACzD,CAAC;YACF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;YAE1E,IAAI,CAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,CAAC,IAAI,CAAC,KAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAC3F,SAAS;aACV;YAED,MAAM,eAAe,GAAoB;gBACvC,IAAI,EAAE,WAAW;gBACjB,OAAO;aACR,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAClB,0DAA0D;gBAC1D,8DAA8D;gBAC9D,OAAO,CAAC,IAAI,CAAC,GAAG;oBACd,GAAG,eAAe;oBAClB,MAAM,EAAE,gBAAgB;oBACxB,UAAU,EAAE,EAAE;iBACf,CAAC;aACH;iBAAM,IACL,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;iBAClC,MAAA,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,0CAAE,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA,EACnE;gBACA,MAAA,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,0CAAE,IAAI,CAAC,eAAe,CAAC,CAAC;aACjD;SACF;KACF;IAED,gFAAgF;IAChF,6EAA6E;IAC7E,6CAA6C;IAC7C,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE;QACnC,OAAO,OAAO,CAAC;KAChB;IACD,OAAO,2BAA2B,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAC/D,CAAC;AA/DD,4CA+DC;AAED;;GAEG;AACH,SAAS,2BAA2B,CAClC,OAAsB,EACtB,UAAyC,EAAE;IAE3C,MAAM,eAAe,GAAkB,EAAE,CAAC;IAC1C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE1C,kDAAkD;IAClD,SAAS,YAAY,CAAC,eAAuB;QAC3C,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAE7C,2CAA2C;QAC3C,IAAI,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YACzC,OAAO;SACR;QACD,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEtC,4DAA4D;QAC5D,KAAK,MAAM,cAAc,IAAI,WAAW,CAAC,YAAY,EAAE;YACrD,MAAM,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;YAEjD,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE;gBACpC,IAAI,yBAAiC,CAAC;gBAEtC,IAAI,gBAAgB,EAAE;oBACpB,eAAe,CAAC,cAAc,CAAC,GAAG,gBAAgB,CAAC;oBACnD,yBAAyB,GAAG,cAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;iBAC9E;qBAAM;oBACL,IAAI;wBACF,yBAAyB,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,cAAc,eAAe,CAAC,CAAC;qBACtF;oBAAC,OAAO,KAAU,EAAE;wBACnB,mEAAmE;wBACnE,wFAAwF;wBACxF,2EAA2E;wBAC3E,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,+BAA+B,EAAE;4BACrE,OAAO,CAAC,IAAI,CACV,eAAK,CAAC,MAAM,CAAC,mCAAmC,cAAc,YAAY,CAAC,CAC5E,CAAC;yBACH;wBACD,SAAS;qBACV;iBACF;gBAED,gCAAgC;gBAChC,YAAY,CAAC,yBAAyB,CAAC,CAAC;aACzC;SACF;IACH,CAAC;IAED,2BAA2B;IAC3B,YAAY,CAAC,sBAAsB,CAAC,CAAC;IAErC,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,wBAAwB,CAC5C,eAA4B;;IAE5B,MAAM,WAAW,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,MAAA,WAAW,CAAC,IAAI,0CAAE,WAAW,CAAC;IAClD,MAAM,eAAe,GAAG,eAAe,CAAC,QAAQ,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAG,eAAe,CAAC,QAAQ,CAAC,CAAA,CAAC;IAC5F,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAChC,EAAE,EACF,WAAW,EACX,eAAe,EACf,eAAe,CACD,CAAC;IAEjB,qFAAqF;IACrF,YAAY,CAAC,WAAW,GAAG,MAAM,uBAAuB,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAElG,OAAO,YAAY,CAAC;AACtB,CAAC;AAjBD,4DAiBC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,aAA4B;;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,YAAY,GAAqC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7F,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;QACtC,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,MAAA,QAAQ,CAAC,UAAU,0CAAE,MAAM,EAAE;YAC/B,OAAO,CAAC,IAAI,CAAC,mCAAmC,eAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC3E,OAAO,CAAC,GAAG,CAAC,MAAM,eAAK,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAE7F,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE;gBAC3C,OAAO,CAAC,GAAG,CAAC,MAAM,eAAK,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;aAC7F;YACD,OAAO,EAAE,CAAC;SACX;KACF;IACD,IAAI,OAAO,GAAG,CAAC,EAAE;QACf,OAAO,CAAC,IAAI,CACV,wGAAwG,CACzG,CAAC;KACH;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAxBD,kDAwBC;AAED;;GAEG;AACI,KAAK,UAAU,mBAAmB,CACvC,aAA4B,EAC5B,OAAuB;IAEvB,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEnE,OAAO,CACL,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;QAClE,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAC7D,WAAW,EACX,QAAQ,EACR,OAAO,CACR,CAAC;QACF,OAAO,cAAc;YACnB,CAAC,CAAC;gBACE,WAAW;gBACX,cAAc,EAAE,QAAQ,CAAC,OAAO;gBAChC,GAAG,cAAc;aAClB;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC,CACH,CACF;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE,CAAC;AA1BD,kDA0BC;AAED;;;GAGG;AACI,KAAK,UAAU,wBAAwB,CAC5C,OAA2B,EAC3B,OAAwB;IAExB,IAAI;QACF,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnE,MAAM,eAAe,CAAC,wBAAwB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;KAC5F;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CACX,eAAK,CAAC,GAAG,CAAC,0DAA0D,OAAO,CAAC,QAAQ,EAAE,CAAC,CACxF,CAAC;QACF,MAAM,CAAC,CAAC;KACT;AACH,CAAC;AAbD,4DAaC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,4BAA4B,CAAC,OAAO,CAAC,cAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACvE,CAAC","sourcesContent":["import chalk from 'chalk';\nimport glob from 'fast-glob';\nimport findUp from 'find-up';\nimport fs from 'fs-extra';\nimport { createRequire } from 'module';\nimport path from 'path';\n\nimport { requireAndResolveExpoModuleConfig } from './ExpoModuleConfig';\nimport {\n GenerateOptions,\n ModuleDescriptor,\n PackageRevision,\n ResolveOptions,\n SearchOptions,\n SearchResults,\n} from './types';\n\n// Names of the config files. From lowest to highest priority.\nconst EXPO_MODULE_CONFIG_FILENAMES = ['unimodule.json', 'expo-module.config.json'];\n\n/**\n * Path to the `package.json` of the closest project in the current working dir.\n */\nconst projectPackageJsonPath = findUp.sync('package.json', { cwd: process.cwd() }) as string;\n\n// This won't happen in usual scenarios, but we need to unwrap the optional path :)\nif (!projectPackageJsonPath) {\n throw new Error(`Couldn't find \"package.json\" up from path \"${process.cwd()}\"`);\n}\n\n/**\n * Custom `require` that resolves from the current working dir instead of this script path.\n * **Requires Node v12.2.0**\n */\nconst projectRequire = createRequire(projectPackageJsonPath);\n\n/**\n * Resolves autolinking search paths. If none is provided, it accumulates all node_modules when\n * going up through the path components. This makes workspaces work out-of-the-box without any configs.\n */\nexport async function resolveSearchPathsAsync(\n searchPaths: string[] | null,\n cwd: string\n): Promise<string[]> {\n return searchPaths && searchPaths.length > 0\n ? searchPaths.map((searchPath) => path.resolve(cwd, searchPath))\n : await findDefaultPathsAsync(cwd);\n}\n\n/**\n * Looks up for workspace's `node_modules` paths.\n */\nexport async function findDefaultPathsAsync(cwd: string): Promise<string[]> {\n const paths = [];\n let dir = cwd;\n let pkgJsonPath: string | undefined;\n\n while ((pkgJsonPath = await findUp('package.json', { cwd: dir }))) {\n dir = path.dirname(path.dirname(pkgJsonPath));\n paths.push(path.join(pkgJsonPath, '..', 'node_modules'));\n }\n return paths;\n}\n\n/**\n * Searches for modules to link based on given config.\n */\nexport async function findModulesAsync(providedOptions: SearchOptions): Promise<SearchResults> {\n const options = await mergeLinkingOptionsAsync(providedOptions);\n const results: SearchResults = {};\n\n for (const searchPath of options.searchPaths) {\n const bracedFilenames = '{' + EXPO_MODULE_CONFIG_FILENAMES.join(',') + '}';\n const paths = await glob([`*/${bracedFilenames}`, `@*/*/${bracedFilenames}`], {\n cwd: searchPath,\n });\n\n // If the package has multiple configs (e.g. `unimodule.json` and `expo-module.config.json` during the transition time)\n // then we want to give `expo-module.config.json` the priority.\n const uniqueConfigPaths: string[] = Object.values(\n paths.reduce<Record<string, string>>((acc, configPath) => {\n const dirname = path.dirname(configPath);\n\n if (!acc[dirname] || configPriority(configPath) > configPriority(acc[dirname])) {\n acc[dirname] = configPath;\n }\n return acc;\n }, {})\n );\n\n for (const packageConfigPath of uniqueConfigPaths) {\n const packagePath = await fs.realpath(path.join(searchPath, path.dirname(packageConfigPath)));\n const expoModuleConfig = requireAndResolveExpoModuleConfig(\n path.join(packagePath, path.basename(packageConfigPath))\n );\n const { name, version } = require(path.join(packagePath, 'package.json'));\n\n if (options.exclude?.includes(name) || !expoModuleConfig.supportsPlatform(options.platform)) {\n continue;\n }\n\n const currentRevision: PackageRevision = {\n path: packagePath,\n version,\n };\n\n if (!results[name]) {\n // The revision that was found first will be the main one.\n // An array of duplicates and the config are needed only here.\n results[name] = {\n ...currentRevision,\n config: expoModuleConfig,\n duplicates: [],\n };\n } else if (\n results[name].path !== packagePath &&\n results[name].duplicates?.every(({ path }) => path !== packagePath)\n ) {\n results[name].duplicates?.push(currentRevision);\n }\n }\n }\n\n // It doesn't make much sense to strip modules if there is only one search path.\n // Workspace root usually doesn't specify all its dependencies (see Expo Go),\n // so in this case we should link everything.\n if (options.searchPaths.length <= 1) {\n return results;\n }\n return filterToProjectDependencies(results, providedOptions);\n}\n\n/**\n * Filters out packages that are not the dependencies of the project.\n */\nfunction filterToProjectDependencies(\n results: SearchResults,\n options: Pick<SearchOptions, 'silent'> = {}\n) {\n const filteredResults: SearchResults = {};\n const visitedPackages = new Set<string>();\n\n // Helper for traversing the dependency hierarchy.\n function visitPackage(packageJsonPath: string) {\n const packageJson = require(packageJsonPath);\n\n // Prevent getting into the recursive loop.\n if (visitedPackages.has(packageJson.name)) {\n return;\n }\n visitedPackages.add(packageJson.name);\n\n // Iterate over the dependencies to find transitive modules.\n for (const dependencyName in packageJson.dependencies) {\n const dependencyResult = results[dependencyName];\n\n if (!filteredResults[dependencyName]) {\n let dependencyPackageJsonPath: string;\n\n if (dependencyResult) {\n filteredResults[dependencyName] = dependencyResult;\n dependencyPackageJsonPath = path.join(dependencyResult.path, 'package.json');\n } else {\n try {\n dependencyPackageJsonPath = projectRequire.resolve(`${dependencyName}/package.json`);\n } catch (error: any) {\n // Some packages don't include package.json in its `exports` field,\n // but none of our packages do that, so it seems fine to just ignore that type of error.\n // Related issue: https://github.com/react-native-community/cli/issues/1168\n if (!options.silent && error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {\n console.warn(\n chalk.yellow(`⚠️ Cannot resolve the path to \"${dependencyName}\" package.`)\n );\n }\n continue;\n }\n }\n\n // Visit the dependency package.\n visitPackage(dependencyPackageJsonPath);\n }\n }\n }\n\n // Visit project's package.\n visitPackage(projectPackageJsonPath);\n\n return filteredResults;\n}\n\n/**\n * Merges autolinking options from different sources (the later the higher priority)\n * - options defined in package.json's `expoModules` field\n * - platform-specific options from the above (e.g. `expoModules.ios`)\n * - options provided to the CLI command\n */\nexport async function mergeLinkingOptionsAsync<OptionsType extends SearchOptions>(\n providedOptions: OptionsType\n): Promise<OptionsType> {\n const packageJson = require(projectPackageJsonPath);\n const baseOptions = packageJson.expo?.autolinking;\n const platformOptions = providedOptions.platform && baseOptions?.[providedOptions.platform];\n const finalOptions = Object.assign(\n {},\n baseOptions,\n platformOptions,\n providedOptions\n ) as OptionsType;\n\n // Makes provided paths absolute or falls back to default paths if none was provided.\n finalOptions.searchPaths = await resolveSearchPathsAsync(finalOptions.searchPaths, process.cwd());\n\n return finalOptions;\n}\n\n/**\n * Verifies the search results by checking whether there are no duplicates.\n */\nexport function verifySearchResults(searchResults: SearchResults): number {\n const cwd = process.cwd();\n const relativePath: (pkg: PackageRevision) => string = (pkg) => path.relative(cwd, pkg.path);\n let counter = 0;\n\n for (const moduleName in searchResults) {\n const revision = searchResults[moduleName];\n\n if (revision.duplicates?.length) {\n console.warn(`⚠️ Found multiple revisions of ${chalk.green(moduleName)}`);\n console.log(` - ${chalk.magenta(relativePath(revision))} (${chalk.cyan(revision.version)})`);\n\n for (const duplicate of revision.duplicates) {\n console.log(` - ${chalk.gray(relativePath(duplicate))} (${chalk.gray(duplicate.version)})`);\n }\n counter++;\n }\n }\n if (counter > 0) {\n console.warn(\n '⚠️ Please get rid of multiple revisions as it may introduce some side effects or compatibility issues'\n );\n }\n return counter;\n}\n\n/**\n * Resolves search results to a list of platform-specific configuration.\n */\nexport async function resolveModulesAsync(\n searchResults: SearchResults,\n options: ResolveOptions\n): Promise<ModuleDescriptor[]> {\n const platformLinking = require(`./platforms/${options.platform}`);\n\n return (\n await Promise.all(\n Object.entries(searchResults).map(async ([packageName, revision]) => {\n const resolvedModule = await platformLinking.resolveModuleAsync(\n packageName,\n revision,\n options\n );\n return resolvedModule\n ? {\n packageName,\n packageVersion: revision.version,\n ...resolvedModule,\n }\n : null;\n })\n )\n )\n .filter(Boolean)\n .sort((a, b) => a.packageName.localeCompare(b.packageName));\n}\n\n/**\n * Generates a source file listing all packages to link.\n * Right know it works only for Android platform.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n options: GenerateOptions\n) {\n try {\n const platformLinking = require(`./platforms/${options.platform}`);\n await platformLinking.generatePackageListAsync(modules, options.target, options.namespace);\n } catch (e) {\n console.error(\n chalk.red(`Generating package list is not available for platform: ${options.platform}`)\n );\n throw e;\n }\n}\n\n/**\n * Returns the priority of the config at given path. Higher number means higher priority.\n */\nfunction configPriority(fullpath: string): number {\n return EXPO_MODULE_CONFIG_FILENAMES.indexOf(path.basename(fullpath));\n}\n"]}
package/build/index.js CHANGED
@@ -14,12 +14,13 @@ function registerSearchCommand(commandName, fn) {
14
14
  .option('-i, --ignore-paths <ignorePaths...>', 'Paths to ignore when looking up for modules.', (value, previous) => (previous !== null && previous !== void 0 ? previous : []).concat(value))
15
15
  .option('-e, --exclude <exclude...>', 'Package names to exclude when looking up for modules.', (value, previous) => (previous !== null && previous !== void 0 ? previous : []).concat(value))
16
16
  .option('-p, --platform [platform]', 'The platform that the resulting modules must support. Available options: "ios", "android"', 'ios')
17
+ .option('--silent', 'Silence resolution warnings')
17
18
  .action(async (searchPaths, providedOptions) => {
18
- const options = await autolinking_1.mergeLinkingOptionsAsync({
19
+ const options = await (0, autolinking_1.mergeLinkingOptionsAsync)({
19
20
  ...providedOptions,
20
21
  searchPaths,
21
22
  });
22
- const searchResults = await autolinking_1.findModulesAsync(options);
23
+ const searchResults = await (0, autolinking_1.findModulesAsync)(options);
23
24
  return await fn(searchResults, options);
24
25
  });
25
26
  }
@@ -41,14 +42,14 @@ module.exports = async function (args) {
41
42
  }).option('-j, --json', 'Output results in the plain JSON format.', () => true, false);
42
43
  // Checks whether there are no resolving issues in the current setup.
43
44
  registerSearchCommand('verify', (results) => {
44
- const numberOfDuplicates = autolinking_1.verifySearchResults(results);
45
+ const numberOfDuplicates = (0, autolinking_1.verifySearchResults)(results);
45
46
  if (!numberOfDuplicates) {
46
47
  console.log('✅ Everything is fine!');
47
48
  }
48
49
  });
49
50
  // Searches for available expo modules and resolves the results for given platform.
50
51
  registerResolveCommand('resolve', async (results, options) => {
51
- const modules = await autolinking_1.resolveModulesAsync(results, options);
52
+ const modules = await (0, autolinking_1.resolveModulesAsync)(results, options);
52
53
  if (options.json) {
53
54
  console.log(JSON.stringify({ modules }));
54
55
  }
@@ -58,8 +59,8 @@ module.exports = async function (args) {
58
59
  }).option('-j, --json', 'Output results in the plain JSON format.', () => true, false);
59
60
  // Generates a source file listing all packages to link.
60
61
  registerResolveCommand('generate-package-list', async (results, options) => {
61
- const modules = options.empty ? [] : await autolinking_1.resolveModulesAsync(results, options);
62
- autolinking_1.generatePackageListAsync(modules, options);
62
+ const modules = options.empty ? [] : await (0, autolinking_1.resolveModulesAsync)(results, options);
63
+ (0, autolinking_1.generatePackageListAsync)(modules, options);
63
64
  })
64
65
  .option('-t, --target <path>', 'Path to the target file, where the package list should be written to.')
65
66
  .option('-n, --namespace <namespace>', 'Java package name under which the package list should be placed.')
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,0DAAkC;AAElC,+CAMuB;AAGvB;;GAEG;AACH,SAAS,qBAAqB,CAC5B,WAAmB,EACnB,EAAwD;IAExD,OAAO,mBAAS;SACb,OAAO,CAAC,GAAG,WAAW,aAAa,CAAC;SACpC,MAAM,CACL,qCAAqC,EACrC,8CAA8C,EAC9C,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACpD;SACA,MAAM,CACL,4BAA4B,EAC5B,uDAAuD,EACvD,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACpD;SACA,MAAM,CACL,2BAA2B,EAC3B,2FAA2F,EAC3F,KAAK,CACN;SACA,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,EAAE;QAC7C,MAAM,OAAO,GAAG,MAAM,sCAAwB,CAAc;YAC1D,GAAG,eAAe;YAClB,WAAW;SACZ,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,8BAAgB,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,MAAM,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAC7B,WAAmB,EACnB,EAAwD;IAExD,OAAO,qBAAqB,CAAc,WAAW,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,KAAK,WAAW,IAAc;IAC7C,uCAAuC;IACvC,qBAAqB,CAAqC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAC7F,IAAI,OAAO,CAAC,IAAI,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;SACtC;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;SAClE;IACH,CAAC,CAAC,CAAC,MAAM,CAAU,YAAY,EAAE,0CAA0C,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEhG,qEAAqE;IACrE,qBAAqB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;QAC1C,MAAM,kBAAkB,GAAG,iCAAmB,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,kBAAkB,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;SACtC;IACH,CAAC,CAAC,CAAC;IAEH,mFAAmF;IACnF,sBAAsB,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAC3D,MAAM,OAAO,GAAG,MAAM,iCAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,OAAO,CAAC,IAAI,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;SAC1C;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;SAC1B;IACH,CAAC,CAAC,CAAC,MAAM,CAAU,YAAY,EAAE,0CAA0C,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEhG,wDAAwD;IACxD,sBAAsB,CAAkB,uBAAuB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,iCAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjF,sCAAwB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC;SACC,MAAM,CACL,qBAAqB,EACrB,uEAAuE,CACxE;SACA,MAAM,CACL,6BAA6B,EAC7B,kEAAkE,CACnE;SACA,MAAM,CACL,SAAS,EACT,8FAA8F,EAC9F,KAAK,CACN,CAAC;IAEJ,MAAM,mBAAS;SACZ,OAAO,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,OAAO,CAAC;SACjE,WAAW,CAAC,8DAA8D,CAAC;SAC3E,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import commander from 'commander';\n\nimport {\n findModulesAsync,\n resolveModulesAsync,\n verifySearchResults,\n generatePackageListAsync,\n mergeLinkingOptionsAsync,\n} from './autolinking';\nimport { GenerateOptions, ResolveOptions, SearchOptions, SearchResults } from './types';\n\n/**\n * Registers a command that only searches for available expo modules.\n */\nfunction registerSearchCommand<OptionsType extends SearchOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return commander\n .command(`${commandName} [paths...]`)\n .option<string[] | null>(\n '-i, --ignore-paths <ignorePaths...>',\n 'Paths to ignore when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option<string[] | null>(\n '-e, --exclude <exclude...>',\n 'Package names to exclude when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option(\n '-p, --platform [platform]',\n 'The platform that the resulting modules must support. Available options: \"ios\", \"android\"',\n 'ios'\n )\n .action(async (searchPaths, providedOptions) => {\n const options = await mergeLinkingOptionsAsync<OptionsType>({\n ...providedOptions,\n searchPaths,\n });\n const searchResults = await findModulesAsync(options);\n return await fn(searchResults, options);\n });\n}\n\n/**\n * Registers a command that searches for modules and then resolves them for specific platform.\n */\nfunction registerResolveCommand<OptionsType extends ResolveOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return registerSearchCommand<OptionsType>(commandName, fn);\n}\n\nmodule.exports = async function (args: string[]) {\n // Searches for available expo modules.\n registerSearchCommand<SearchOptions & { json?: boolean }>('search', async (results, options) => {\n if (options.json) {\n console.log(JSON.stringify(results));\n } else {\n console.log(require('util').inspect(results, false, null, true));\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Checks whether there are no resolving issues in the current setup.\n registerSearchCommand('verify', (results) => {\n const numberOfDuplicates = verifySearchResults(results);\n if (!numberOfDuplicates) {\n console.log('✅ Everything is fine!');\n }\n });\n\n // Searches for available expo modules and resolves the results for given platform.\n registerResolveCommand('resolve', async (results, options) => {\n const modules = await resolveModulesAsync(results, options);\n\n if (options.json) {\n console.log(JSON.stringify({ modules }));\n } else {\n console.log({ modules });\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Generates a source file listing all packages to link.\n registerResolveCommand<GenerateOptions>('generate-package-list', async (results, options) => {\n const modules = options.empty ? [] : await resolveModulesAsync(results, options);\n generatePackageListAsync(modules, options);\n })\n .option(\n '-t, --target <path>',\n 'Path to the target file, where the package list should be written to.'\n )\n .option(\n '-n, --namespace <namespace>',\n 'Java package name under which the package list should be placed.'\n )\n .option(\n '--empty',\n 'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.',\n false\n );\n\n await commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for Expo modules to autolink them.')\n .parseAsync(args, { from: 'user' });\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import commander from 'commander';\n\nimport {\n findModulesAsync,\n resolveModulesAsync,\n verifySearchResults,\n generatePackageListAsync,\n mergeLinkingOptionsAsync,\n} from './autolinking';\nimport { GenerateOptions, ResolveOptions, SearchOptions, SearchResults } from './types';\n\n/**\n * Registers a command that only searches for available expo modules.\n */\nfunction registerSearchCommand<OptionsType extends SearchOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return commander\n .command(`${commandName} [paths...]`)\n .option<string[] | null>(\n '-i, --ignore-paths <ignorePaths...>',\n 'Paths to ignore when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option<string[] | null>(\n '-e, --exclude <exclude...>',\n 'Package names to exclude when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option(\n '-p, --platform [platform]',\n 'The platform that the resulting modules must support. Available options: \"ios\", \"android\"',\n 'ios'\n )\n .option('--silent', 'Silence resolution warnings')\n .action(async (searchPaths, providedOptions) => {\n const options = await mergeLinkingOptionsAsync<OptionsType>({\n ...providedOptions,\n searchPaths,\n });\n const searchResults = await findModulesAsync(options);\n return await fn(searchResults, options);\n });\n}\n\n/**\n * Registers a command that searches for modules and then resolves them for specific platform.\n */\nfunction registerResolveCommand<OptionsType extends ResolveOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return registerSearchCommand<OptionsType>(commandName, fn);\n}\n\nmodule.exports = async function (args: string[]) {\n // Searches for available expo modules.\n registerSearchCommand<SearchOptions & { json?: boolean }>('search', async (results, options) => {\n if (options.json) {\n console.log(JSON.stringify(results));\n } else {\n console.log(require('util').inspect(results, false, null, true));\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Checks whether there are no resolving issues in the current setup.\n registerSearchCommand('verify', (results) => {\n const numberOfDuplicates = verifySearchResults(results);\n if (!numberOfDuplicates) {\n console.log('✅ Everything is fine!');\n }\n });\n\n // Searches for available expo modules and resolves the results for given platform.\n registerResolveCommand('resolve', async (results, options) => {\n const modules = await resolveModulesAsync(results, options);\n\n if (options.json) {\n console.log(JSON.stringify({ modules }));\n } else {\n console.log({ modules });\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Generates a source file listing all packages to link.\n registerResolveCommand<GenerateOptions>('generate-package-list', async (results, options) => {\n const modules = options.empty ? [] : await resolveModulesAsync(results, options);\n generatePackageListAsync(modules, options);\n })\n .option(\n '-t, --target <path>',\n 'Path to the target file, where the package list should be written to.'\n )\n .option(\n '-n, --namespace <namespace>',\n 'Java package name under which the package list should be placed.'\n )\n .option(\n '--empty',\n 'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.',\n false\n );\n\n await commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for Expo modules to autolink them.')\n .parseAsync(args, { from: 'user' });\n};\n"]}
@@ -17,11 +17,12 @@ async function generatePackageListAsync(modules, targetPath, namespace) {
17
17
  exports.generatePackageListAsync = generatePackageListAsync;
18
18
  async function resolveModuleAsync(packageName, revision) {
19
19
  // TODO: Relative source dir should be configurable through the module config.
20
+ var _a;
20
21
  // Don't link itself... :D
21
22
  if (packageName === '@unimodules/react-native-adapter') {
22
23
  return null;
23
24
  }
24
- const [buildGradleFile] = await fast_glob_1.default('*/build.gradle', {
25
+ const [buildGradleFile] = await (0, fast_glob_1.default)('*/build.gradle', {
25
26
  cwd: revision.path,
26
27
  ignore: ['**/node_modules/**'],
27
28
  });
@@ -33,6 +34,7 @@ async function resolveModuleAsync(packageName, revision) {
33
34
  return {
34
35
  projectName: convertPackageNameToProjectName(packageName),
35
36
  sourceDir,
37
+ modulesClassNames: (_a = revision.config) === null || _a === void 0 ? void 0 : _a.androidModulesClassNames(),
36
38
  };
37
39
  }
38
40
  exports.resolveModuleAsync = resolveModuleAsync;
@@ -42,29 +44,46 @@ exports.resolveModuleAsync = resolveModuleAsync;
42
44
  async function generatePackageListFileContentAsync(modules, namespace) {
43
45
  // TODO: Instead of ignoring `expo` here, make the package class paths configurable from `expo-module.config.json`.
44
46
  const packagesClasses = await findAndroidPackagesAsync(modules.filter((module) => module.packageName !== 'expo'));
47
+ const modulesClasses = await findAndroidModules(modules);
45
48
  return `package ${namespace};
46
49
 
47
50
  import java.util.Arrays;
48
51
  import java.util.List;
49
52
  import expo.modules.core.interfaces.Package;
53
+ import expo.modules.kotlin.modules.Module;
54
+ import expo.modules.kotlin.ModulesProvider;
50
55
 
51
- public class ExpoModulesPackageList {
56
+ public class ExpoModulesPackageList implements ModulesProvider {
52
57
  private static class LazyHolder {
53
58
  static final List<Package> packagesList = Arrays.<Package>asList(
54
59
  ${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\n')}
55
60
  );
61
+
62
+ static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(
63
+ ${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\n')}
64
+ );
56
65
  }
57
66
 
58
67
  public static List<Package> getPackageList() {
59
68
  return LazyHolder.packagesList;
60
69
  }
70
+
71
+ @Override
72
+ public List<Class<? extends Module>> getModulesList() {
73
+ return LazyHolder.modulesList;
74
+ }
61
75
  }
62
76
  `;
63
77
  }
78
+ function findAndroidModules(modules) {
79
+ const modulesToProvide = modules.filter((module) => module.modulesClassNames.length > 0);
80
+ const classNames = [].concat(...modulesToProvide.map((module) => module.modulesClassNames));
81
+ return classNames;
82
+ }
64
83
  async function findAndroidPackagesAsync(modules) {
65
84
  const classes = [];
66
85
  await Promise.all(modules.map(async (module) => {
67
- const files = await fast_glob_1.default('src/**/*Package.{java,kt}', {
86
+ const files = await (0, fast_glob_1.default)('**/*Package.{java,kt}', {
68
87
  cwd: module.sourceDir,
69
88
  });
70
89
  for (const file of files) {
@@ -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,OAA2B,EAC3B,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;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,CAAC,eAAe,CAAC,GAAG,MAAM,mBAAI,CAAC,gBAAgB,EAAE;QACrD,GAAG,EAAE,QAAQ,CAAC,IAAI;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,qEAAqE;IACrE,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,IAAI,CAAC;KACb;IAED,MAAM,SAAS,GAAG,cAAI,CAAC,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;IAE1E,OAAO;QACL,WAAW,EAAE,+BAA+B,CAAC,WAAW,CAAC;QACzD,SAAS;KACV,CAAC;AACJ,CAAC;AA3BD,gDA2BC;AAED;;GAEG;AACH,KAAK,UAAU,mCAAmC,CAChD,OAA2B,EAC3B,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,OAAO,WAAW,SAAS;;;;;;;;;EAS3B,eAAe,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,aAAa,YAAY,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;CAQjF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,OAA2B;IACjE,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,MAAM,mBAAI,CAAC,2BAA2B,EAAE;YACpD,GAAG,EAAE,MAAM,CAAC,SAAS;SACtB,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YAEjF,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;;;GAGG;AACH,SAAS,+BAA+B,CAAC,WAAmB;IAC1D,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptor, PackageRevision } from '../types';\n\n/**\n * Generates Java file that contains all autolinked packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n targetPath: string,\n namespace: string\n): Promise<void> {\n const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptor | 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 [buildGradleFile] = await glob('*/build.gradle', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n // Just in case where the module doesn't have its own `build.gradle`.\n if (!buildGradleFile) {\n return null;\n }\n\n const sourceDir = path.dirname(path.join(revision.path, buildGradleFile));\n\n return {\n projectName: convertPackageNameToProjectName(packageName),\n sourceDir,\n };\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptor[],\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 return `package ${namespace};\n\nimport java.util.Arrays;\nimport java.util.List;\nimport expo.modules.core.interfaces.Package;\n\npublic class ExpoModulesPackageList {\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\n public static List<Package> getPackageList() {\n return LazyHolder.packagesList;\n }\n}\n`;\n}\n\nasync function findAndroidPackagesAsync(modules: ModuleDescriptor[]): Promise<string[]> {\n const classes: string[] = [];\n\n await Promise.all(\n modules.map(async (module) => {\n const files = await glob('src/**/*Package.{java,kt}', {\n cwd: module.sourceDir,\n });\n\n for (const file of files) {\n const fileContent = await fs.readFile(path.join(module.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 to Android's project name.\n * Example: `@unimodules/core` → `unimodules-core`\n */\nfunction convertPackageNameToProjectName(projectName: string): string {\n return projectName.replace(/^@/g, '').replace(/\\W+/g, '-');\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 { ModuleDescriptor, PackageRevision } from '../types';\n\n/**\n * Generates Java file that contains all autolinked packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n targetPath: string,\n namespace: string\n): Promise<void> {\n const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptor | 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 [buildGradleFile] = await glob('*/build.gradle', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n // Just in case where the module doesn't have its own `build.gradle`.\n if (!buildGradleFile) {\n return null;\n }\n\n const sourceDir = path.dirname(path.join(revision.path, buildGradleFile));\n\n return {\n projectName: convertPackageNameToProjectName(packageName),\n sourceDir,\n modulesClassNames: revision.config?.androidModulesClassNames(),\n };\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptor[],\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: ModuleDescriptor[]): string[] {\n const modulesToProvide = modules.filter((module) => module.modulesClassNames.length > 0);\n const classNames = [].concat(...modulesToProvide.map((module) => module.modulesClassNames));\n return classNames;\n}\n\nasync function findAndroidPackagesAsync(modules: ModuleDescriptor[]): Promise<string[]> {\n const classes: string[] = [];\n\n await Promise.all(\n modules.map(async (module) => {\n const files = await glob('**/*Package.{java,kt}', {\n cwd: module.sourceDir,\n });\n\n for (const file of files) {\n const fileContent = await fs.readFile(path.join(module.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 to Android's project name.\n * Example: `@unimodules/core` → `unimodules-core`\n */\nfunction convertPackageNameToProjectName(projectName: string): string {\n return projectName.replace(/^@/g, '').replace(/\\W+/g, '-');\n}\n"]}
@@ -11,8 +11,8 @@ const path_1 = __importDefault(require("path"));
11
11
  * Resolves module search result with additional details required for iOS platform.
12
12
  */
13
13
  async function resolveModuleAsync(packageName, revision, options) {
14
- var _a;
15
- const [podspecFile] = await fast_glob_1.default('*/*.podspec', {
14
+ var _a, _b;
15
+ const [podspecFile] = await (0, fast_glob_1.default)('*/*.podspec', {
16
16
  cwd: revision.path,
17
17
  ignore: ['**/node_modules/**'],
18
18
  });
@@ -26,6 +26,7 @@ async function resolveModuleAsync(packageName, revision, options) {
26
26
  podspecDir,
27
27
  flags: options.flags,
28
28
  modulesClassNames: (_a = revision.config) === null || _a === void 0 ? void 0 : _a.iosModulesClassNames(),
29
+ appDelegateSubscribers: (_b = revision.config) === null || _b === void 0 ? void 0 : _b.iosAppDelegateSubscribers(),
29
30
  };
30
31
  }
31
32
  exports.resolveModuleAsync = resolveModuleAsync;
@@ -42,9 +43,14 @@ exports.generatePackageListAsync = generatePackageListAsync;
42
43
  * Generates the string to put into the generated package list.
43
44
  */
44
45
  async function generatePackageListFileContentAsync(modules, className) {
45
- const modulesToProvide = modules.filter((module) => module.modulesClassNames.length > 0);
46
- const pods = modulesToProvide.map((module) => module.podName);
47
- const classNames = [].concat(...modulesToProvide.map((module) => module.modulesClassNames));
46
+ const modulesToImport = modules.filter((module) => module.modulesClassNames.length + module.appDelegateSubscribers.length > 0);
47
+ const pods = modulesToImport.map((module) => module.podName);
48
+ const modulesClassNames = []
49
+ .concat(...modulesToImport.map((module) => module.modulesClassNames))
50
+ .filter(Boolean);
51
+ const appDelegateSubscribers = []
52
+ .concat(...modulesToImport.map((module) => module.appDelegateSubscribers))
53
+ .filter(Boolean);
48
54
  return `/**
49
55
  * Automatically generated by expo-modules-autolinking.
50
56
  *
@@ -57,10 +63,21 @@ ${pods.map((podName) => `import ${podName}\n`).join('')}
57
63
  @objc(${className})
58
64
  public class ${className}: ModulesProvider {
59
65
  public override func getModuleClasses() -> [AnyModule.Type] {
60
- return [${classNames.map((className) => `\n ${className}.self`).join(',')}
61
- ]
66
+ return ${formatArrayOfClassNames(modulesClassNames)}
67
+ }
68
+
69
+ public override func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {
70
+ return ${formatArrayOfClassNames(appDelegateSubscribers)}
62
71
  }
63
72
  }
64
73
  `;
65
74
  }
75
+ /**
76
+ * Formats an array of class names to Swift's array containing these classes.
77
+ */
78
+ function formatArrayOfClassNames(classNames) {
79
+ const indent = ' ';
80
+ return `[${classNames.map((className) => `\n${indent.repeat(3)}${className}.self`).join(',')}
81
+ ${indent.repeat(2)}]`;
82
+ }
66
83
  //# sourceMappingURL=ios.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/platforms/ios.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,wDAA0B;AAC1B,gDAAwB;AAIxB;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB,EACzB,OAAsB;;IAEtB,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,mBAAI,CAAC,aAAa,EAAE;QAC9C,GAAG,EAAE,QAAQ,CAAC,IAAI;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,IAAI,CAAC;KACb;IAED,MAAM,OAAO,GAAG,cAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAEvE,OAAO;QACL,OAAO;QACP,UAAU;QACV,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,iBAAiB,EAAE,MAAA,QAAQ,CAAC,MAAM,0CAAE,oBAAoB,EAAE;KAC3D,CAAC;AACJ,CAAC;AAvBD,gDAuBC;AAED;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAC5C,OAA2B,EAC3B,UAAkB;IAElB,MAAM,SAAS,GAAG,cAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACtE,MAAM,oBAAoB,GAAG,MAAM,mCAAmC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAE3F,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;AACxD,CAAC;AARD,4DAQC;AAED;;GAEG;AACH,KAAK,UAAU,mCAAmC,CAChD,OAA2B,EAC3B,SAAiB;IAEjB,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAE5F,OAAO;;;;;;;;EAQP,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,SAAS;eACF,SAAS;;cAEV,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,WAAW,SAAS,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;;;CAIjF,CAAC;AACF,CAAC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptor, PackageRevision, SearchOptions } from '../types';\n\n/**\n * Resolves module search result with additional details required for iOS platform.\n */\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision,\n options: SearchOptions\n): Promise<ModuleDescriptor | null> {\n const [podspecFile] = await glob('*/*.podspec', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n if (!podspecFile) {\n return null;\n }\n\n const podName = path.basename(podspecFile, path.extname(podspecFile));\n const podspecDir = path.dirname(path.join(revision.path, podspecFile));\n\n return {\n podName,\n podspecDir,\n flags: options.flags,\n modulesClassNames: revision.config?.iosModulesClassNames(),\n };\n}\n\n/**\n * Generates Swift file that contains all autolinked Swift packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n targetPath: string\n): Promise<void> {\n const className = path.basename(targetPath, path.extname(targetPath));\n const generatedFileContent = await generatePackageListFileContentAsync(modules, className);\n\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptor[],\n className: string\n): Promise<string> {\n const modulesToProvide = modules.filter((module) => module.modulesClassNames.length > 0);\n const pods = modulesToProvide.map((module) => module.podName);\n const classNames = [].concat(...modulesToProvide.map((module) => module.modulesClassNames));\n\n return `/**\n * Automatically generated by expo-modules-autolinking.\n *\n * This autogenerated class provides a list of classes of native Expo modules,\n * but only these that are written in Swift and use the new API for creating Expo modules.\n */\n\nimport ExpoModulesCore\n${pods.map((podName) => `import ${podName}\\n`).join('')}\n@objc(${className})\npublic class ${className}: ModulesProvider {\n public override func getModuleClasses() -> [AnyModule.Type] {\n return [${classNames.map((className) => `\\n ${className}.self`).join(',')}\n ]\n }\n}\n`;\n}\n"]}
1
+ {"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/platforms/ios.ts"],"names":[],"mappings":"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","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptor, PackageRevision, SearchOptions } from '../types';\n\n/**\n * Resolves module search result with additional details required for iOS platform.\n */\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision,\n options: SearchOptions\n): Promise<ModuleDescriptor | null> {\n const [podspecFile] = await glob('*/*.podspec', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n if (!podspecFile) {\n return null;\n }\n\n const podName = path.basename(podspecFile, path.extname(podspecFile));\n const podspecDir = path.dirname(path.join(revision.path, podspecFile));\n\n return {\n podName,\n podspecDir,\n flags: options.flags,\n modulesClassNames: revision.config?.iosModulesClassNames(),\n appDelegateSubscribers: revision.config?.iosAppDelegateSubscribers(),\n };\n}\n\n/**\n * Generates Swift file that contains all autolinked Swift packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n targetPath: string\n): Promise<void> {\n const className = path.basename(targetPath, path.extname(targetPath));\n const generatedFileContent = await generatePackageListFileContentAsync(modules, className);\n\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptor[],\n className: string\n): Promise<string> {\n const modulesToImport = modules.filter(\n (module) => module.modulesClassNames.length + module.appDelegateSubscribers.length > 0\n );\n const pods = modulesToImport.map((module) => module.podName);\n\n const modulesClassNames = []\n .concat(...modulesToImport.map((module) => module.modulesClassNames))\n .filter(Boolean);\n\n const appDelegateSubscribers = []\n .concat(...modulesToImport.map((module) => module.appDelegateSubscribers))\n .filter(Boolean);\n\n return `/**\n * Automatically generated by expo-modules-autolinking.\n *\n * This autogenerated class provides a list of classes of native Expo modules,\n * but only these that are written in Swift and use the new API for creating Expo modules.\n */\n\nimport ExpoModulesCore\n${pods.map((podName) => `import ${podName}\\n`).join('')}\n@objc(${className})\npublic class ${className}: ModulesProvider {\n public override func getModuleClasses() -> [AnyModule.Type] {\n return ${formatArrayOfClassNames(modulesClassNames)}\n }\n\n public override func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {\n return ${formatArrayOfClassNames(appDelegateSubscribers)}\n }\n}\n`;\n}\n\n/**\n * Formats an array of class names to Swift's array containing these classes.\n */\nfunction formatArrayOfClassNames(classNames: string[]): string {\n const indent = ' ';\n return `[${classNames.map((className) => `\\n${indent.repeat(3)}${className}.self`).join(',')}\n${indent.repeat(2)}]`;\n}\n"]}
package/build/types.d.ts CHANGED
@@ -5,6 +5,7 @@ export interface SearchOptions {
5
5
  ignorePaths?: string[] | null;
6
6
  exclude?: string[] | null;
7
7
  platform: SupportedPlatform;
8
+ silent?: boolean;
8
9
  flags?: Record<string, any>;
9
10
  }
10
11
  export interface ResolveOptions extends SearchOptions {
@@ -41,5 +42,18 @@ export interface RawExpoModuleConfig {
41
42
  * Names of Swift native modules classes to put to the generated modules provider file.
42
43
  */
43
44
  modulesClassNames?: string[];
45
+ /**
46
+ * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.
47
+ */
48
+ appDelegateSubscribers?: string[];
49
+ };
50
+ /**
51
+ * Android-specific config.
52
+ */
53
+ android?: {
54
+ /**
55
+ * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.
56
+ */
57
+ modulesClassNames?: string[];
44
58
  };
45
59
  }
@@ -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\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 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 type ModuleDescriptor = Record<string, any>;\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 modulesClassNames?: 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\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 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 type ModuleDescriptor = Record<string, any>;\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 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 /**\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 modulesClassNames?: string[];\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-autolinking",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Scripts that autolink Expo modules.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -34,18 +34,18 @@
34
34
  "license": "MIT",
35
35
  "homepage": "https://github.com/expo/expo/tree/master/packages/expo-modules-autolinking#readme",
36
36
  "devDependencies": {
37
+ "@expo/spawn-async": "^1.5.0",
37
38
  "@tsconfig/node12": "^1.0.9",
38
39
  "@types/fs-extra": "^9.0.11",
39
40
  "expo-module-scripts": "~2.0.0",
40
- "@expo/spawn-async": "1.5.0",
41
41
  "tempy": "^0.7.1"
42
42
  },
43
43
  "dependencies": {
44
44
  "chalk": "^4.1.0",
45
45
  "commander": "^7.2.0",
46
46
  "fast-glob": "^3.2.5",
47
- "find-up": "~5.0.0",
47
+ "find-up": "^5.0.0",
48
48
  "fs-extra": "^9.1.0"
49
49
  },
50
- "gitHead": "b8f1c8fcebe384722d646f83c3834c9fb25b026a"
50
+ "gitHead": "9faa58818454ba59dbff95077b9025a1c1cbd9fd"
51
51
  }
@@ -44,7 +44,7 @@ class ExpoAutolinkingManager {
44
44
  String[] args = convertOptionsToCommandArgs('resolve', this.options)
45
45
  args += ['--json']
46
46
 
47
- String output = exec(args)
47
+ String output = exec(args, projectDir)
48
48
  Object json = new JsonSlurper().parseText(output)
49
49
 
50
50
  cachedResolvingResults = json
@@ -84,11 +84,11 @@ class ExpoAutolinkingManager {
84
84
  args += '--empty'
85
85
  }
86
86
 
87
- exec(args)
87
+ exec(args, project.rootDir)
88
88
  }
89
89
 
90
- static String exec(String[] commandArgs) {
91
- Process proc = commandArgs.execute()
90
+ static String exec(String[] commandArgs, File dir) {
91
+ Process proc = commandArgs.execute(null, dir)
92
92
  StringBuffer outputStream = new StringBuffer()
93
93
  proc.waitForProcessOutput(outputStream, System.err)
94
94
  return outputStream.toString()
@@ -166,6 +166,7 @@ if (rootProject instanceof ProjectDescriptor) {
166
166
  return
167
167
  }
168
168
 
169
+ println ''
169
170
  println 'Using expo modules'
170
171
 
171
172
  for (module in modules) {
@@ -181,8 +182,10 @@ if (rootProject instanceof ProjectDescriptor) {
181
182
  continue
182
183
  }
183
184
 
184
- println " ${Colors.GREEN}${module.name}${Colors.RESET} (${module.version})"
185
+ println " - ${Colors.GREEN}${module.name}${Colors.RESET} (${module.version})"
185
186
  }
187
+
188
+ println ''
186
189
  }
187
190
 
188
191
  // Adding dependencies
@@ -2,6 +2,7 @@ require_relative 'constants'
2
2
  require_relative 'package'
3
3
 
4
4
  # Require extensions to CocoaPods' classes
5
+ require_relative 'cocoapods/pod_target'
5
6
  require_relative 'cocoapods/target_definition'
6
7
  require_relative 'cocoapods/user_project_integrator'
7
8
 
@@ -57,7 +58,7 @@ module Expo
57
58
 
58
59
  # Spawns `expo-module-autolinking generate-package-list` command.
59
60
  public def generate_package_list(target_name, target_path)
60
- IO.popen(generate_package_list_command_args(target_path))
61
+ Process.wait IO.popen(generate_package_list_command_args(target_path)).pid
61
62
  end
62
63
 
63
64
  # If there is any package to autolink.
@@ -0,0 +1,38 @@
1
+ # Overrides CocoaPods `PodTarget` class to make the `ReactCommon` pod define a module
2
+ # and tell CocoaPods to generate a modulemap for it. This is needed for Swift/JSI integration
3
+ # until the upstream podspec add `DEFINES_MODULE => YES` to build settings.
4
+ # See: https://github.com/CocoaPods/CocoaPods/blob/master/lib/cocoapods/target/pod_target.rb
5
+
6
+ module Pod
7
+ class PodTarget
8
+
9
+ private
10
+
11
+ _original_defines_module = instance_method(:defines_module?)
12
+
13
+ public
14
+
15
+ # @return [Boolean] Whether the target defines a "module"
16
+ # (and thus will need a module map and umbrella header).
17
+ #
18
+ # @note Static library targets can temporarily opt in to this behavior by setting
19
+ # `DEFINES_MODULE = YES` in their specification's `pod_target_xcconfig`.
20
+ #
21
+ define_method(:defines_module?) do
22
+ # Call the original method
23
+ original_result = _original_defines_module.bind(self).()
24
+
25
+ # Make ReactCommon specs define a module. This is required for ExpoModulesCore
26
+ # to use `ReactCommon/turbomodule/core` subspec as a module, from Swift.
27
+ # It also needs to handle versioned pods in Expo Go, so we check if the pod name
28
+ # ends with `ReactCommon` instead of checking if they're equal.
29
+ if !original_result && name.end_with?('ReactCommon')
30
+ root_spec.consumer(platform).pod_target_xcconfig['DEFINES_MODULE'] = 'YES'
31
+ return @defines_module = true
32
+ end
33
+
34
+ # Return the original value if not applicable for hack.
35
+ return original_result
36
+ end
37
+ end
38
+ end
@@ -20,6 +20,20 @@ export class ExpoModuleConfig {
20
20
  return this.rawConfig.ios?.modulesClassNames ?? [];
21
21
  }
22
22
 
23
+ /**
24
+ * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.
25
+ */
26
+ iosAppDelegateSubscribers(): string[] {
27
+ return this.rawConfig.ios?.appDelegateSubscribers ?? [];
28
+ }
29
+
30
+ /**
31
+ * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
32
+ */
33
+ androidModulesClassNames() {
34
+ return this.rawConfig.android?.modulesClassNames ?? [];
35
+ }
36
+
23
37
  /**
24
38
  * Returns serializable raw config.
25
39
  */
@@ -127,13 +127,16 @@ export async function findModulesAsync(providedOptions: SearchOptions): Promise<
127
127
  if (options.searchPaths.length <= 1) {
128
128
  return results;
129
129
  }
130
- return filterToProjectDependencies(results);
130
+ return filterToProjectDependencies(results, providedOptions);
131
131
  }
132
132
 
133
133
  /**
134
134
  * Filters out packages that are not the dependencies of the project.
135
135
  */
136
- function filterToProjectDependencies(results: SearchResults) {
136
+ function filterToProjectDependencies(
137
+ results: SearchResults,
138
+ options: Pick<SearchOptions, 'silent'> = {}
139
+ ) {
137
140
  const filteredResults: SearchResults = {};
138
141
  const visitedPackages = new Set<string>();
139
142
 
@@ -160,11 +163,11 @@ function filterToProjectDependencies(results: SearchResults) {
160
163
  } else {
161
164
  try {
162
165
  dependencyPackageJsonPath = projectRequire.resolve(`${dependencyName}/package.json`);
163
- } catch (error) {
166
+ } catch (error: any) {
164
167
  // Some packages don't include package.json in its `exports` field,
165
168
  // but none of our packages do that, so it seems fine to just ignore that type of error.
166
169
  // Related issue: https://github.com/react-native-community/cli/issues/1168
167
- if (error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
170
+ if (!options.silent && error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
168
171
  console.warn(
169
172
  chalk.yellow(`⚠️ Cannot resolve the path to "${dependencyName}" package.`)
170
173
  );
@@ -285,6 +288,7 @@ export async function generatePackageListAsync(
285
288
  console.error(
286
289
  chalk.red(`Generating package list is not available for platform: ${options.platform}`)
287
290
  );
291
+ throw e;
288
292
  }
289
293
  }
290
294
 
package/src/index.ts CHANGED
@@ -33,6 +33,7 @@ function registerSearchCommand<OptionsType extends SearchOptions>(
33
33
  'The platform that the resulting modules must support. Available options: "ios", "android"',
34
34
  'ios'
35
35
  )
36
+ .option('--silent', 'Silence resolution warnings')
36
37
  .action(async (searchPaths, providedOptions) => {
37
38
  const options = await mergeLinkingOptionsAsync<OptionsType>({
38
39
  ...providedOptions,
@@ -42,6 +42,7 @@ export async function resolveModuleAsync(
42
42
  return {
43
43
  projectName: convertPackageNameToProjectName(packageName),
44
44
  sourceDir,
45
+ modulesClassNames: revision.config?.androidModulesClassNames(),
45
46
  };
46
47
  }
47
48
 
@@ -57,32 +58,51 @@ async function generatePackageListFileContentAsync(
57
58
  modules.filter((module) => module.packageName !== 'expo')
58
59
  );
59
60
 
61
+ const modulesClasses = await findAndroidModules(modules);
62
+
60
63
  return `package ${namespace};
61
64
 
62
65
  import java.util.Arrays;
63
66
  import java.util.List;
64
67
  import expo.modules.core.interfaces.Package;
68
+ import expo.modules.kotlin.modules.Module;
69
+ import expo.modules.kotlin.ModulesProvider;
65
70
 
66
- public class ExpoModulesPackageList {
71
+ public class ExpoModulesPackageList implements ModulesProvider {
67
72
  private static class LazyHolder {
68
73
  static final List<Package> packagesList = Arrays.<Package>asList(
69
74
  ${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\n')}
70
75
  );
76
+
77
+ static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(
78
+ ${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\n')}
79
+ );
71
80
  }
72
81
 
73
82
  public static List<Package> getPackageList() {
74
83
  return LazyHolder.packagesList;
75
84
  }
85
+
86
+ @Override
87
+ public List<Class<? extends Module>> getModulesList() {
88
+ return LazyHolder.modulesList;
89
+ }
76
90
  }
77
91
  `;
78
92
  }
79
93
 
94
+ function findAndroidModules(modules: ModuleDescriptor[]): string[] {
95
+ const modulesToProvide = modules.filter((module) => module.modulesClassNames.length > 0);
96
+ const classNames = [].concat(...modulesToProvide.map((module) => module.modulesClassNames));
97
+ return classNames;
98
+ }
99
+
80
100
  async function findAndroidPackagesAsync(modules: ModuleDescriptor[]): Promise<string[]> {
81
101
  const classes: string[] = [];
82
102
 
83
103
  await Promise.all(
84
104
  modules.map(async (module) => {
85
- const files = await glob('src/**/*Package.{java,kt}', {
105
+ const files = await glob('**/*Package.{java,kt}', {
86
106
  cwd: module.sourceDir,
87
107
  });
88
108
 
@@ -29,6 +29,7 @@ export async function resolveModuleAsync(
29
29
  podspecDir,
30
30
  flags: options.flags,
31
31
  modulesClassNames: revision.config?.iosModulesClassNames(),
32
+ appDelegateSubscribers: revision.config?.iosAppDelegateSubscribers(),
32
33
  };
33
34
  }
34
35
 
@@ -52,9 +53,18 @@ async function generatePackageListFileContentAsync(
52
53
  modules: ModuleDescriptor[],
53
54
  className: string
54
55
  ): Promise<string> {
55
- const modulesToProvide = modules.filter((module) => module.modulesClassNames.length > 0);
56
- const pods = modulesToProvide.map((module) => module.podName);
57
- const classNames = [].concat(...modulesToProvide.map((module) => module.modulesClassNames));
56
+ const modulesToImport = modules.filter(
57
+ (module) => module.modulesClassNames.length + module.appDelegateSubscribers.length > 0
58
+ );
59
+ const pods = modulesToImport.map((module) => module.podName);
60
+
61
+ const modulesClassNames = []
62
+ .concat(...modulesToImport.map((module) => module.modulesClassNames))
63
+ .filter(Boolean);
64
+
65
+ const appDelegateSubscribers = []
66
+ .concat(...modulesToImport.map((module) => module.appDelegateSubscribers))
67
+ .filter(Boolean);
58
68
 
59
69
  return `/**
60
70
  * Automatically generated by expo-modules-autolinking.
@@ -68,9 +78,21 @@ ${pods.map((podName) => `import ${podName}\n`).join('')}
68
78
  @objc(${className})
69
79
  public class ${className}: ModulesProvider {
70
80
  public override func getModuleClasses() -> [AnyModule.Type] {
71
- return [${classNames.map((className) => `\n ${className}.self`).join(',')}
72
- ]
81
+ return ${formatArrayOfClassNames(modulesClassNames)}
82
+ }
83
+
84
+ public override func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {
85
+ return ${formatArrayOfClassNames(appDelegateSubscribers)}
73
86
  }
74
87
  }
75
88
  `;
76
89
  }
90
+
91
+ /**
92
+ * Formats an array of class names to Swift's array containing these classes.
93
+ */
94
+ function formatArrayOfClassNames(classNames: string[]): string {
95
+ const indent = ' ';
96
+ return `[${classNames.map((className) => `\n${indent.repeat(3)}${className}.self`).join(',')}
97
+ ${indent.repeat(2)}]`;
98
+ }
package/src/types.ts CHANGED
@@ -8,6 +8,7 @@ export interface SearchOptions {
8
8
  ignorePaths?: string[] | null;
9
9
  exclude?: string[] | null;
10
10
  platform: SupportedPlatform;
11
+ silent?: boolean;
11
12
 
12
13
  // Scratched from project's config
13
14
  flags?: Record<string, any>;
@@ -53,5 +54,20 @@ export interface RawExpoModuleConfig {
53
54
  * Names of Swift native modules classes to put to the generated modules provider file.
54
55
  */
55
56
  modulesClassNames?: string[];
57
+
58
+ /**
59
+ * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.
60
+ */
61
+ appDelegateSubscribers?: string[];
62
+ };
63
+
64
+ /**
65
+ * Android-specific config.
66
+ */
67
+ android?: {
68
+ /**
69
+ * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.
70
+ */
71
+ modulesClassNames?: string[];
56
72
  };
57
73
  }