expo-modules-autolinking 56.0.2 → 56.0.4

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,16 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 56.0.4 — 2026-05-11
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 56.0.3 — 2026-05-08
18
+
19
+ ### 🐛 Bug fixes
20
+
21
+ - [iOS] Re-stamp `ExpoModulesJSI.xcframework` stub slices on every `pod install` so cached pods can't ship with missing slices. ([#45542](https://github.com/expo/expo/pull/45542) by [@tsapeta](https://github.com/tsapeta))
22
+
13
23
  ## 56.0.2 — 2026-05-06
14
24
 
15
25
  _This version does not introduce any user-facing changes._
@@ -34,18 +34,27 @@ fun Project.defineDefaultProperties(versionCatalogs: Optional<VersionCatalog>) {
34
34
  val kotlin = extra.setIfNotExist("kotlinVersion") { versionCatalogs.getVersionOrDefault("kotlin", "2.0.21") }
35
35
  val ksp = extra.setIfNotExist("kspVersion") {
36
36
  versionCatalogs.getVersionOrDefault("ksp") {
37
- try {
38
- return@getVersionOrDefault KSPLookup.getValue(extra.get("kotlinVersion") as String)
39
- } catch (e: Throwable) {
40
- throw IllegalStateException(
41
- "Can't find KSP version for Kotlin version '${extra.get("kotlinVersion")}'. You're probably using an unsupported version of Kotlin. Supported versions are: '${KSPLookup.keys.joinToString(", ")}'",
42
- e
43
- )
37
+ val kotlinVersion = extra.get("kotlinVersion") as String
38
+
39
+ KSPLookup[kotlinVersion]?.let { return@getVersionOrDefault it }
40
+ if (kotlinVersion >= "2.3.0") {
41
+ return@getVersionOrDefault latestKspVersion
44
42
  }
43
+
44
+ val minSupported = KSPLookup.keys.min()
45
+ throw IllegalStateException(
46
+ """
47
+ Kotlin $kotlinVersion is not supported by Expo modules.
48
+ The minimum supported Kotlin version is $minSupported.
49
+ Update 'kotlinVersion' in your project's build.gradle to a supported version.
50
+ Alternatively, you can set 'kspVersion' explicitly in build.gradle to bypass this check, but this is unsupported and may cause build failures.
51
+ """.trimIndent()
52
+ )
45
53
  }
46
54
  }
47
55
 
48
- project.logger.quiet("""
56
+ project.logger.quiet(
57
+ """
49
58
  ${"[ExpoRootProject]".withColor(Colors.GREEN)} Using the following versions:
50
59
  - buildTools: ${buildTools.withColor(Colors.GREEN)}
51
60
  - minSdk: ${minSdk.withColor(Colors.GREEN)}
@@ -54,7 +63,8 @@ fun Project.defineDefaultProperties(versionCatalogs: Optional<VersionCatalog>) {
54
63
  - ndk: ${ndk.withColor(Colors.GREEN)}
55
64
  - kotlin: ${kotlin.withColor(Colors.GREEN)}
56
65
  - ksp: ${ksp.withColor(Colors.GREEN)}
57
- """.trimIndent())
66
+ """.trimIndent()
67
+ )
58
68
  }
59
69
 
60
70
  inline fun ExtraPropertiesExtension.setIfNotExist(name: String, value: () -> Any): Any? {
@@ -1,20 +1,15 @@
1
1
  // Copyright 2015-present 650 Industries. All rights reserved.
2
- // Generated using './scripts/generateKSPLookUp.js'
3
2
  package expo.modules.plugin
4
3
 
4
+ // Starting with KSP 2.3.0, KSP is no longer tied to a specific Kotlin version.
5
+ const val latestKspVersion = "2.3.7"
6
+
7
+ // For older Kotlin versions, KSP releases were tied to specific Kotlin versions.
5
8
  val KSPLookup = mapOf(
6
9
  "2.2.21" to "2.2.21-2.0.5",
7
- "2.3.1" to "2.3.1",
8
- "2.3.0" to "2.3.0",
9
10
  "2.2.20" to "2.2.20-2.0.4",
10
11
  "2.2.10" to "2.2.10-2.0.2",
11
12
  "2.2.0" to "2.2.0-2.0.2",
12
13
  "2.1.21" to "2.1.21-2.0.2",
13
- "2.1.20" to "2.1.20-2.0.1",
14
- "2.1.10" to "2.1.10-1.0.31",
15
- "2.1.0" to "2.1.0-1.0.29",
16
- "2.0.21" to "2.0.21-1.0.28",
17
- "2.0.20" to "2.0.20-1.0.25",
18
- "2.0.10" to "2.0.10-1.0.24",
19
- "2.0.0" to "2.0.0-1.0.24"
14
+ "2.1.20" to "2.1.20-2.0.1"
20
15
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-autolinking",
3
- "version": "56.0.2",
3
+ "version": "56.0.4",
4
4
  "description": "Scripts that autolink Expo modules.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -41,15 +41,15 @@
41
41
  "homepage": "https://github.com/expo/expo/tree/main/packages/expo-modules-autolinking#readme",
42
42
  "devDependencies": {
43
43
  "memfs": "^3.2.0",
44
- "expo-module-scripts": "56.0.1"
44
+ "expo-module-scripts": "56.0.2"
45
45
  },
46
46
  "dependencies": {
47
- "@expo/require-utils": "^56.0.0",
47
+ "@expo/require-utils": "^56.1.0",
48
48
  "@expo/spawn-async": "^1.7.2",
49
49
  "chalk": "^4.1.0",
50
50
  "commander": "^7.2.0"
51
51
  },
52
- "gitHead": "d2109c94206280625a070242b0cb6e2500357c46",
52
+ "gitHead": "42013232893cb2aa71ab218e9b422d4a8476b3f0",
53
53
  "scripts": {
54
54
  "build": "expo-module build",
55
55
  "clean": "expo-module clean",
@@ -84,10 +84,19 @@ module Pod
84
84
 
85
85
  private
86
86
 
87
- # Creates the stub xcframework for ExpoModulesJSI if it doesn't exist.
88
- # CocoaPods only runs prepare_command when a pod is freshly downloaded or
89
- # its podspec changes, so CI cache hits skip it. This method runs on every
90
- # pod install to guarantee the stub is always present.
87
+ # Ensures every slice declared by ExpoModulesJSI's podspec exists in
88
+ # `Products/ExpoModulesJSI.xcframework`. CocoaPods only runs
89
+ # prepare_command when a pod is freshly downloaded or its podspec
90
+ # changes, so CI cache hits skip it. This method runs on every pod
91
+ # install to guarantee every declared slice is present — an xcframework
92
+ # with only some slices (e.g. simulator-only after a prior Debug build)
93
+ # breaks the per-slice copy script CocoaPods generates from Info.plist,
94
+ # which then leaves XCFrameworkIntermediates empty for the missing slice
95
+ # and surfaces as `No such module 'ExpoModulesJSI'`.
96
+ #
97
+ # The script itself is idempotent and only stamps slices that are
98
+ # missing, so always invoking it is cheaper than maintaining a separate
99
+ # completeness check that would have to mirror the script's slice list.
91
100
  def ensure_expo_modules_jsi_stub_xcframework
92
101
  jsi_target = self.pod_targets.find { |t| t.name == 'ExpoModulesJSI' }
93
102
  return if jsi_target.nil?
@@ -95,9 +104,6 @@ module Pod
95
104
  pod_dir = jsi_target.sandbox.pod_dir('ExpoModulesJSI')
96
105
  return unless File.directory?(pod_dir)
97
106
 
98
- xcframework_path = File.join(pod_dir, 'Products', 'ExpoModulesJSI.xcframework')
99
- return if File.directory?(xcframework_path)
100
-
101
107
  system('./scripts/create-stub-xcframework.sh', chdir: pod_dir.to_s)
102
108
  end
103
109
 
@@ -1,101 +0,0 @@
1
- #!/usr/bin/env node
2
- const { execSync } = require('child_process');
3
- const fs = require('fs');
4
-
5
- const minKotlinVersion = '2.0.0';
6
- const maxKotlinVersion = '2.3.10';
7
-
8
- const groupId = 'com.google.devtools.ksp';
9
- const artifactId = 'symbol-processing-gradle-plugin';
10
- const path = require('path').resolve(
11
- __dirname,
12
- '../android/expo-gradle-plugin/expo-autolinking-plugin/src/main/kotlin/expo/modules/plugin/KSPLookup.kt'
13
- );
14
-
15
- const numberPerPage = 30;
16
- const githubApiPath = '/repos/google/ksp/releases';
17
-
18
- async function* fetchKSPReleases() {
19
- let currentPage = 1;
20
- while (true) {
21
- const apiPath = `${githubApiPath}?per_page=${numberPerPage}&page=${currentPage}`;
22
- console.log(`Fetching versions from: ${apiPath}...`);
23
-
24
- const output = execSync(`gh api "${apiPath}"`, { encoding: 'utf-8' });
25
- const data = JSON.parse(output);
26
- const versions = data
27
- .map((release) => release.tag_name)
28
- // Filter out release candidates, beta and milestone versions
29
- .filter((version) => !/(rc|beta|m1)/i.test(version));
30
-
31
- yield versions;
32
-
33
- currentPage += 1;
34
- }
35
- }
36
-
37
- async function filterByKotinVersion(generator, minKotlinVersion, maxKotlinVersion) {
38
- let hasMoreData = true;
39
- const result = [];
40
- while (hasMoreData) {
41
- const { value } = await generator.next();
42
- const versions = value.map((version) => {
43
- const [kotlinVersion] = version.split('-');
44
- return { kotlinVersion, version };
45
- });
46
-
47
- // If the version is lower than the minKotlinVersion, we can stop fetching more data
48
- hasMoreData = !versions.some(({ kotlinVersion }) => kotlinVersion < minKotlinVersion);
49
-
50
- result.push(
51
- ...versions.filter(
52
- ({ kotlinVersion }) =>
53
- kotlinVersion >= minKotlinVersion && kotlinVersion <= maxKotlinVersion
54
- )
55
- );
56
- }
57
- return result;
58
- }
59
-
60
- // Group versions by kotlinVersion and return the most recent version for each kotlinVersion
61
- function groupByKotlinVersion(versions) {
62
- const mostRecentVersions = {};
63
-
64
- // Fill the mostRecentVersions object with the newest version of each kotlinVersion
65
- versions.forEach(({ kotlinVersion, version }) => {
66
- if (!mostRecentVersions[kotlinVersion] || mostRecentVersions[kotlinVersion] < version) {
67
- mostRecentVersions[kotlinVersion] = version;
68
- }
69
- });
70
-
71
- // Convert the results object back into an array
72
- return Object.entries(mostRecentVersions).map(([kotlinVersion, version]) => ({
73
- kotlinVersion,
74
- version,
75
- }));
76
- }
77
-
78
- async function generateKSPLookup() {
79
- const versionsGenerator = fetchKSPReleases(groupId, artifactId, minKotlinVersion);
80
- const versions = groupByKotlinVersion(
81
- await filterByKotinVersion(versionsGenerator, minKotlinVersion, maxKotlinVersion)
82
- );
83
-
84
- console.log(`Found stable versions for ${groupId}:${artifactId}:`);
85
- for (const { kotlinVersion, version } of versions) {
86
- console.log(` ${kotlinVersion} => ${version}`);
87
- }
88
-
89
- console.log('Genereating KSP lookup file...');
90
- const fileContent = `// Copyright 2015-present 650 Industries. All rights reserved.
91
- // Generated using './scripts/generateKSPLookUp.js'
92
- package expo.modules.plugin
93
-
94
- val KSPLookup = mapOf(
95
- ${versions.map(({ kotlinVersion, version }) => ` "${kotlinVersion}" to "${version}"`).join(',\n')}
96
- )
97
- `;
98
- fs.writeFileSync(path, fileContent, 'utf-8');
99
- }
100
-
101
- generateKSPLookup();