expo-modules-autolinking 3.0.24 → 3.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 3.0.25 — 2026-04-27
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fix missing deep object merging that should allow a project config to override a dependency's per-platform config options selectively ([#44668](https://github.com/expo/expo/pull/44668) by [@kitten](https://github.com/kitten))
|
|
18
|
+
|
|
13
19
|
## 3.0.24 — 2026-01-06
|
|
14
20
|
|
|
15
21
|
### 💡 Others
|
|
@@ -14,6 +14,22 @@ const iosResolver_1 = require("./iosResolver");
|
|
|
14
14
|
const ExpoModuleConfig_1 = require("../ExpoModuleConfig");
|
|
15
15
|
const dependencies_1 = require("../dependencies");
|
|
16
16
|
const webResolver_1 = require("./webResolver");
|
|
17
|
+
const deepObjectMerge = (target, source) => {
|
|
18
|
+
if (source !== undefined &&
|
|
19
|
+
typeof target === 'object' &&
|
|
20
|
+
target != null &&
|
|
21
|
+
!Array.isArray(target) &&
|
|
22
|
+
(!target.constructor || target.constructor === Object) &&
|
|
23
|
+
typeof source === 'object' &&
|
|
24
|
+
!Array.isArray(source)) {
|
|
25
|
+
target = { ...target };
|
|
26
|
+
for (const key in source) {
|
|
27
|
+
target[key] = deepObjectMerge(target[key], source[key]);
|
|
28
|
+
}
|
|
29
|
+
return target;
|
|
30
|
+
}
|
|
31
|
+
return source !== undefined ? source : target;
|
|
32
|
+
};
|
|
17
33
|
const isMissingFBReactNativeSpecCodegenOutput = async (reactNativePath) => {
|
|
18
34
|
const generatedDir = path_1.default.resolve(reactNativePath, 'React/FBReactNativeSpec');
|
|
19
35
|
try {
|
|
@@ -36,15 +52,16 @@ async function resolveReactNativeModule(resolution, projectConfig, platform, exc
|
|
|
36
52
|
return null;
|
|
37
53
|
}
|
|
38
54
|
const libraryConfig = (await (0, config_1.loadConfigAsync)(resolution.path));
|
|
39
|
-
const reactNativeConfig = {
|
|
40
|
-
...libraryConfig?.dependency,
|
|
41
|
-
...projectConfig?.dependencies?.[resolution.name],
|
|
42
|
-
};
|
|
43
55
|
if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {
|
|
44
56
|
// Package defines platforms would be a platform host package.
|
|
45
57
|
// The rnc-cli will skip this package.
|
|
46
58
|
return null;
|
|
47
59
|
}
|
|
60
|
+
let reactNativeConfig = libraryConfig?.dependency ?? {};
|
|
61
|
+
const projectDependencyOverride = projectConfig?.dependencies?.[resolution.name];
|
|
62
|
+
if (projectDependencyOverride != null) {
|
|
63
|
+
reactNativeConfig = deepObjectMerge(reactNativeConfig, projectDependencyOverride);
|
|
64
|
+
}
|
|
48
65
|
let maybeExpoModuleConfig;
|
|
49
66
|
if (!libraryConfig) {
|
|
50
67
|
// NOTE(@kitten): If we don't have an explicit react-native.config.{js,ts} file,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactNativeConfig.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport type { SupportedPlatform } from '../types';\nimport {\n findGradleAndManifestAsync,\n parsePackageNameAsync,\n resolveDependencyConfigImplAndroidAsync,\n} from './androidResolver';\nimport { loadConfigAsync } from './config';\nimport { resolveDependencyConfigImplIosAsync } from './iosResolver';\nimport type {\n RNConfigDependency,\n RNConfigDependencyAndroid,\n RNConfigDependencyIos,\n RNConfigDependencyWeb,\n RNConfigReactNativeAppProjectConfig,\n RNConfigReactNativeLibraryConfig,\n RNConfigReactNativeProjectConfig,\n RNConfigResult,\n} from './reactNativeConfig.types';\nimport { discoverExpoModuleConfigAsync, ExpoModuleConfig } from '../ExpoModuleConfig';\nimport { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport {\n DependencyResolution,\n filterMapResolutionResult,\n mergeResolutionResults,\n scanDependenciesFromRNProjectConfig,\n scanDependenciesInSearchPath,\n scanDependenciesRecursively,\n} from '../dependencies';\nimport { checkDependencyWebAsync } from './webResolver';\n\nconst isMissingFBReactNativeSpecCodegenOutput = async (reactNativePath: string) => {\n const generatedDir = path.resolve(reactNativePath, 'React/FBReactNativeSpec');\n try {\n const stat = await fs.promises.lstat(generatedDir);\n return !stat.isDirectory();\n } catch {\n return true;\n }\n};\n\nexport async function resolveReactNativeModule(\n resolution: DependencyResolution,\n projectConfig: RNConfigReactNativeProjectConfig | null,\n platform: SupportedPlatform,\n excludeNames: Set<string>\n): Promise<RNConfigDependency | null> {\n if (excludeNames.has(resolution.name)) {\n return null;\n } else if (resolution.name === 'react-native' || resolution.name === 'react-native-macos') {\n // Starting from version 0.76, the `react-native` package only defines platforms\n // when @react-native-community/cli-platform-android/ios is installed.\n // Therefore, we need to manually filter it out.\n // NOTE(@kitten): `loadConfigAsync` is skipped too, because react-native's config is too slow\n return null;\n }\n\n const libraryConfig = (await loadConfigAsync(\n resolution.path\n )) as RNConfigReactNativeLibraryConfig;\n const reactNativeConfig = {\n ...libraryConfig?.dependency,\n ...projectConfig?.dependencies?.[resolution.name],\n };\n\n if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {\n // Package defines platforms would be a platform host package.\n // The rnc-cli will skip this package.\n return null;\n }\n\n let maybeExpoModuleConfig: ExpoModuleConfig | null | undefined;\n if (!libraryConfig) {\n // NOTE(@kitten): If we don't have an explicit react-native.config.{js,ts} file,\n // we should pass the Expo Module config (if it exists) to the resolvers below,\n // which can then decide if the React Native inferred config and Expo Module\n // configs conflict\n try {\n maybeExpoModuleConfig = await discoverExpoModuleConfigAsync(resolution.path);\n } catch {\n // We ignore invalid Expo Modules for the purpose of auto-linking and\n // pretend the config doesn't exist, if it isn't valid JSON\n }\n }\n\n let platformData:\n | RNConfigDependencyAndroid\n | RNConfigDependencyIos\n | RNConfigDependencyWeb\n | null = null;\n if (platform === 'android') {\n platformData = await resolveDependencyConfigImplAndroidAsync(\n resolution.path,\n reactNativeConfig.platforms?.android,\n maybeExpoModuleConfig\n );\n } else if (platform === 'ios') {\n platformData = await resolveDependencyConfigImplIosAsync(\n resolution,\n reactNativeConfig.platforms?.ios,\n maybeExpoModuleConfig\n );\n } else if (platform === 'web') {\n platformData = await checkDependencyWebAsync(\n resolution,\n reactNativeConfig,\n maybeExpoModuleConfig\n );\n }\n return (\n platformData && {\n root: resolution.path,\n name: resolution.name,\n platforms: {\n [platform]: platformData,\n },\n }\n );\n}\n\ninterface CreateRNConfigParams {\n appRoot: string;\n sourceDir: string | undefined;\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform };\n}\n\n/**\n * Create config for react-native core autolinking.\n */\nexport async function createReactNativeConfigAsync({\n appRoot,\n sourceDir,\n autolinkingOptions,\n}: CreateRNConfigParams): Promise<RNConfigResult> {\n const excludeNames = new Set(autolinkingOptions.exclude);\n const projectConfig = (await loadConfigAsync(appRoot)) as RNConfigReactNativeProjectConfig;\n\n // custom native modules should be resolved first so that they can override other modules\n const searchPaths = autolinkingOptions.nativeModulesDir\n ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]\n : autolinkingOptions.searchPaths;\n\n const limitDepth = autolinkingOptions.legacy_shallowReactNativeLinking ? 1 : undefined;\n\n const resolutions = mergeResolutionResults(\n await Promise.all([\n scanDependenciesFromRNProjectConfig(appRoot, projectConfig),\n ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)),\n scanDependenciesRecursively(appRoot, { limitDepth }),\n ])\n );\n\n const dependencies = await filterMapResolutionResult(resolutions, (resolution) =>\n resolveReactNativeModule(resolution, projectConfig, autolinkingOptions.platform, excludeNames)\n );\n\n // See: https://github.com/facebook/react-native/pull/53690\n // When we're building react-native from source without these generated files, we need to force them to be generated\n // Every published react-native version (or out-of-tree version) should have these files, but building from the raw repo won't (e.g. Expo Go)\n const reactNativeResolution = resolutions['react-native'];\n if (\n reactNativeResolution &&\n autolinkingOptions.platform === 'ios' &&\n (await isMissingFBReactNativeSpecCodegenOutput(reactNativeResolution.path))\n ) {\n dependencies['react-native'] = {\n root: reactNativeResolution.path,\n name: 'react-native',\n platforms: {\n ios: {\n // This will trigger a warning in list_native_modules but will trigger the artifacts\n // codegen codepath as expected\n podspecPath: '',\n version: reactNativeResolution.version,\n configurations: [],\n scriptPhases: [],\n },\n },\n };\n }\n\n return {\n root: appRoot,\n reactNativePath: resolutions['react-native']?.path!,\n dependencies,\n project: await resolveAppProjectConfigAsync(appRoot, autolinkingOptions.platform, sourceDir),\n };\n}\n\nexport async function resolveAppProjectConfigAsync(\n projectRoot: string,\n platform: SupportedPlatform,\n sourceDir?: string\n): Promise<RNConfigReactNativeAppProjectConfig> {\n // TODO(@kitten): use the commandRoot here to find these files in non <projectRoot>/<platform> folders\n if (platform === 'android') {\n const androidDir = sourceDir ?? path.join(projectRoot, 'android');\n const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: false });\n if (gradle == null || manifest == null) {\n return {};\n }\n const packageName = await parsePackageNameAsync(manifest, gradle);\n\n return {\n android: {\n packageName: packageName ?? '',\n sourceDir: sourceDir ?? path.join(projectRoot, 'android'),\n },\n };\n }\n\n if (platform === 'ios') {\n return {\n ios: {\n sourceDir: sourceDir ?? path.join(projectRoot, 'ios'),\n },\n };\n }\n\n return {};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reactNativeConfig.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport type { SupportedPlatform } from '../types';\nimport {\n findGradleAndManifestAsync,\n parsePackageNameAsync,\n resolveDependencyConfigImplAndroidAsync,\n} from './androidResolver';\nimport { loadConfigAsync } from './config';\nimport { resolveDependencyConfigImplIosAsync } from './iosResolver';\nimport type {\n RNConfigDependency,\n RNConfigDependencyAndroid,\n RNConfigDependencyIos,\n RNConfigDependencyWeb,\n RNConfigReactNativeAppProjectConfig,\n RNConfigReactNativeLibraryConfig,\n RNConfigReactNativeProjectConfig,\n RNConfigResult,\n} from './reactNativeConfig.types';\nimport { discoverExpoModuleConfigAsync, ExpoModuleConfig } from '../ExpoModuleConfig';\nimport { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport {\n DependencyResolution,\n filterMapResolutionResult,\n mergeResolutionResults,\n scanDependenciesFromRNProjectConfig,\n scanDependenciesInSearchPath,\n scanDependenciesRecursively,\n} from '../dependencies';\nimport { checkDependencyWebAsync } from './webResolver';\n\nconst deepObjectMerge = (target: any, source: any): any => {\n if (\n source !== undefined &&\n typeof target === 'object' &&\n target != null &&\n !Array.isArray(target) &&\n (!target.constructor || target.constructor === Object) &&\n typeof source === 'object' &&\n !Array.isArray(source)\n ) {\n target = { ...target };\n for (const key in source) {\n target[key] = deepObjectMerge(target[key], source[key]);\n }\n return target;\n }\n return source !== undefined ? source : target;\n};\n\nconst isMissingFBReactNativeSpecCodegenOutput = async (reactNativePath: string) => {\n const generatedDir = path.resolve(reactNativePath, 'React/FBReactNativeSpec');\n try {\n const stat = await fs.promises.lstat(generatedDir);\n return !stat.isDirectory();\n } catch {\n return true;\n }\n};\n\nexport async function resolveReactNativeModule(\n resolution: DependencyResolution,\n projectConfig: RNConfigReactNativeProjectConfig | null,\n platform: SupportedPlatform,\n excludeNames: Set<string>\n): Promise<RNConfigDependency | null> {\n if (excludeNames.has(resolution.name)) {\n return null;\n } else if (resolution.name === 'react-native' || resolution.name === 'react-native-macos') {\n // Starting from version 0.76, the `react-native` package only defines platforms\n // when @react-native-community/cli-platform-android/ios is installed.\n // Therefore, we need to manually filter it out.\n // NOTE(@kitten): `loadConfigAsync` is skipped too, because react-native's config is too slow\n return null;\n }\n\n const libraryConfig = (await loadConfigAsync(\n resolution.path\n )) as RNConfigReactNativeLibraryConfig;\n\n if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {\n // Package defines platforms would be a platform host package.\n // The rnc-cli will skip this package.\n return null;\n }\n\n let reactNativeConfig = libraryConfig?.dependency ?? {};\n const projectDependencyOverride = projectConfig?.dependencies?.[resolution.name];\n if (projectDependencyOverride != null) {\n reactNativeConfig = deepObjectMerge(reactNativeConfig, projectDependencyOverride);\n }\n\n let maybeExpoModuleConfig: ExpoModuleConfig | null | undefined;\n if (!libraryConfig) {\n // NOTE(@kitten): If we don't have an explicit react-native.config.{js,ts} file,\n // we should pass the Expo Module config (if it exists) to the resolvers below,\n // which can then decide if the React Native inferred config and Expo Module\n // configs conflict\n try {\n maybeExpoModuleConfig = await discoverExpoModuleConfigAsync(resolution.path);\n } catch {\n // We ignore invalid Expo Modules for the purpose of auto-linking and\n // pretend the config doesn't exist, if it isn't valid JSON\n }\n }\n\n let platformData:\n | RNConfigDependencyAndroid\n | RNConfigDependencyIos\n | RNConfigDependencyWeb\n | null = null;\n if (platform === 'android') {\n platformData = await resolveDependencyConfigImplAndroidAsync(\n resolution.path,\n reactNativeConfig.platforms?.android,\n maybeExpoModuleConfig\n );\n } else if (platform === 'ios') {\n platformData = await resolveDependencyConfigImplIosAsync(\n resolution,\n reactNativeConfig.platforms?.ios,\n maybeExpoModuleConfig\n );\n } else if (platform === 'web') {\n platformData = await checkDependencyWebAsync(\n resolution,\n reactNativeConfig,\n maybeExpoModuleConfig\n );\n }\n return (\n platformData && {\n root: resolution.path,\n name: resolution.name,\n platforms: {\n [platform]: platformData,\n },\n }\n );\n}\n\ninterface CreateRNConfigParams {\n appRoot: string;\n sourceDir: string | undefined;\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform };\n}\n\n/**\n * Create config for react-native core autolinking.\n */\nexport async function createReactNativeConfigAsync({\n appRoot,\n sourceDir,\n autolinkingOptions,\n}: CreateRNConfigParams): Promise<RNConfigResult> {\n const excludeNames = new Set(autolinkingOptions.exclude);\n const projectConfig = (await loadConfigAsync(appRoot)) as RNConfigReactNativeProjectConfig;\n\n // custom native modules should be resolved first so that they can override other modules\n const searchPaths = autolinkingOptions.nativeModulesDir\n ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]\n : autolinkingOptions.searchPaths;\n\n const limitDepth = autolinkingOptions.legacy_shallowReactNativeLinking ? 1 : undefined;\n\n const resolutions = mergeResolutionResults(\n await Promise.all([\n scanDependenciesFromRNProjectConfig(appRoot, projectConfig),\n ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)),\n scanDependenciesRecursively(appRoot, { limitDepth }),\n ])\n );\n\n const dependencies = await filterMapResolutionResult(resolutions, (resolution) =>\n resolveReactNativeModule(resolution, projectConfig, autolinkingOptions.platform, excludeNames)\n );\n\n // See: https://github.com/facebook/react-native/pull/53690\n // When we're building react-native from source without these generated files, we need to force them to be generated\n // Every published react-native version (or out-of-tree version) should have these files, but building from the raw repo won't (e.g. Expo Go)\n const reactNativeResolution = resolutions['react-native'];\n if (\n reactNativeResolution &&\n autolinkingOptions.platform === 'ios' &&\n (await isMissingFBReactNativeSpecCodegenOutput(reactNativeResolution.path))\n ) {\n dependencies['react-native'] = {\n root: reactNativeResolution.path,\n name: 'react-native',\n platforms: {\n ios: {\n // This will trigger a warning in list_native_modules but will trigger the artifacts\n // codegen codepath as expected\n podspecPath: '',\n version: reactNativeResolution.version,\n configurations: [],\n scriptPhases: [],\n },\n },\n };\n }\n\n return {\n root: appRoot,\n reactNativePath: resolutions['react-native']?.path!,\n dependencies,\n project: await resolveAppProjectConfigAsync(appRoot, autolinkingOptions.platform, sourceDir),\n };\n}\n\nexport async function resolveAppProjectConfigAsync(\n projectRoot: string,\n platform: SupportedPlatform,\n sourceDir?: string\n): Promise<RNConfigReactNativeAppProjectConfig> {\n // TODO(@kitten): use the commandRoot here to find these files in non <projectRoot>/<platform> folders\n if (platform === 'android') {\n const androidDir = sourceDir ?? path.join(projectRoot, 'android');\n const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: false });\n if (gradle == null || manifest == null) {\n return {};\n }\n const packageName = await parsePackageNameAsync(manifest, gradle);\n\n return {\n android: {\n packageName: packageName ?? '',\n sourceDir: sourceDir ?? path.join(projectRoot, 'android'),\n },\n };\n }\n\n if (platform === 'ios') {\n return {\n ios: {\n sourceDir: sourceDir ?? path.join(projectRoot, 'ios'),\n },\n };\n }\n\n return {};\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-autolinking",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.25",
|
|
4
4
|
"description": "Scripts that autolink Expo modules.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"require-from-string": "^2.0.2",
|
|
45
45
|
"resolve-from": "^5.0.0"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "dd4e87727c4ef32ac5d8a7b5a42fd80da254140f"
|
|
48
48
|
}
|
|
@@ -31,6 +31,25 @@ import {
|
|
|
31
31
|
} from '../dependencies';
|
|
32
32
|
import { checkDependencyWebAsync } from './webResolver';
|
|
33
33
|
|
|
34
|
+
const deepObjectMerge = (target: any, source: any): any => {
|
|
35
|
+
if (
|
|
36
|
+
source !== undefined &&
|
|
37
|
+
typeof target === 'object' &&
|
|
38
|
+
target != null &&
|
|
39
|
+
!Array.isArray(target) &&
|
|
40
|
+
(!target.constructor || target.constructor === Object) &&
|
|
41
|
+
typeof source === 'object' &&
|
|
42
|
+
!Array.isArray(source)
|
|
43
|
+
) {
|
|
44
|
+
target = { ...target };
|
|
45
|
+
for (const key in source) {
|
|
46
|
+
target[key] = deepObjectMerge(target[key], source[key]);
|
|
47
|
+
}
|
|
48
|
+
return target;
|
|
49
|
+
}
|
|
50
|
+
return source !== undefined ? source : target;
|
|
51
|
+
};
|
|
52
|
+
|
|
34
53
|
const isMissingFBReactNativeSpecCodegenOutput = async (reactNativePath: string) => {
|
|
35
54
|
const generatedDir = path.resolve(reactNativePath, 'React/FBReactNativeSpec');
|
|
36
55
|
try {
|
|
@@ -60,10 +79,6 @@ export async function resolveReactNativeModule(
|
|
|
60
79
|
const libraryConfig = (await loadConfigAsync(
|
|
61
80
|
resolution.path
|
|
62
81
|
)) as RNConfigReactNativeLibraryConfig;
|
|
63
|
-
const reactNativeConfig = {
|
|
64
|
-
...libraryConfig?.dependency,
|
|
65
|
-
...projectConfig?.dependencies?.[resolution.name],
|
|
66
|
-
};
|
|
67
82
|
|
|
68
83
|
if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {
|
|
69
84
|
// Package defines platforms would be a platform host package.
|
|
@@ -71,6 +86,12 @@ export async function resolveReactNativeModule(
|
|
|
71
86
|
return null;
|
|
72
87
|
}
|
|
73
88
|
|
|
89
|
+
let reactNativeConfig = libraryConfig?.dependency ?? {};
|
|
90
|
+
const projectDependencyOverride = projectConfig?.dependencies?.[resolution.name];
|
|
91
|
+
if (projectDependencyOverride != null) {
|
|
92
|
+
reactNativeConfig = deepObjectMerge(reactNativeConfig, projectDependencyOverride);
|
|
93
|
+
}
|
|
94
|
+
|
|
74
95
|
let maybeExpoModuleConfig: ExpoModuleConfig | null | undefined;
|
|
75
96
|
if (!libraryConfig) {
|
|
76
97
|
// NOTE(@kitten): If we don't have an explicit react-native.config.{js,ts} file,
|