peachsim 0.1.2194 → 0.1.2195
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/README.md +4 -1
- package/cli/commands/control.ts +2 -0
- package/cli/commands/kotlin.ts +10 -3
- package/cli/commands/package.ts +2 -0
- package/cli/native-input.ts +2 -0
- package/cli/outbound-endpoints.ts +1 -1
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/bundle-channel.cjs +986 -785
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/config.mjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +3 -3
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +991 -790
- package/dist-lib/host/fetch-proxy-handler.cjs +2 -2
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +2 -2
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +82 -13
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +2 -2
- package/dist-lib/native-app-identity-project.cjs +1 -1
- package/dist-lib/native-app-identity-project.mjs +1 -1
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.mjs +1 -1
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/pdfium-raster.cjs +1 -1
- package/dist-lib/pdfium-raster.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/public-origins-lib-esm.json +24 -24
- package/dist-lib/public-origins-lib.json +65 -62
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/reap-browser.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +1513 -1264
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +2 -2
- package/dist-lib/vite.cjs +2 -2
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/dist-types/packages/peach-engine/src/engine/types.d.ts +1 -0
- package/kotlin/sdk.tar.gz +0 -0
- package/package.json +1 -1
- package/src/android-bridge-dependencies.ts +93 -0
- package/src/android-bridge-packages.ts +1 -0
- package/src/android-gradle-sources.ts +76 -9
- package/src/androidGradleContract.ts +8 -0
- package/src/expo-kotlin-host.ts +20 -7
- package/src/expoKotlinContract.ts +1 -1
- package/src/java-module-abi.ts +7 -1
- package/src/kotlin-app.ts +120 -63
- package/src/kotlin-host.ts +1 -0
- package/src/kotlinSdkContract.ts +8 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/vite-swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -30614,7 +30614,7 @@ function sourceClosureDigest(srcDir, entrypoints) {
|
|
|
30614
30614
|
return hash.digest("hex");
|
|
30615
30615
|
}
|
|
30616
30616
|
var standinSourceDigest = (srcDir = __sootsim_import_meta_dirname) => sourceClosureDigest(srcDir, STANDIN_DIGEST_ENTRYPOINTS);
|
|
30617
|
-
var STANDIN_SOURCE_DIGEST = true ? "
|
|
30617
|
+
var STANDIN_SOURCE_DIGEST = true ? "afff2f6ba145885813b507114e72f9218f9a815a257ab2e44f7da376b7bf5cd1" : standinSourceDigest();
|
|
30618
30618
|
|
|
30619
30619
|
// src/swift-standins.ts
|
|
30620
30620
|
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1909,7 +1909,7 @@ function readIosSdkTree(root) {
|
|
|
1909
1909
|
|
|
1910
1910
|
// src/swift-standin-digest.ts
|
|
1911
1911
|
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
1912
|
-
var STANDIN_SOURCE_DIGEST = true ? "
|
|
1912
|
+
var STANDIN_SOURCE_DIGEST = true ? "afff2f6ba145885813b507114e72f9218f9a815a257ab2e44f7da376b7bf5cd1" : standinSourceDigest();
|
|
1913
1913
|
|
|
1914
1914
|
// src/expo-native-workspace.ts
|
|
1915
1915
|
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2195 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/kotlin/sdk.tar.gz
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { resolveReactNativeAndroidAutolinking } from './android-autolinking'
|
|
4
|
+
import { resolveAndroidGradleSources } from './android-gradle-sources'
|
|
5
|
+
import { readJavaModuleSpecs } from './java-module-abi'
|
|
6
|
+
import { installKotlinSdkArchive } from './kotlin-sdk'
|
|
7
|
+
import { ensureToolchain, readToolchain } from './kotlin-toolchain'
|
|
8
|
+
import type { BridgePackage, BridgeSelection } from './android-bridge-packages'
|
|
9
|
+
|
|
10
|
+
export async function collectAndroidBridgeDependencies(
|
|
11
|
+
appRoot: string,
|
|
12
|
+
moduleRoot: string,
|
|
13
|
+
): Promise<BridgeSelection | null> {
|
|
14
|
+
const root = path.join(appRoot, 'android')
|
|
15
|
+
if (!fs.existsSync(path.join(root, 'gradlew'))) return null
|
|
16
|
+
const dependencies = (await resolveReactNativeAndroidAutolinking(appRoot)).flatMap(
|
|
17
|
+
(dependency) =>
|
|
18
|
+
dependency.sourceDir === null || dependency.packageInstance === null
|
|
19
|
+
? []
|
|
20
|
+
: [
|
|
21
|
+
{
|
|
22
|
+
...dependency,
|
|
23
|
+
sourceDir: dependency.sourceDir,
|
|
24
|
+
packageInstance: dependency.packageInstance,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
)
|
|
28
|
+
if (dependencies.length === 0) return null
|
|
29
|
+
const models = await resolveAndroidGradleSources({
|
|
30
|
+
root,
|
|
31
|
+
projects: [
|
|
32
|
+
path.join(root, 'app'),
|
|
33
|
+
...dependencies.map((dependency) => dependency.sourceDir),
|
|
34
|
+
],
|
|
35
|
+
variant: 'debug',
|
|
36
|
+
})
|
|
37
|
+
const applicationId = models[0].applicationId
|
|
38
|
+
if (applicationId === null) throw new Error(`${root}/app is not an Android application`)
|
|
39
|
+
const toolchain = readToolchain(moduleRoot)
|
|
40
|
+
const [sdk, ready] = await Promise.all([
|
|
41
|
+
installKotlinSdkArchive(
|
|
42
|
+
fs.readFileSync(path.join(moduleRoot, 'sdk.tar.gz')),
|
|
43
|
+
toolchain.compiler.sha256,
|
|
44
|
+
),
|
|
45
|
+
ensureToolchain(toolchain),
|
|
46
|
+
])
|
|
47
|
+
const packages: BridgePackage[] = []
|
|
48
|
+
for (const dependency of dependencies) {
|
|
49
|
+
const model = models.find(
|
|
50
|
+
(entry) => entry.projectDir === fs.realpathSync(dependency.sourceDir),
|
|
51
|
+
)!
|
|
52
|
+
try {
|
|
53
|
+
const className = /^import\s+([\w.]+)\s*;$/.exec(
|
|
54
|
+
dependency.packageImportPath ?? '',
|
|
55
|
+
)?.[1]
|
|
56
|
+
const constructor = /^new\s+([\w.]+)\s*\(\s*\)$/.exec(
|
|
57
|
+
dependency.packageInstance,
|
|
58
|
+
)?.[1]
|
|
59
|
+
if (
|
|
60
|
+
!className ||
|
|
61
|
+
(constructor !== className && constructor !== className.split('.').pop())
|
|
62
|
+
)
|
|
63
|
+
throw new Error(
|
|
64
|
+
'native package registration requires a constructor without arguments',
|
|
65
|
+
)
|
|
66
|
+
const declarations = await readJavaModuleSpecs(model.java, sdk.root, ready)
|
|
67
|
+
const modules = declarations.specs.flatMap((spec) =>
|
|
68
|
+
spec.name === null
|
|
69
|
+
? []
|
|
70
|
+
: [
|
|
71
|
+
{
|
|
72
|
+
className: spec.className,
|
|
73
|
+
name: spec.name,
|
|
74
|
+
methods: spec.methods,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
)
|
|
78
|
+
if (modules.length === 0) continue
|
|
79
|
+
packages.push({
|
|
80
|
+
className,
|
|
81
|
+
modules,
|
|
82
|
+
sources: model.kotlin,
|
|
83
|
+
javaSpecs: model.java,
|
|
84
|
+
unsupported: null,
|
|
85
|
+
})
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(
|
|
88
|
+
`[peach] ${dependency.name} native source is unavailable: ${error instanceof Error ? error.message : String(error)}`,
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return packages.length ? { applicationId, packages } : null
|
|
93
|
+
}
|
|
@@ -7,6 +7,7 @@ import { PEACH_FORKED_SCRIPT_ENV } from './forked-script-contract'
|
|
|
7
7
|
import { isRecord } from './is-record'
|
|
8
8
|
import { kotlinHome } from './kotlin-toolchain'
|
|
9
9
|
import type {
|
|
10
|
+
AndroidGradleDependency,
|
|
10
11
|
AndroidGradleSourceRequest,
|
|
11
12
|
AndroidGradleSources,
|
|
12
13
|
} from './androidGradleContract'
|
|
@@ -15,8 +16,26 @@ const run = promisify(execFile)
|
|
|
15
16
|
const modelQuery = `
|
|
16
17
|
import groovy.json.JsonOutput
|
|
17
18
|
import groovy.json.JsonSlurper
|
|
19
|
+
import org.gradle.api.artifacts.FileCollectionDependency
|
|
20
|
+
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
|
|
21
|
+
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
|
22
|
+
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
|
23
|
+
import org.gradle.api.attributes.Category
|
|
18
24
|
|
|
19
25
|
def request = new JsonSlurper().parseText(new String(Base64.decoder.decode('__PEACH_REQUEST__'), 'UTF-8'))
|
|
26
|
+
def selectedVariants = [:]
|
|
27
|
+
gradle.beforeProject { project ->
|
|
28
|
+
def directory = project.projectDir.canonicalPath
|
|
29
|
+
if (project.rootProject.projectDir.canonicalPath != request.root || !request.projects.contains(directory)) return
|
|
30
|
+
['com.android.application', 'com.android.library'].each { plugin ->
|
|
31
|
+
project.pluginManager.withPlugin(plugin) {
|
|
32
|
+
def components = project.extensions.getByName('androidComponents')
|
|
33
|
+
components.onVariants(components.selector().withName(request.variant)) { variant ->
|
|
34
|
+
selectedVariants[directory] = variant
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
20
39
|
gradle.projectsEvaluated {
|
|
21
40
|
if (gradle.rootProject.projectDir.canonicalPath != request.root) return
|
|
22
41
|
def selected = []
|
|
@@ -31,19 +50,15 @@ gradle.projectsEvaluated {
|
|
|
31
50
|
if (!library && !project.pluginManager.hasPlugin('com.android.application')) {
|
|
32
51
|
throw new GradleException('Project has no Android application or library plugin: ' + project.path)
|
|
33
52
|
}
|
|
34
|
-
def
|
|
35
|
-
def variants = library ? android.libraryVariants : android.applicationVariants
|
|
36
|
-
def variant = variants.find { it.name == request.variant }
|
|
53
|
+
def variant = selectedVariants[directory]
|
|
37
54
|
if (variant == null) throw new GradleException('Android variant ' + request.variant + ' is absent: ' + project.path)
|
|
38
55
|
def generators = []
|
|
39
|
-
def buildConfig = variant.generateBuildConfigProvider
|
|
40
|
-
if (buildConfig != null) generators.add(buildConfig)
|
|
41
56
|
if (project.pluginManager.hasPlugin('com.facebook.react')) {
|
|
42
57
|
generators.add(project.tasks.named('generateCodegenArtifactsFromSchema'))
|
|
43
58
|
}
|
|
44
59
|
def kotlin = project.tasks.findByName('compile' + variant.name.capitalize() + 'Kotlin')
|
|
45
60
|
def kotlinSources = kotlin == null ? project.files() : kotlin.sources
|
|
46
|
-
def javaSources = variant.
|
|
61
|
+
def javaSources = project.tasks.named('compile' + variant.name.capitalize() + 'JavaWithJavac').get().source
|
|
47
62
|
def query = project.tasks.register(request.task) {
|
|
48
63
|
dependsOn(generators)
|
|
49
64
|
dependsOn(kotlinSources.buildDependencies, javaSources.buildDependencies)
|
|
@@ -51,13 +66,31 @@ gradle.projectsEvaluated {
|
|
|
51
66
|
def files = (kotlinSources.files + javaSources.files).unique()
|
|
52
67
|
def unknown = files.find { !it.name.endsWith('.kt') && !it.name.endsWith('.java') }
|
|
53
68
|
if (unknown != null) throw new GradleException('Unsupported Android source: ' + unknown)
|
|
69
|
+
def dependencies = [variant.compileConfiguration, variant.runtimeConfiguration].collectMany { configuration ->
|
|
70
|
+
def modules = configuration.incoming.resolutionResult.rootComponent.get().dependencies.findAll { !it.constraint }.collectMany { dependency ->
|
|
71
|
+
if (!(dependency instanceof ResolvedDependencyResult)) throw new GradleException('Unresolved Android dependency: ' + dependency.requested, dependency.failure)
|
|
72
|
+
def category = dependency.resolvedVariant.attributes.getAttribute(Category.CATEGORY_ATTRIBUTE)?.name
|
|
73
|
+
if (category == Category.REGULAR_PLATFORM || category == Category.ENFORCED_PLATFORM) return []
|
|
74
|
+
def id = dependency.selected.id
|
|
75
|
+
if (id instanceof ModuleComponentIdentifier) return [[kind:'module', group:id.group, name:id.module, version:id.version]]
|
|
76
|
+
if (id instanceof ProjectComponentIdentifier) return [[kind:'project', name:id.displayName]]
|
|
77
|
+
throw new GradleException('Unsupported Android dependency component: ' + id.displayName)
|
|
78
|
+
}
|
|
79
|
+
def local = configuration.allDependencies.withType(FileCollectionDependency).collectMany { dependency ->
|
|
80
|
+
dependency.files.files.collect { [kind:'file', name:it.absolutePath] }
|
|
81
|
+
}
|
|
82
|
+
modules + local
|
|
83
|
+
}.unique()
|
|
54
84
|
new File(request.output, index.toString() + '.json').text = JsonOutput.toJson([
|
|
55
85
|
projectDir:project.projectDir.canonicalPath,
|
|
56
86
|
projectPath:project.path,
|
|
57
87
|
variant:variant.name,
|
|
58
|
-
applicationId:library ? null : variant.applicationId,
|
|
88
|
+
applicationId:library ? null : variant.applicationId.get(),
|
|
89
|
+
namespace:variant.namespace.get(),
|
|
90
|
+
targetSdk:library ? null : variant.targetSdk.apiLevel,
|
|
59
91
|
kotlin:files.findAll { it.name.endsWith('.kt') }.collect { it.absolutePath }.sort(),
|
|
60
|
-
java:files.findAll { it.name.endsWith('.java') }.collect { it.absolutePath }.sort()
|
|
92
|
+
java:files.findAll { it.name.endsWith('.java') }.collect { it.absolutePath }.sort(),
|
|
93
|
+
dependencies:dependencies
|
|
61
94
|
])
|
|
62
95
|
}
|
|
63
96
|
}
|
|
@@ -97,6 +130,7 @@ export async function resolveAndroidGradleSources(
|
|
|
97
130
|
`${task}All`,
|
|
98
131
|
'--no-daemon',
|
|
99
132
|
'--no-configuration-cache',
|
|
133
|
+
'--no-configure-on-demand',
|
|
100
134
|
'--max-workers=1',
|
|
101
135
|
'--console=plain',
|
|
102
136
|
],
|
|
@@ -116,7 +150,13 @@ export async function resolveAndroidGradleSources(
|
|
|
116
150
|
value.projectDir !== projectDir ||
|
|
117
151
|
value.variant !== variant ||
|
|
118
152
|
typeof value.projectPath !== 'string' ||
|
|
119
|
-
(value.applicationId !== null && typeof value.applicationId !== 'string')
|
|
153
|
+
(value.applicationId !== null && typeof value.applicationId !== 'string') ||
|
|
154
|
+
typeof value.namespace !== 'string' ||
|
|
155
|
+
!value.namespace ||
|
|
156
|
+
(value.targetSdk !== null &&
|
|
157
|
+
(typeof value.targetSdk !== 'number' ||
|
|
158
|
+
!Number.isInteger(value.targetSdk) ||
|
|
159
|
+
value.targetSdk <= 0))
|
|
120
160
|
)
|
|
121
161
|
throw new Error('Gradle printed an invalid Android project source model')
|
|
122
162
|
const sources = (field: 'kotlin' | 'java'): string[] => {
|
|
@@ -128,13 +168,40 @@ export async function resolveAndroidGradleSources(
|
|
|
128
168
|
throw new Error(`Gradle printed invalid Android ${field} source paths`)
|
|
129
169
|
return list.map(String)
|
|
130
170
|
}
|
|
171
|
+
if (!Array.isArray(value.dependencies))
|
|
172
|
+
throw new Error('Gradle printed invalid Android dependencies')
|
|
173
|
+
const dependencies = value.dependencies.map(
|
|
174
|
+
(entry: unknown): AndroidGradleDependency => {
|
|
175
|
+
if (isRecord(entry) && typeof entry.name === 'string' && entry.name) {
|
|
176
|
+
if (
|
|
177
|
+
entry.kind === 'module' &&
|
|
178
|
+
typeof entry.group === 'string' &&
|
|
179
|
+
entry.group &&
|
|
180
|
+
typeof entry.version === 'string' &&
|
|
181
|
+
entry.version
|
|
182
|
+
)
|
|
183
|
+
return {
|
|
184
|
+
kind: entry.kind,
|
|
185
|
+
group: entry.group,
|
|
186
|
+
name: entry.name,
|
|
187
|
+
version: entry.version,
|
|
188
|
+
}
|
|
189
|
+
if (entry.kind === 'project' || entry.kind === 'file')
|
|
190
|
+
return { kind: entry.kind, name: entry.name }
|
|
191
|
+
}
|
|
192
|
+
throw new Error('Gradle printed an invalid Android dependency')
|
|
193
|
+
},
|
|
194
|
+
)
|
|
131
195
|
return {
|
|
132
196
|
projectDir,
|
|
133
197
|
projectPath: value.projectPath,
|
|
134
198
|
variant,
|
|
135
199
|
applicationId: value.applicationId,
|
|
200
|
+
namespace: value.namespace,
|
|
201
|
+
targetSdk: value.targetSdk,
|
|
136
202
|
kotlin: sources('kotlin'),
|
|
137
203
|
java: sources('java'),
|
|
204
|
+
dependencies,
|
|
138
205
|
}
|
|
139
206
|
})
|
|
140
207
|
} finally {
|
|
@@ -9,6 +9,14 @@ export interface AndroidGradleSources {
|
|
|
9
9
|
projectPath: string
|
|
10
10
|
variant: string
|
|
11
11
|
applicationId: string | null
|
|
12
|
+
namespace: string
|
|
13
|
+
targetSdk: number | null
|
|
12
14
|
kotlin: string[]
|
|
13
15
|
java: string[]
|
|
16
|
+
dependencies: AndroidGradleDependency[]
|
|
14
17
|
}
|
|
18
|
+
|
|
19
|
+
export type AndroidGradleDependency =
|
|
20
|
+
| { kind: 'module'; group: string; name: string; version: string }
|
|
21
|
+
| { kind: 'project'; name: string }
|
|
22
|
+
| { kind: 'file'; name: string }
|
package/src/expo-kotlin-host.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import fs from 'node:fs'
|
|
6
6
|
import path from 'node:path'
|
|
7
7
|
import { resolveExpoAndroidAutolinking } from './android-autolinking'
|
|
8
|
+
import { collectAndroidBridgeDependencies } from './android-bridge-dependencies'
|
|
8
9
|
import {
|
|
9
10
|
androidAppSources,
|
|
10
11
|
selectBridgePackages,
|
|
@@ -27,7 +28,7 @@ export interface ExpoKotlinModules {
|
|
|
27
28
|
sources: string[]
|
|
28
29
|
javaSpecs?: string[]
|
|
29
30
|
gradleSources?: AndroidGradleSourceRequest
|
|
30
|
-
//
|
|
31
|
+
// React Native package modules, hosted beside the Expo ones
|
|
31
32
|
bridge: BridgeSelection | null
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -113,8 +114,12 @@ export async function collectExpoKotlinModules(
|
|
|
113
114
|
return result.length === 0 && !answeredInstalled ? null : result
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
//
|
|
117
|
+
// native dependency packages followed by the app's own registrations
|
|
117
118
|
async function collectBridgePackages(appRoot: string): Promise<BridgeSelection | null> {
|
|
119
|
+
const dependencies = await collectAndroidBridgeDependencies(
|
|
120
|
+
appRoot,
|
|
121
|
+
peachKotlinModuleRoot(),
|
|
122
|
+
)
|
|
118
123
|
const app = androidAppSources(appRoot)
|
|
119
124
|
if (
|
|
120
125
|
!app ||
|
|
@@ -122,11 +127,14 @@ async function collectBridgePackages(appRoot: string): Promise<BridgeSelection |
|
|
|
122
127
|
/\b(?:Base|Turbo)?ReactPackage\b/.test(fs.readFileSync(file, 'utf8')),
|
|
123
128
|
)
|
|
124
129
|
)
|
|
125
|
-
return
|
|
130
|
+
return dependencies
|
|
126
131
|
const { scanBridgeFiles } = await import('./kotlin-host')
|
|
127
132
|
const files = await scanBridgeFiles(peachKotlinModuleRoot(), app.kotlin)
|
|
128
133
|
const selection = selectBridgePackages(app.applicationId, files, app.java)
|
|
129
|
-
|
|
134
|
+
const packages = [...(dependencies?.packages ?? []), ...selection.packages]
|
|
135
|
+
return packages.length
|
|
136
|
+
? { applicationId: dependencies?.applicationId ?? selection.applicationId, packages }
|
|
137
|
+
: null
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
export async function compileExpoKotlinModules(
|
|
@@ -190,22 +198,27 @@ export async function compileExpoKotlinModules(
|
|
|
190
198
|
const artifact = await expoKotlinArtifact(root, peachKotlinModuleRoot(), origin, {
|
|
191
199
|
modules,
|
|
192
200
|
sources,
|
|
201
|
+
javaSpecs: [...new Set(hosted.flatMap((entry) => entry.javaSpecs ?? []))],
|
|
193
202
|
bridge: selection && { applicationId: selection.applicationId, packages: hosted },
|
|
194
203
|
})
|
|
195
204
|
return result(artifact)
|
|
196
205
|
} catch (error) {
|
|
197
206
|
const message = error instanceof Error ? error.message : String(error)
|
|
198
207
|
// kotlinc names each failing source line; anything else is the host's
|
|
199
|
-
const errors = message.match(/^.+\.kt:\d+:\d+: error:.*$/gm)
|
|
208
|
+
const errors = message.match(/^.+\.(?:kt|java):\d+:\d+: error:.*$/gm)
|
|
200
209
|
if (!errors) throw error
|
|
201
210
|
const linesFor = (sources: string[]) =>
|
|
202
211
|
errors.filter((line) => sources.some((source) => line.startsWith(`${source}:`)))
|
|
203
|
-
const broken = hosted.filter(
|
|
212
|
+
const broken = hosted.filter(
|
|
213
|
+
(entry) => linesFor([...entry.sources, ...(entry.javaSpecs ?? [])]).length > 0,
|
|
214
|
+
)
|
|
204
215
|
const brokenProjects = projects.filter(
|
|
205
216
|
(project) => project.installed && linesFor(project.sources).length > 0,
|
|
206
217
|
)
|
|
207
218
|
if (broken.length > 0 || brokenProjects.length > 0) {
|
|
208
|
-
drop(broken, (entry) =>
|
|
219
|
+
drop(broken, (entry) =>
|
|
220
|
+
linesFor([...entry.sources, ...(entry.javaSpecs ?? [])]).join('\n'),
|
|
221
|
+
)
|
|
209
222
|
dropProjects(brokenProjects, (project) => linesFor(project.sources).join('\n'))
|
|
210
223
|
continue
|
|
211
224
|
}
|
|
@@ -12,7 +12,7 @@ export interface ExpoKotlinCompilationResult {
|
|
|
12
12
|
namespaces: string[]
|
|
13
13
|
module: { url: string; hash: string; compose: boolean } | null
|
|
14
14
|
failures: { namespace: string; diagnostic: string }[]
|
|
15
|
-
// the namespaces the app's
|
|
15
|
+
// the namespaces the app's React Native package modules answer for; the
|
|
16
16
|
// engine installs them as bridge modules, not as Expo modules
|
|
17
17
|
bridgeModules: string[]
|
|
18
18
|
}
|
package/src/java-module-abi.ts
CHANGED
|
@@ -44,7 +44,13 @@ export async function readJavaModuleSpecs(
|
|
|
44
44
|
...origins.keys(),
|
|
45
45
|
],
|
|
46
46
|
{ maxBuffer: 16 * 1024 * 1024 },
|
|
47
|
-
)
|
|
47
|
+
).catch((cause: unknown) => {
|
|
48
|
+
if (!isRecord(cause) || typeof cause.stderr !== 'string') throw cause
|
|
49
|
+
let diagnostic = cause.stderr
|
|
50
|
+
for (const [temporary, original] of origins)
|
|
51
|
+
diagnostic = diagnostic.replaceAll(temporary, original)
|
|
52
|
+
throw new Error(`Java module read failed:\n${diagnostic.trim()}`, { cause })
|
|
53
|
+
})
|
|
48
54
|
const specs = stdout
|
|
49
55
|
.split('\n')
|
|
50
56
|
.filter(Boolean)
|