expo-modules-autolinking 55.0.7 → 55.0.8

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,10 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.8 — 2026-02-25
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
13
17
  ## 55.0.7 — 2026-02-20
14
18
 
15
19
  _This version does not introduce any user-facing changes._
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-autolinking",
3
- "version": "55.0.7",
3
+ "version": "55.0.8",
4
4
  "description": "Scripts that autolink Expo modules.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -38,10 +38,10 @@
38
38
  "memfs": "^3.2.0"
39
39
  },
40
40
  "dependencies": {
41
- "@expo/require-utils": "^55.0.1",
41
+ "@expo/require-utils": "^55.0.2",
42
42
  "@expo/spawn-async": "^1.7.2",
43
43
  "chalk": "^4.1.0",
44
44
  "commander": "^7.2.0"
45
45
  },
46
- "gitHead": "22e2ad4afba05b91f833f8cf07a36637748a1f70"
46
+ "gitHead": "b183e5cbd95eb6ee54a878291c7077d8d63e4850"
47
47
  }
@@ -1,466 +0,0 @@
1
- import groovy.json.JsonSlurper
2
- import java.nio.file.Paths
3
-
4
-
5
- // Object representing a gradle project.
6
- class ExpoModuleGradleProject {
7
- // Name of the Android project
8
- String name
9
-
10
- // Path to the folder with Android project
11
- String sourceDir
12
-
13
- // Gradle projects containing AAR files
14
- ExpoModuleGradleAarProject[] aarProjects
15
-
16
- ExpoModuleGradleProject(Object data) {
17
- this.name = data.name
18
- this.sourceDir = data.sourceDir
19
- this.aarProjects = data.aarProjects.collect { new ExpoModuleGradleAarProject(it) }
20
- }
21
- }
22
-
23
- // Object representing a gradle plugin
24
- class ExpoModuleGradlePlugin {
25
- // ID of the gradle plugin
26
- String id
27
-
28
- // Artifact group
29
- String group
30
-
31
- // Path to the plugin folder
32
- String sourceDir
33
-
34
- Boolean applyToRootProject
35
-
36
- ExpoModuleGradlePlugin(Object data) {
37
- this.id = data.id
38
- this.group = data.group
39
- this.sourceDir = data.sourceDir
40
- this.applyToRootProject = data.applyToRootProject
41
- }
42
- }
43
-
44
- // Object representing an gradle project containing AAR file
45
- class ExpoModuleGradleAarProject {
46
- // Name of the project
47
- String name
48
-
49
- // Path to the AAR file
50
- String aarFilePath
51
-
52
- // Project directory
53
- String projectDir
54
-
55
- ExpoModuleGradleAarProject(Object data) {
56
- this.name = data.name
57
- this.aarFilePath = data.aarFilePath
58
- this.projectDir = data.projectDir
59
- }
60
- }
61
-
62
- // Object representing a module.
63
- class ExpoModule {
64
- // Name of the JavaScript package
65
- String name
66
-
67
- // Version of the package, loaded from `package.json`
68
- String version
69
-
70
- // Gradle projects
71
- ExpoModuleGradleProject[] projects
72
-
73
- // Gradle plugins
74
- ExpoModuleGradlePlugin[] plugins
75
-
76
- ExpoModule(Object data) {
77
- this.name = data.packageName
78
- this.version = data.packageVersion
79
- this.projects = data.projects.collect { new ExpoModuleGradleProject(it) }
80
- this.plugins = data.plugins.collect { new ExpoModuleGradlePlugin(it) }
81
- }
82
-
83
- List<ExpoModuleGradleAarProject> allAarProjects() {
84
- return projects.collect { it.aarProjects }.flatten()
85
- }
86
- }
87
-
88
- // Object representing a maven repository.
89
- class MavenRepo {
90
- String url
91
- Object credentials
92
- String authentication
93
-
94
- MavenRepo(Object data) {
95
- this.url = data.url
96
- this.credentials = data.credentials
97
- this.authentication = data.authentication
98
- }
99
- }
100
-
101
- class ExpoAutolinkingManager {
102
- private File projectDir
103
- private Map options
104
- private Object cachedResolvingResults
105
-
106
- static String generatedPackageListNamespace = 'expo.modules'
107
- static String generatedPackageListFilename = 'ExpoModulesPackageList.kt'
108
- static String generatedFilesSrcDir = 'generated/expo/src/main/java'
109
-
110
- ExpoAutolinkingManager(File projectDir, Map options = [:]) {
111
- this.projectDir = projectDir
112
- this.options = options
113
- }
114
-
115
- Object resolve(ProviderFactory providers, shouldUseCachedValue=false) {
116
- if (cachedResolvingResults) {
117
- return cachedResolvingResults
118
- }
119
- if (shouldUseCachedValue) {
120
- logger.warn("Warning: Expo modules were resolved multiple times. Probably something is wrong with the project configuration.")
121
- }
122
- String[] args = convertOptionsToCommandArgs('resolve', this.options)
123
- args += ['--json']
124
-
125
- String output = providers.exec {
126
- workingDir(projectDir)
127
- commandLine(args)
128
- }.standardOutput.asText.get().trim()
129
- Object json = new JsonSlurper().parseText(output)
130
-
131
- cachedResolvingResults = json
132
- return json
133
- }
134
-
135
- boolean shouldUseAAR() {
136
- return options?.useAAR == true
137
- }
138
-
139
- ExpoModule[] getModules(ProviderFactory providers, shouldUseCachedValue=false) {
140
- Object json = resolve(providers, shouldUseCachedValue)
141
- return json.modules.collect { new ExpoModule(it) }
142
- }
143
-
144
- MavenRepo[] getExtraMavenRepos(ProviderFactory providers, shouldUseCachedValue=false) {
145
- Object json = resolve(providers, shouldUseCachedValue)
146
- return json.extraDependencies.collect { new MavenRepo(it) }
147
- }
148
-
149
- static String getGeneratedFilePath(Project project) {
150
- return Paths.get(
151
- project.buildDir.toString(),
152
- generatedFilesSrcDir,
153
- generatedPackageListNamespace.replace('.', '/'),
154
- generatedPackageListFilename
155
- ).toString()
156
- }
157
-
158
- static void generatePackageList(Project project, Map options) {
159
- String[] args = convertOptionsToCommandArgs('generate-package-list', options)
160
-
161
- // Construct absolute path to generated package list.
162
- def generatedFilePath = getGeneratedFilePath(project)
163
-
164
- args += [
165
- '--namespace',
166
- generatedPackageListNamespace,
167
- '--target',
168
- generatedFilePath
169
- ]
170
-
171
- if (options == null) {
172
- // Options are provided only when settings.gradle was configured.
173
- // If not or opted-out from autolinking, the generated list should be empty.
174
- args += '--empty'
175
- }
176
-
177
- project.providers.exec {
178
- workingDir(project.rootDir)
179
- commandLine(args)
180
- }.result.get().assertNormalExitValue()
181
- }
182
-
183
- static private String[] convertOptionsToCommandArgs(String command, Map options) {
184
- String[] args = [
185
- 'node',
186
- '--no-warnings',
187
- '--eval',
188
- 'require(\'expo/bin/autolinking\')',
189
- 'expo-modules-autolinking',
190
- command,
191
- '--platform',
192
- 'android'
193
- ]
194
-
195
- def searchPaths = options?.get("searchPaths", options?.get("modulesPaths", null))
196
- if (searchPaths) {
197
- args += searchPaths
198
- }
199
-
200
- if (options?.ignorePaths) {
201
- args += '--ignore-paths'
202
- args += options.ignorePaths
203
- }
204
-
205
- if (options?.exclude) {
206
- args += '--exclude'
207
- args += options.exclude
208
- }
209
-
210
- return args
211
- }
212
- }
213
-
214
- class Colors {
215
- static final String GREEN = "\u001B[32m"
216
- static final String YELLOW = "\u001B[33m"
217
- static final String RESET = "\u001B[0m"
218
- }
219
- class Emojis {
220
- static final String INFORMATION = "\u2139\uFE0F"
221
- }
222
-
223
- // We can't cast a manager that is created in `settings.gradle` to the `ExpoAutolinkingManager`
224
- // because if someone is using `buildSrc`, the `ExpoAutolinkingManager` class
225
- // will be loaded by two different class loader - `settings.gradle` will use a diffrent loader.
226
- // In the JVM, classes are equal only if were loaded by the same loader.
227
- // There is nothing that we can do in that case, but to make our code safer, we check if the class name is the same.
228
- def validateExpoAutolinkingManager(manager) {
229
- assert ExpoAutolinkingManager.name == manager.getClass().name
230
- return manager
231
- }
232
-
233
- // Here we split the implementation, depending on Gradle context.
234
- // `rootProject` is a `ProjectDescriptor` if this file is imported in `settings.gradle` context,
235
- // otherwise we can assume it is imported in `build.gradle`.
236
- if (rootProject instanceof ProjectDescriptor) {
237
- // Method to be used in `settings.gradle`. Options passed here will have an effect in `build.gradle` context as well,
238
- // i.e. adding the dependencies and generating the package list.
239
- ext.useExpoModules = { Map options = [:] ->
240
- ExpoAutolinkingManager manager = new ExpoAutolinkingManager(rootProject.projectDir, options)
241
- ExpoModule[] modules = manager.getModules(providers)
242
- MavenRepo[] extraMavenRepos = manager.getExtraMavenRepos(providers)
243
-
244
- for (module in modules) {
245
- for (moduleProject in module.projects) {
246
- include(":${moduleProject.name}")
247
- project(":${moduleProject.name}").projectDir = new File(moduleProject.sourceDir)
248
- }
249
- for (modulePlugin in module.plugins) {
250
- includeBuild(new File(modulePlugin.sourceDir))
251
- }
252
- for (moduleAarProject in module.allAarProjects()) {
253
- include(":${moduleAarProject.name}")
254
- def projectDir = new File(moduleAarProject.projectDir)
255
- if (!projectDir.exists()) {
256
- projectDir.mkdirs()
257
- }
258
- project(":${moduleAarProject.name}").projectDir = projectDir
259
- }
260
- }
261
-
262
- gradle.beforeProject { project ->
263
- // Setup AAR projects
264
- for (module in modules) {
265
- for (moduleAarProject in module.allAarProjects()) {
266
- if (project.name == moduleAarProject.name) {
267
- project.configurations.maybeCreate('default')
268
- project.artifacts.add('default', file(moduleAarProject.aarFilePath))
269
- }
270
- }
271
- }
272
-
273
- // Setup autolinking from the root project
274
- if (project !== project.rootProject) {
275
- return
276
- }
277
- def rootProject = project
278
-
279
- // Add plugin classpath to the root project
280
- for (module in modules) {
281
- for (modulePlugin in module.plugins) {
282
- rootProject.buildscript.dependencies.add('classpath', "${modulePlugin.group}:${modulePlugin.id}")
283
- }
284
- }
285
-
286
- // Add extra maven repositories to allprojects
287
- for (mavenRepo in extraMavenRepos) {
288
- println "Adding extra maven repository - '${mavenRepo.url}'"
289
- }
290
- rootProject.allprojects { eachProject ->
291
- eachProject.repositories {
292
- for (mavenRepo in extraMavenRepos) {
293
- maven {
294
- url "${mavenRepo.url}"
295
- if (mavenRepo.credentials != null) {
296
- if (mavenRepo.credentials.username && mavenRepo.credentials.password) {
297
- credentials {
298
- username mavenRepo.credentials.username
299
- password mavenRepo.credentials.password
300
- }
301
- } else if (mavenRepo.credentials.name && mavenRepo.credentials.value) {
302
- credentials(HttpHeaderCredentials) {
303
- name mavenRepo.credentials.name
304
- value mavenRepo.credentials.value
305
- }
306
- } else if (mavenRepo.credentials.accessKey && mavenRepo.credentials.secretKey) {
307
- credentials(AwsCredentials) {
308
- accessKey mavenRepo.credentials.accessKey
309
- secretKey mavenRepo.credentials.secretKey
310
- sessionToken mavenRepo.credentials.sessionToken
311
- }
312
- }
313
- }
314
- if (mavenRepo.authentication != null) {
315
- authentication {
316
- if (mavenRepo.authentication == "basic") {
317
- basic(BasicAuthentication)
318
- } else if (mavenRepo.authentication == "digest") {
319
- digest(DigestAuthentication)
320
- } else if (mavenRepo.authentication == "header") {
321
- header(HttpHeaderAuthentication)
322
- }
323
- }
324
- }
325
- }
326
- }
327
- }
328
- }
329
- }
330
-
331
- // Apply plugins for all app projects
332
- gradle.afterProject { project ->
333
- if (!project.plugins.hasPlugin('com.android.application')) {
334
- return
335
- }
336
- for (module in modules) {
337
- for (modulePlugin in module.plugins) {
338
- if (!modulePlugin.applyToRootProject) {
339
- continue
340
- }
341
- println " ${Emojis.INFORMATION} ${Colors.YELLOW}Applying gradle plugin${Colors.RESET} '${Colors.GREEN}${modulePlugin.id}${Colors.RESET}' (${module.name}@${module.version})"
342
- project.plugins.apply(modulePlugin.id)
343
- }
344
- }
345
- }
346
-
347
- // Save the manager in the shared context, so that we can later use it in `build.gradle`.
348
- gradle.ext.expoAutolinkingManager = manager
349
- }
350
- } else {
351
- def addModule = { DependencyHandler handler, String projectName, Boolean useAAR ->
352
- Project dependency = rootProject.project(":${projectName}")
353
-
354
- if (useAAR) {
355
- handler.add('api', "${dependency.group}:${projectName}:${dependency.version}")
356
- } else {
357
- handler.add('api', dependency)
358
- }
359
- }
360
-
361
- def addDependencies = { DependencyHandler handler, Project project ->
362
- def manager = validateExpoAutolinkingManager(gradle.ext.expoAutolinkingManager)
363
- def modules = manager.getModules(project.providers, true)
364
-
365
- if (!modules.length) {
366
- return
367
- }
368
-
369
- println ''
370
- println 'Using expo modules'
371
-
372
- for (module in modules) {
373
- // Don't link itself
374
- if (module.name == project.name) {
375
- continue
376
- }
377
- // Can remove this once we move all the interfaces into the core.
378
- if (module.name.endsWith('-interface')) {
379
- continue
380
- }
381
-
382
- for (moduleProject in module.projects) {
383
- addModule(handler, moduleProject.name, manager.shouldUseAAR())
384
- println " - ${Colors.GREEN}${moduleProject.name}${Colors.RESET} (${module.version})"
385
- }
386
- }
387
-
388
- println ''
389
- }
390
-
391
- // Adding dependencies
392
- ext.addExpoModulesDependencies = { DependencyHandler handler, Project project ->
393
- // Return early if `useExpoModules` was not called in `settings.gradle`
394
- if (!gradle.ext.has('expoAutolinkingManager')) {
395
- logger.error('Error: Autolinking is not set up in `settings.gradle`: expo modules won\'t be autolinked.')
396
- return
397
- }
398
-
399
- def manager = validateExpoAutolinkingManager(gradle.ext.expoAutolinkingManager)
400
-
401
- if (rootProject.findProject(':expo-modules-core')) {
402
- // `expo` requires `expo-modules-core` as a dependency, even if autolinking is turned off.
403
- addModule(handler, 'expo-modules-core', manager.shouldUseAAR())
404
- } else {
405
- logger.error('Error: `expo-modules-core` project is not included by autolinking.')
406
- }
407
-
408
- // If opted-in not to autolink modules as dependencies
409
- if (manager.options == null) {
410
- return
411
- }
412
-
413
- addDependencies(handler, project)
414
- }
415
-
416
- // Generating the package list
417
- ext.generatedFilesSrcDir = ExpoAutolinkingManager.generatedFilesSrcDir
418
-
419
- ext.generateExpoModulesPackageList = {
420
- // Get options used in `settings.gradle` or null if it wasn't set up.
421
- Map options = gradle.ext.has('expoAutolinkingManager') ? gradle.ext.expoAutolinkingManager.options : null
422
-
423
- if (options == null) {
424
- // TODO(@tsapeta): Temporarily muted this error — uncomment it once we start migrating from autolinking v1 to v2
425
- // logger.error('Autolinking is not set up in `settings.gradle`: generated package list with expo modules will be empty.')
426
- }
427
- ExpoAutolinkingManager.generatePackageList(project, options)
428
- }
429
-
430
- ext.getGenerateExpoModulesPackagesListPath = {
431
- return ExpoAutolinkingManager.getGeneratedFilePath(project)
432
- }
433
-
434
- ext.getModulesConfig = {
435
- if (!gradle.ext.has('expoAutolinkingManager')) {
436
- return null
437
- }
438
-
439
- def modules = gradle.ext.expoAutolinkingManager.resolve(project.providers, true).modules
440
- return modules.toString()
441
- }
442
-
443
- ext.ensureDependeciesWereEvaluated = { Project project ->
444
- if (!gradle.ext.has('expoAutolinkingManager')) {
445
- return
446
- }
447
-
448
- def modules = gradle.ext.expoAutolinkingManager.getModules(project.providers, true)
449
- for (module in modules) {
450
- for (moduleProject in module.projects) {
451
- def dependency = project.findProject(":${moduleProject.name}")
452
- if (dependency == null) {
453
- logger.warn("Coudn't find project ${moduleProject.name}. Please, make sure that `useExpoModules` was called in `settings.gradle`.")
454
- continue
455
- }
456
-
457
- // Prevent circular dependencies
458
- if (moduleProject.name == project.name) {
459
- continue
460
- }
461
-
462
- project.evaluationDependsOn(":${moduleProject.name}")
463
- }
464
- }
465
- }
466
- }