peachsim 0.1.1481 → 0.1.1619
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 +56 -13
- package/cli/app-catalog.ts +7 -5
- package/cli/app-config.ts +47 -8
- package/cli/app-fonts.ts +84 -49
- package/cli/app-stubs.ts +433 -0
- package/cli/bin.ts +15 -2
- package/cli/bridge-flow-runner.ts +383 -123
- package/cli/cloud-client.ts +26 -25
- package/cli/cloud-test-tunnel.ts +2 -0
- package/cli/command-registry.ts +2 -1
- package/cli/commands/agent-indicator-mode.ts +39 -0
- package/cli/commands/box/bundle-plane.ts +4 -0
- package/cli/commands/box.ts +16 -23
- package/cli/commands/control.ts +221 -126
- package/cli/commands/daemon.ts +99 -24
- package/cli/commands/debug.ts +31 -3
- package/cli/commands/detect.ts +1 -1
- package/cli/commands/device.ts +6 -8
- package/cli/commands/diagnose.ts +2 -0
- package/cli/commands/do-chain.ts +2 -2
- package/cli/commands/doctor.ts +1030 -0
- package/cli/commands/flow.ts +447 -406
- package/cli/commands/inspect/actions.ts +2 -0
- package/cli/commands/inspect/core.ts +138 -46
- package/cli/commands/inspect/env.ts +10 -0
- package/cli/commands/inspect/list.ts +25 -8
- package/cli/commands/inspect/memory.ts +9 -0
- package/cli/commands/inspect/settling.ts +219 -66
- package/cli/commands/inspect/shared.ts +53 -12
- package/cli/commands/inspect/wait-event.ts +0 -1
- package/cli/commands/inspect/wait.ts +2 -2
- package/cli/commands/inspect.ts +51 -16
- package/cli/commands/install-desktop.ts +3 -2
- package/cli/commands/kotlin.ts +81 -22
- package/cli/commands/login.ts +1 -1
- package/cli/commands/maestro-compare.ts +41 -5
- package/cli/commands/maestro-generate.ts +11 -7
- package/cli/commands/maestro.ts +43 -15
- package/cli/commands/mode.ts +13 -1
- package/cli/commands/no-bridge-hint.ts +26 -3
- package/cli/commands/perf-record.ts +296 -0
- package/cli/commands/perf.ts +6 -1
- package/cli/commands/platform.ts +15 -4
- package/cli/commands/preview.ts +1 -1
- package/cli/commands/record.ts +37 -6
- package/cli/commands/report-issue.ts +2 -1
- package/cli/commands/runtime.ts +9 -11
- package/cli/commands/screenshots.ts +4 -3
- package/cli/commands/serve.ts +30 -2
- package/cli/commands/setup.ts +32 -7
- package/cli/commands/skills.ts +16 -43
- package/cli/commands/swift.ts +22 -3
- package/cli/commands/upgrade.ts +7 -6
- package/cli/commands/upload.ts +118 -69
- package/cli/commands/window.ts +449 -0
- package/cli/current-sim.ts +1 -2
- package/cli/desktop-companion.ts +84 -10
- package/cli/device-option.ts +8 -0
- package/cli/drivers/desktop.ts +3 -1
- package/cli/drivers/playwright-sim-host.ts +30 -11
- package/cli/drivers/playwright.ts +1 -4
- package/cli/flow-export.ts +2 -2
- package/cli/flow-file.ts +19 -18
- package/cli/internal-child.ts +7 -6
- package/cli/maestro-compare.ts +28 -6
- package/cli/maestro-js.ts +2 -1
- package/cli/main.ts +25 -4
- package/cli/material-symbol-fonts.ts +171 -0
- package/cli/outbound-endpoints.ts +132 -54
- package/cli/parse-args.ts +7 -0
- package/cli/preview-capture.ts +12 -0
- package/cli/privacy.ts +1 -1
- package/cli/run-registry.ts +5 -2
- package/cli/runtime-compat.ts +16 -0
- package/cli/telemetry.ts +6 -3
- package/cli/ui.ts +5 -0
- package/cli/ws-bridge.ts +121 -62
- package/detox/attempt-events.cjs +762 -0
- package/detox/attempt-events.d.cts +106 -0
- package/detox/gestures.ts +115 -2
- package/detox/index.ts +762 -426
- package/detox/jest-environment.cjs +86 -0
- package/detox/jest-preset.cjs +3 -1
- package/detox/jest-setup-after-env.cjs +1 -0
- package/detox/matchers.ts +3 -6
- package/detox/motion-change.cjs +259 -0
- package/detox/motion-change.d.cts +73 -0
- package/detox/proof-frame.cjs +83 -9
- 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 +15 -5
- 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 +3 -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 +5950 -1775
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cloud-contract.cjs +6 -1
- package/dist-lib/cloud-contract.mjs +5 -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 +34 -3
- package/dist-lib/config.mjs +33 -3
- package/dist-lib/detox/index.cjs +3443 -564
- package/dist-lib/detox/jest-environment.cjs +86 -0
- package/dist-lib/detox/jest-preset.cjs +3 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +5518 -1446
- package/dist-lib/expo-swift-metadata.cjs +21 -13
- package/dist-lib/expo-swift-metadata.mjs +21 -13
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +21728 -16808
- package/dist-lib/host/fetch-proxy-handler.cjs +177 -102
- package/dist-lib/host/fetch-proxy-overrides.cjs +84 -4
- package/dist-lib/host/fetch-proxy-overrides.mjs +74 -3
- package/dist-lib/host/replacement-module-handler.cjs +16 -15
- package/dist-lib/host/websocket-proxy.cjs +243 -6
- package/dist-lib/index.cjs +6063 -4113
- package/dist-lib/jump-to-source-babel.cjs +73 -35
- package/dist-lib/jump-to-source-native.cjs +118 -10
- package/dist-lib/kotlin-host.cjs +264 -121
- 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 +147 -99
- package/dist-lib/metro-production-bundle.mjs +142 -99
- package/dist-lib/metro.cjs +4249 -360
- package/dist-lib/native-app-identity-project.cjs +318 -131
- package/dist-lib/native-app-identity-project.mjs +317 -131
- package/dist-lib/native-app-identity.cjs +322 -33
- package/dist-lib/native-app-identity.mjs +319 -32
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.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/react-native-host-modules.cjs +11 -1
- package/dist-lib/react-native-host-modules.mjs +11 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +127 -42
- package/dist-lib/sdk.cjs +311 -103
- package/dist-lib/sdk.mjs +311 -103
- package/dist-lib/skills.cjs +18344 -11121
- package/dist-lib/swift-compile.cjs +3291 -544
- package/dist-lib/swift-compile.mjs +3227 -478
- package/dist-lib/swift-package.cjs +25 -3
- package/dist-lib/swift-package.mjs +22 -2
- package/dist-lib/swift-submit.cjs +2 -2
- package/dist-lib/swift-submit.mjs +2 -2
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +5523 -1428
- package/dist-lib/vite.cjs +251 -60
- package/dist-lib/worklet-executable.cjs +18 -4
- package/dist-lib/worklet-executable.mjs +18 -4
- package/install.sh +8 -3
- package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +2 -0
- package/kotlin/AndroidViewSources/android/graphics/Paint.kt +18 -0
- package/kotlin/AndroidViewSources/dev/peach/app/JavaFormat.kt +16 -8
- package/kotlin/AppSources/android/view/Window.kt +4 -1
- package/kotlin/AppSources/android/window/BackEvent.kt +24 -0
- package/kotlin/AppSources/android/window/OnBackAnimationCallback.kt +7 -0
- package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +37 -1
- package/kotlin/AppSources/androidx/activity/BackEventCompat.kt +5 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +8 -1
- package/kotlin/AppSources/dev/peach/app/PeachApp.kt +14 -0
- package/kotlin/CompilerSources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar +1 -0
- package/kotlin/CompilerSources/PeachJniIncoming.kt +243 -0
- package/kotlin/CompilerSources/PeachJniPlugin.kt +116 -0
- package/kotlin/ComposeSources/PeachComposeHost.kt +58 -32
- package/kotlin/ComposeSources/PeachMagnifier.kt +185 -0
- package/kotlin/ExpoComposeSources/PeachAndroidView.kt +16 -0
- package/kotlin/JniPlatformSources/androidx/annotation/CallSuper.kt +5 -0
- package/kotlin/JniPlatformSources/com/facebook/proguard/annotations/DoNotStrip.kt +5 -0
- package/kotlin/JniPlatformSources/dalvik/annotation/optimization/FastNative.kt +5 -0
- package/kotlin/JniPlatformSources/kotlin/Synchronized.kt +6 -0
- package/kotlin/JniPlatformSources/kotlin/jvm/JvmField.kt +5 -0
- package/kotlin/JniPlatformSources/kotlin/jvm/JvmStatic.kt +5 -0
- package/kotlin/JniSources/com/facebook/jni/HybridData.kt +68 -0
- package/kotlin/JniSources/dev/peach/jni/IncomingBindings.kt +157 -0
- package/kotlin/JniSources/dev/peach/jni/NativeBindings.kt +79 -0
- package/kotlin/JniTransportSources/dev/peach/jni/integration/JniTransport.kt +91 -0
- package/kotlin/README.md +18 -0
- package/kotlin/Sources/java/util/IllegalFormatCodePointException.kt +10 -0
- package/kotlin/Sources/java/util/IllegalFormatException.kt +5 -0
- package/kotlin/fixtures/counter/CounterApp.native.tsx +30 -3
- package/kotlin/fixtures/counter/CounterScreen.d.kt.ts +1 -0
- package/kotlin/fixtures/counter/CounterScreen.kt +2 -1
- package/kotlin/fixtures/counter/package.json +15 -2
- package/kotlin/fixtures/counter/vite.config.ts +11 -1
- package/kotlin/fork/NOTICE +1 -0
- package/kotlin/fork/README.md +5 -4
- package/kotlin/fork/compose-worker-globals.patch +629 -0
- package/kotlin/fork/fork.json +1 -1
- package/kotlin/toolchain.json +3 -3
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +166 -81
- package/skills/contrast/SKILL.md +4 -4
- package/skills/peach-debug/SKILL.md +1 -1
- package/skills/peach-perf/SKILL.md +25 -0
- package/skills/peach-setup/SKILL.md +47 -13
- package/skills/peach-test/SKILL.md +2 -3
- package/src/agent-identity.ts +18 -0
- package/src/assetCatalogContract.ts +31 -3
- package/src/auth/shared-session.ts +3 -2
- package/src/bridge-constants.ts +1 -1
- package/src/bridge-contract.ts +5 -0
- package/src/bundle-channel.mjs +38 -7
- package/src/bundleGlobalFooter.ts +70 -20
- package/src/cloud-contract.ts +11 -0
- package/src/config.ts +47 -1
- package/src/configured-bundle-producer.ts +4 -1
- package/src/desktop-host-delivery.ts +4 -3
- package/src/expo-kotlin-host.ts +7 -2
- package/src/guest-bundle.ts +15 -8
- package/src/host/agent-host.ts +2 -4
- package/src/host/bridge-host.ts +260 -119
- package/src/host/fetch-proxy-handler.ts +237 -146
- package/src/host/fetch-proxy-overrides.ts +118 -0
- package/src/host/fetch-proxy-transport.ts +77 -63
- package/src/host/lease-owner.test.ts +18 -1
- package/src/host/lease-owner.ts +4 -5
- package/src/host/loopback-ports.ts +34 -0
- package/src/host/replacement-module-handler.ts +24 -15
- package/src/host/server-scan-handler.ts +87 -0
- package/src/host/staged-host-files.ts +92 -0
- package/src/host/websocket-proxy.ts +271 -5
- package/src/installed-package-versions.ts +66 -0
- package/src/jump-to-source-babel.ts +97 -89
- package/src/jump-to-source-native.ts +109 -11
- package/src/kotlin-host.ts +144 -27
- package/src/kotlin-module.ts +52 -0
- package/src/kotlinDiscoveryContract.ts +27 -0
- package/src/metro-layout-parser.ts +78 -0
- package/src/metro-plugin.ts +129 -39
- package/src/metro-production-bundle.ts +140 -139
- package/src/native-app-identity-project.ts +103 -5
- package/src/native-app-identity.ts +173 -11
- package/src/native-firebase-config.ts +83 -80
- package/src/native-seam-manifest.ts +0 -44
- package/src/nativeAppIconContract.ts +137 -0
- package/src/nativeViewSourceContract.ts +49 -0
- package/src/nativeViewWebContract.ts +41 -0
- package/src/nitro-bundle.ts +43 -0
- package/src/nitro-compile.ts +107 -0
- package/src/nitro-source.ts +310 -0
- package/src/nitroContract.ts +51 -0
- package/src/one-widget-metadata.ts +23 -3
- package/src/oneWidgetContract.ts +36 -3
- package/src/packageVersionsContract.ts +52 -0
- package/src/process-group.ts +306 -0
- package/src/process-liveness.ts +24 -0
- package/src/process-output.ts +21 -2
- package/src/react-devtools-frontend-react.ts +45 -0
- package/src/react-native-host-modules.ts +10 -0
- package/src/serverDiscoveryContract.ts +41 -0
- package/src/skills/builtin/maestro-test.ts +2 -4
- package/src/swift-compile.ts +3195 -650
- package/src/swift-design-time.ts +552 -0
- package/src/swift-distribution-contract.ts +11 -0
- package/src/swift-distribution.lock.json +46 -11
- package/src/swift-host.ts +144 -30
- package/src/swift-icu.ts +10 -2
- package/src/swift-objc-sdk.ts +726 -0
- package/src/swift-objc-standin.ts +441 -0
- package/src/swift-package.ts +25 -0
- package/src/swift-packages.ts +25 -10
- package/src/swift-standin-config.ts +94 -0
- package/src/swift-standin-emit.ts +5 -3
- package/src/swift-standins.ts +225 -81
- package/src/swift-submit.ts +2 -1
- package/src/swiftContract.ts +4 -0
- package/src/target-matcher.ts +67 -0
- package/src/visit-parsed-program.ts +21 -0
- package/src/vite-plugin-one.ts +65 -17
- package/src/vite-plugin-swift.ts +1 -0
- package/src/vite-plugin.ts +168 -70
- package/src/worker-system-chunks.ts +89 -10
- package/src/worklet-executable.ts +21 -3
- package/src/worklets-babel.ts +85 -13
- package/src/xcode-project.ts +81 -134
- package/src/xcode-target-members.ts +107 -0
- package/cli/commands/compat.ts +0 -395
|
@@ -1,9 +1,85 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1619 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/native-app-identity-project.ts
|
|
4
4
|
import fs2 from "node:fs";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
5
6
|
import path3 from "node:path";
|
|
6
7
|
|
|
8
|
+
// src/nativeAppIconContract.ts
|
|
9
|
+
function isRecord(value) {
|
|
10
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
function resolveNativeAppIconArtwork(resources, readText, resourceUri, icons, primaryName, alternateNames, resolveReference) {
|
|
13
|
+
const members = new Set(resources);
|
|
14
|
+
const dictionary = isRecord(icons) ? icons : {};
|
|
15
|
+
const alternates = Object.fromEntries(
|
|
16
|
+
Object.entries(
|
|
17
|
+
isRecord(dictionary.CFBundleAlternateIcons) ? dictionary.CFBundleAlternateIcons : {}
|
|
18
|
+
).map(([name, declaration]) => [resolveReference(name), declaration])
|
|
19
|
+
);
|
|
20
|
+
const resolve = (declaration, defaultName) => {
|
|
21
|
+
const entry = isRecord(declaration) ? declaration : {};
|
|
22
|
+
const name = typeof entry.CFBundleIconName === "string" ? resolveReference(entry.CFBundleIconName) : resolveReference(defaultName);
|
|
23
|
+
const catalogs = resources.filter(
|
|
24
|
+
(file) => file.endsWith(`/${name}.appiconset/Contents.json`)
|
|
25
|
+
);
|
|
26
|
+
const populatedCatalogs = [];
|
|
27
|
+
for (const catalog of catalogs) {
|
|
28
|
+
const catalogCandidates = [];
|
|
29
|
+
const text2 = readText(catalog);
|
|
30
|
+
const contents = text2 === null ? null : JSON.parse(text2);
|
|
31
|
+
if (isRecord(contents) && Array.isArray(contents.images)) {
|
|
32
|
+
for (const image of contents.images) {
|
|
33
|
+
if (!isRecord(image) || typeof image.filename !== "string" || /[/\\]/.test(image.filename) || !/\.(png|jpe?g|webp)$/i.test(image.filename) || image.appearances !== void 0 || !["iphone", "universal", "ios-marketing"].includes(String(image.idiom)))
|
|
34
|
+
continue;
|
|
35
|
+
const file = catalog.slice(0, -"Contents.json".length) + image.filename;
|
|
36
|
+
const scale = image.scale === "2x" ? 2 : image.scale === "3x" ? 3 : 1;
|
|
37
|
+
const size = typeof image.size === "string" ? parseFloat(image.size) : 1024;
|
|
38
|
+
if (members.has(file) && Number.isFinite(size) && size > 0)
|
|
39
|
+
catalogCandidates.push({ file, scale, size });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (catalogCandidates.length > 0) populatedCatalogs.push(catalogCandidates);
|
|
43
|
+
}
|
|
44
|
+
if (populatedCatalogs.length > 1)
|
|
45
|
+
throw new Error(`native app icon catalog ${name} is ambiguous`);
|
|
46
|
+
const candidates = [];
|
|
47
|
+
if (populatedCatalogs.length === 1) {
|
|
48
|
+
candidates.push(...populatedCatalogs[0]);
|
|
49
|
+
const home = candidates.filter((image) => image.size === 60);
|
|
50
|
+
const chosen = home.length ? home : candidates.sort((a, b) => b.size * b.scale - a.size * a.scale).slice(0, 1);
|
|
51
|
+
return chosen.flatMap(({ file, scale }) => {
|
|
52
|
+
const uri = resourceUri(file);
|
|
53
|
+
return uri ? [{ uri, scale }] : [];
|
|
54
|
+
}).sort((a, b) => a.scale - b.scale);
|
|
55
|
+
}
|
|
56
|
+
const files = Array.isArray(entry.CFBundleIconFiles) ? entry.CFBundleIconFiles : [];
|
|
57
|
+
for (const iconFile of files) {
|
|
58
|
+
if (typeof iconFile !== "string" || /[/\\]/.test(iconFile)) continue;
|
|
59
|
+
const base = resolveReference(iconFile).replace(/\.(png|jpe?g|webp)$/i, "");
|
|
60
|
+
for (const file of resources) {
|
|
61
|
+
const match = /(?:^|\/)([^/]+?)(?:@([23])x)?\.(png|jpe?g|webp)$/i.exec(file);
|
|
62
|
+
if (!match || match[1] !== base) continue;
|
|
63
|
+
candidates.push({ file, scale: Number(match[2] ?? 1), size: 60 });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return candidates.flatMap(({ file, scale }) => {
|
|
67
|
+
const uri = resourceUri(file);
|
|
68
|
+
return uri ? [{ uri, scale }] : [];
|
|
69
|
+
}).sort((a, b) => a.scale - b.scale);
|
|
70
|
+
};
|
|
71
|
+
const primary = resolve(dictionary.CFBundlePrimaryIcon, primaryName);
|
|
72
|
+
return {
|
|
73
|
+
...primary.length ? { primary } : {},
|
|
74
|
+
alternates: Object.fromEntries(
|
|
75
|
+
alternateNames.flatMap((name) => {
|
|
76
|
+
const images = resolve(alternates[name], name);
|
|
77
|
+
return images.length ? [[name, images]] : [];
|
|
78
|
+
})
|
|
79
|
+
)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
7
83
|
// src/openstep-plist.ts
|
|
8
84
|
var isDict = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
85
|
var str = (value) => typeof value === "string" ? value : void 0;
|
|
@@ -99,7 +175,101 @@ function parseOpenStepPlist(text2) {
|
|
|
99
175
|
return root;
|
|
100
176
|
}
|
|
101
177
|
|
|
178
|
+
// src/xcode-target-members.ts
|
|
179
|
+
var NEVER_MEMBER = /(?:^|\/)(?:Info\.plist|[^/]+\.entitlements|[^/]+\.xcconfig|\.DS_Store)$/;
|
|
180
|
+
var BUNDLE_DIR = /\.(xcassets|bundle|lproj|xcdatamodeld|scnassets|spriteatlas|rcproject|storyboardc|icon)$/;
|
|
181
|
+
function xcodePathResolver(objects, projectDir, join) {
|
|
182
|
+
const parents = /* @__PURE__ */ new Map();
|
|
183
|
+
for (const [id, entry] of Object.entries(objects)) {
|
|
184
|
+
if (!isDict(entry)) continue;
|
|
185
|
+
if (entry.isa === "PBXGroup" || entry.isa === "PBXVariantGroup") {
|
|
186
|
+
for (const child of list(entry.children)) parents.set(child, id);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const paths = /* @__PURE__ */ new Map();
|
|
190
|
+
const resolve = (id) => {
|
|
191
|
+
if (paths.has(id)) return paths.get(id);
|
|
192
|
+
paths.set(id, null);
|
|
193
|
+
const entry = objects[id];
|
|
194
|
+
let result = null;
|
|
195
|
+
if (isDict(entry)) {
|
|
196
|
+
const own = str(entry.path) ?? "";
|
|
197
|
+
const tree = str(entry.sourceTree) ?? "<group>";
|
|
198
|
+
if (tree === "<absolute>") result = own;
|
|
199
|
+
else if (tree === "SOURCE_ROOT") result = join(projectDir, own);
|
|
200
|
+
else if (tree === "<group>") {
|
|
201
|
+
const parent = parents.get(id);
|
|
202
|
+
const base = parent ? resolve(parent) : projectDir;
|
|
203
|
+
if (base !== null) result = join(base, own);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
paths.set(id, result);
|
|
207
|
+
return result;
|
|
208
|
+
};
|
|
209
|
+
return resolve;
|
|
210
|
+
}
|
|
211
|
+
function visitXcodeTargetMembers(objects, targetId, resolvePath, filesUnder, join, visit) {
|
|
212
|
+
const target = objects[targetId];
|
|
213
|
+
if (!isDict(target)) return;
|
|
214
|
+
for (const phaseId of list(target.buildPhases)) {
|
|
215
|
+
const phase = objects[phaseId];
|
|
216
|
+
if (!isDict(phase)) continue;
|
|
217
|
+
if (phase.isa !== "PBXSourcesBuildPhase" && phase.isa !== "PBXResourcesBuildPhase")
|
|
218
|
+
continue;
|
|
219
|
+
for (const buildFileId of list(phase.files)) {
|
|
220
|
+
const buildFile = objects[buildFileId];
|
|
221
|
+
if (!isDict(buildFile)) continue;
|
|
222
|
+
const refId = str(buildFile.fileRef);
|
|
223
|
+
if (!refId) continue;
|
|
224
|
+
const entry = objects[refId];
|
|
225
|
+
const refs = isDict(entry) && entry.isa === "PBXVariantGroup" ? list(entry.children) : [refId];
|
|
226
|
+
for (const id of refs) {
|
|
227
|
+
const file = resolvePath(id);
|
|
228
|
+
if (file === null) continue;
|
|
229
|
+
if (phase.isa === "PBXSourcesBuildPhase") visit(file, "source");
|
|
230
|
+
else for (const inner of filesUnder(file)) visit(inner, "resource");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const owned = new Set(list(target.fileSystemSynchronizedGroups));
|
|
235
|
+
for (const [groupId, group] of Object.entries(objects)) {
|
|
236
|
+
if (!isDict(group) || group.isa !== "PBXFileSystemSynchronizedRootGroup") continue;
|
|
237
|
+
const folder = resolvePath(groupId);
|
|
238
|
+
if (folder === null) continue;
|
|
239
|
+
const prefix = folder === "" ? "" : `${folder.replace(/\/$/, "")}/`;
|
|
240
|
+
const exceptions = /* @__PURE__ */ new Set();
|
|
241
|
+
for (const exceptionId of list(group.exceptions)) {
|
|
242
|
+
const exception = objects[exceptionId];
|
|
243
|
+
if (!isDict(exception) || exception.target !== targetId) continue;
|
|
244
|
+
for (const relative of list(exception.membershipExceptions))
|
|
245
|
+
exceptions.add(relative);
|
|
246
|
+
}
|
|
247
|
+
const members = owned.has(groupId) ? filesUnder(folder) : [...exceptions].flatMap((relative) => filesUnder(join(folder, relative)));
|
|
248
|
+
for (const file of members) {
|
|
249
|
+
const relative = file.slice(prefix.length);
|
|
250
|
+
const excepted = [...exceptions].some(
|
|
251
|
+
(exception) => relative === exception || relative.startsWith(`${exception}/`)
|
|
252
|
+
);
|
|
253
|
+
if (owned.has(groupId) === excepted || NEVER_MEMBER.test(relative)) continue;
|
|
254
|
+
if (file.endsWith(".swift")) {
|
|
255
|
+
if (!relative.split("/").some((segment) => BUNDLE_DIR.test(segment)))
|
|
256
|
+
visit(file, "source");
|
|
257
|
+
} else if (/\.(h|m|mm|c|cpp|metal)$/.test(file)) {
|
|
258
|
+
if (!file.endsWith(".h")) visit(file, "source");
|
|
259
|
+
} else visit(file, "resource");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
102
264
|
// src/native-app-identity.ts
|
|
265
|
+
var ROOT_MODULE_NAME_RE = /(?:\bm|M)oduleName\s*[:=]\s*@?"([^"\\]+)"/g;
|
|
266
|
+
function readRootModuleName(sources) {
|
|
267
|
+
const names = /* @__PURE__ */ new Set();
|
|
268
|
+
for (const source of sources) {
|
|
269
|
+
for (const match of source.matchAll(ROOT_MODULE_NAME_RE)) names.add(match[1]);
|
|
270
|
+
}
|
|
271
|
+
return names.size === 1 ? [...names][0] : void 0;
|
|
272
|
+
}
|
|
103
273
|
function canExtractNativeAppIdentity(platform) {
|
|
104
274
|
return platform === "ios";
|
|
105
275
|
}
|
|
@@ -456,8 +626,6 @@ var MODULE_PRODUCTS = /* @__PURE__ */ new Set([
|
|
|
456
626
|
"com.apple.product-type.library.static",
|
|
457
627
|
"com.apple.product-type.library.dynamic"
|
|
458
628
|
]);
|
|
459
|
-
var NEVER_MEMBER = /(?:^|\/)(?:Info\.plist|[^/]+\.entitlements|[^/]+\.xcconfig|\.DS_Store)$/;
|
|
460
|
-
var BUNDLE_DIR = /\.(xcassets|bundle|lproj|xcdatamodeld|scnassets|spriteatlas|rcproject|storyboardc|icon)$/;
|
|
461
629
|
var CONDITIONS = {
|
|
462
630
|
sdk: "iphonesimulator",
|
|
463
631
|
arch: "arm64",
|
|
@@ -595,32 +763,7 @@ function loadProject(xcodeproj) {
|
|
|
595
763
|
const projectDir = fs.realpathSync(
|
|
596
764
|
path2.resolve(path2.dirname(xcodeproj), str(project.projectDirPath) ?? "")
|
|
597
765
|
);
|
|
598
|
-
const
|
|
599
|
-
for (const [id, entry] of Object.entries(objects)) {
|
|
600
|
-
if (!isDict(entry)) continue;
|
|
601
|
-
if (entry.isa === "PBXGroup" || entry.isa === "PBXVariantGroup") {
|
|
602
|
-
for (const child of list(entry.children)) parent.set(child, id);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
const resolvedPaths = /* @__PURE__ */ new Map();
|
|
606
|
-
const resolvePath = (id) => {
|
|
607
|
-
if (resolvedPaths.has(id)) return resolvedPaths.get(id);
|
|
608
|
-
const entry = object(id);
|
|
609
|
-
let result2 = null;
|
|
610
|
-
if (entry) {
|
|
611
|
-
const own = str(entry.path) ?? "";
|
|
612
|
-
const tree = str(entry.sourceTree) ?? "<group>";
|
|
613
|
-
if (tree === "<absolute>") result2 = own;
|
|
614
|
-
else if (tree === "SOURCE_ROOT") result2 = path2.join(projectDir, own);
|
|
615
|
-
else if (tree === "<group>") {
|
|
616
|
-
const up = parent.get(id);
|
|
617
|
-
const base = up ? resolvePath(up) : projectDir;
|
|
618
|
-
result2 = base === null ? null : path2.join(base, own);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
resolvedPaths.set(id, result2);
|
|
622
|
-
return result2;
|
|
623
|
-
};
|
|
766
|
+
const resolvePath = xcodePathResolver(objects, projectDir, path2.join);
|
|
624
767
|
const result = {
|
|
625
768
|
xcodeproj,
|
|
626
769
|
projectFile,
|
|
@@ -640,7 +783,7 @@ function defaultConfiguration(project) {
|
|
|
640
783
|
);
|
|
641
784
|
return names.includes("Debug") ? "Debug" : str(configList?.defaultConfigurationName) ?? names[0] ?? "Debug";
|
|
642
785
|
}
|
|
643
|
-
function targetSettings(ref, configuration, builtins) {
|
|
786
|
+
function targetSettings(ref, configuration, builtins, options = {}) {
|
|
644
787
|
const { project, target } = ref;
|
|
645
788
|
const xcconfigs = [];
|
|
646
789
|
const level = (listId) => {
|
|
@@ -652,6 +795,10 @@ function targetSettings(ref, configuration, builtins) {
|
|
|
652
795
|
const base = str(config.baseConfigurationReference);
|
|
653
796
|
const own = isDict(config.buildSettings) ? config.buildSettings : {};
|
|
654
797
|
const baseFile = base ? project.resolvePath(base) : null;
|
|
798
|
+
if (options.requireSources !== false && base && (!baseFile || !fs.existsSync(baseFile)))
|
|
799
|
+
throw new Error(
|
|
800
|
+
`Unable to open base configuration reference file '${baseFile ?? base}'`
|
|
801
|
+
);
|
|
655
802
|
const read = [];
|
|
656
803
|
const fromFile = baseFile ? readXcconfig(baseFile, read) : {};
|
|
657
804
|
xcconfigs.push(...read);
|
|
@@ -747,23 +894,6 @@ function targetMembers(ref, settings, options = {}) {
|
|
|
747
894
|
const sources = /* @__PURE__ */ new Set();
|
|
748
895
|
const allSources = /* @__PURE__ */ new Set();
|
|
749
896
|
const resources = /* @__PURE__ */ new Set();
|
|
750
|
-
const addResource = (file) => {
|
|
751
|
-
if (isDirectory(file)) {
|
|
752
|
-
for (const inner of walkFiles(file)) resources.add(inner);
|
|
753
|
-
} else if (fs.existsSync(file)) resources.add(file);
|
|
754
|
-
};
|
|
755
|
-
const fileRefPaths = (refId) => {
|
|
756
|
-
const entry = project.object(refId);
|
|
757
|
-
if (!entry) return [];
|
|
758
|
-
if (entry.isa === "PBXVariantGroup") {
|
|
759
|
-
return list(entry.children).flatMap((child) => {
|
|
760
|
-
const resolved2 = project.resolvePath(child);
|
|
761
|
-
return resolved2 ? [resolved2] : [];
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
const resolved = project.resolvePath(refId);
|
|
765
|
-
return resolved ? [resolved] : [];
|
|
766
|
-
};
|
|
767
897
|
const scriptForOutput = /* @__PURE__ */ new Map();
|
|
768
898
|
const noteScriptOutput = (raw, script) => {
|
|
769
899
|
const expanded = expand(raw, settings);
|
|
@@ -787,26 +917,28 @@ function targetMembers(ref, settings, options = {}) {
|
|
|
787
917
|
}
|
|
788
918
|
}
|
|
789
919
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
throw new Error(
|
|
801
|
-
script ? `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)` : `${targetName}: missing source ${file}`
|
|
802
|
-
);
|
|
803
|
-
}
|
|
804
|
-
allSources.add(file);
|
|
805
|
-
if (file.endsWith(".swift")) sources.add(file);
|
|
806
|
-
} else if (phase.isa === "PBXResourcesBuildPhase") addResource(file);
|
|
920
|
+
visitXcodeTargetMembers(
|
|
921
|
+
project.objects,
|
|
922
|
+
targetId,
|
|
923
|
+
project.resolvePath,
|
|
924
|
+
(file) => isDirectory(file) ? walkFiles(file) : fs.existsSync(file) ? [file] : [],
|
|
925
|
+
path2.join,
|
|
926
|
+
(file, kind) => {
|
|
927
|
+
if (kind === "resource") {
|
|
928
|
+
resources.add(file);
|
|
929
|
+
return;
|
|
807
930
|
}
|
|
931
|
+
if (!fs.existsSync(file)) {
|
|
932
|
+
if (options.requireSources === false) return;
|
|
933
|
+
const script = scriptForOutput.get(path2.normalize(file));
|
|
934
|
+
throw new Error(
|
|
935
|
+
script ? `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)` : `${targetName}: missing source ${file}`
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
allSources.add(file);
|
|
939
|
+
if (file.endsWith(".swift")) sources.add(file);
|
|
808
940
|
}
|
|
809
|
-
|
|
941
|
+
);
|
|
810
942
|
for (const [file, script] of scriptForOutput) {
|
|
811
943
|
if (sources.has(file) || allSources.has(file)) continue;
|
|
812
944
|
if (!fs.existsSync(file)) {
|
|
@@ -818,52 +950,6 @@ function targetMembers(ref, settings, options = {}) {
|
|
|
818
950
|
allSources.add(file);
|
|
819
951
|
sources.add(file);
|
|
820
952
|
}
|
|
821
|
-
const addSynchronized = (folder, relative) => {
|
|
822
|
-
const file = path2.join(folder, relative);
|
|
823
|
-
if (NEVER_MEMBER.test(relative)) return;
|
|
824
|
-
if (file.endsWith(".swift")) {
|
|
825
|
-
if (!relative.split("/").some((segment) => BUNDLE_DIR.test(segment))) {
|
|
826
|
-
sources.add(file);
|
|
827
|
-
allSources.add(file);
|
|
828
|
-
}
|
|
829
|
-
} else if (/\.(h|m|mm|c|cpp|metal)$/.test(file)) {
|
|
830
|
-
if (!file.endsWith(".h")) allSources.add(file);
|
|
831
|
-
} else resources.add(file);
|
|
832
|
-
};
|
|
833
|
-
const owned = new Set(list(target.fileSystemSynchronizedGroups));
|
|
834
|
-
for (const [groupId, group] of Object.entries(project.objects)) {
|
|
835
|
-
if (!isDict(group) || group.isa !== "PBXFileSystemSynchronizedRootGroup") continue;
|
|
836
|
-
const folder = project.resolvePath(groupId);
|
|
837
|
-
if (!folder) continue;
|
|
838
|
-
const exceptions = /* @__PURE__ */ new Set();
|
|
839
|
-
for (const exceptionId of list(group.exceptions)) {
|
|
840
|
-
const exception = project.object(exceptionId);
|
|
841
|
-
if (exception?.target !== targetId) continue;
|
|
842
|
-
for (const relative of list(exception.membershipExceptions))
|
|
843
|
-
exceptions.add(relative);
|
|
844
|
-
}
|
|
845
|
-
if (owned.has(groupId)) {
|
|
846
|
-
for (const file of walkFiles(folder)) {
|
|
847
|
-
const relative = path2.relative(folder, file).split(path2.sep).join("/");
|
|
848
|
-
if ([...exceptions].some(
|
|
849
|
-
(exception) => relative === exception || relative.startsWith(`${exception}/`)
|
|
850
|
-
))
|
|
851
|
-
continue;
|
|
852
|
-
addSynchronized(folder, relative);
|
|
853
|
-
}
|
|
854
|
-
} else {
|
|
855
|
-
for (const relative of exceptions) {
|
|
856
|
-
const file = path2.join(folder, relative);
|
|
857
|
-
if (isDirectory(file)) {
|
|
858
|
-
for (const inner of walkFiles(file))
|
|
859
|
-
addSynchronized(
|
|
860
|
-
folder,
|
|
861
|
-
path2.relative(folder, inner).split(path2.sep).join("/")
|
|
862
|
-
);
|
|
863
|
-
} else if (fs.existsSync(file)) addSynchronized(folder, relative);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
953
|
return {
|
|
868
954
|
sources: [...sources].sort(),
|
|
869
955
|
resources: [...resources].sort(),
|
|
@@ -917,15 +1003,31 @@ function nativeTargets(project) {
|
|
|
917
1003
|
}
|
|
918
1004
|
return refs;
|
|
919
1005
|
}
|
|
920
|
-
function
|
|
921
|
-
|
|
1006
|
+
function isIosAppTarget(ref, options = {}) {
|
|
1007
|
+
if (ref.target.productType !== APPLICATION) return false;
|
|
1008
|
+
const { get } = targetSettings(
|
|
1009
|
+
ref,
|
|
1010
|
+
defaultConfiguration(ref.project),
|
|
1011
|
+
{
|
|
1012
|
+
TARGET_NAME: str(ref.target.name) ?? ref.id
|
|
1013
|
+
},
|
|
1014
|
+
options
|
|
1015
|
+
);
|
|
1016
|
+
const sdk = get("SDKROOT");
|
|
1017
|
+
return sdk === "auto" ? settingList(get("SUPPORTED_PLATFORMS")).some(isIosPlatform) : sdk === "" || isIosPlatform(sdk);
|
|
1018
|
+
}
|
|
1019
|
+
function isIosPlatform(name) {
|
|
1020
|
+
return name.startsWith("iphoneos") || name.startsWith("iphonesimulator");
|
|
1021
|
+
}
|
|
1022
|
+
function listXcodeAppTargets(xcodeprojOrWorkspace, options = {}) {
|
|
1023
|
+
return workspaceProjects(xcodeprojOrWorkspace).projects.flatMap(nativeTargets).filter((ref) => isIosAppTarget(ref, options)).map((ref) => str(ref.target.name) ?? ref.id);
|
|
922
1024
|
}
|
|
923
1025
|
function readXcodeAppTarget(input, targetName, configurationName, options = {}) {
|
|
924
1026
|
const xcodeprojOrWorkspace = fs.realpathSync(input);
|
|
925
1027
|
const workspace = xcodeprojOrWorkspace.endsWith(".xcworkspace") ? xcodeprojOrWorkspace : null;
|
|
926
1028
|
const { listed, projects, projectAt } = workspaceProjects(xcodeprojOrWorkspace);
|
|
927
1029
|
const allTargets = projects.flatMap(nativeTargets);
|
|
928
|
-
const appTargets = allTargets.filter((ref) => ref
|
|
1030
|
+
const appTargets = allTargets.filter((ref) => isIosAppTarget(ref, options));
|
|
929
1031
|
const appTargetNames = appTargets.map((ref) => str(ref.target.name) ?? ref.id);
|
|
930
1032
|
const container = path2.basename(xcodeprojOrWorkspace);
|
|
931
1033
|
const named = targetName ? appTargets.filter((ref) => ref.target.name === targetName) : appTargets;
|
|
@@ -993,14 +1095,19 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
993
1095
|
get: settings2,
|
|
994
1096
|
keys,
|
|
995
1097
|
xcconfigs: read
|
|
996
|
-
} = targetSettings(
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1098
|
+
} = targetSettings(
|
|
1099
|
+
ref,
|
|
1100
|
+
configuration,
|
|
1101
|
+
{
|
|
1102
|
+
TARGET_NAME: name,
|
|
1103
|
+
PROJECT_NAME: path2.basename(ref.project.xcodeproj, ".xcodeproj"),
|
|
1104
|
+
SRCROOT: ref.project.projectDir,
|
|
1105
|
+
SOURCE_ROOT: ref.project.projectDir,
|
|
1106
|
+
PROJECT_DIR: ref.project.projectDir,
|
|
1107
|
+
DEVELOPMENT_LANGUAGE: str(ref.project.project.developmentRegion) ?? "en"
|
|
1108
|
+
},
|
|
1109
|
+
options
|
|
1110
|
+
);
|
|
1004
1111
|
for (const file of read) xcconfigs.add(file);
|
|
1005
1112
|
const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
|
|
1006
1113
|
return {
|
|
@@ -1138,7 +1245,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
1138
1245
|
}
|
|
1139
1246
|
|
|
1140
1247
|
// src/native-app-identity-project.ts
|
|
1141
|
-
function
|
|
1248
|
+
function isRecord2(value) {
|
|
1142
1249
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1143
1250
|
}
|
|
1144
1251
|
function nonEmptyString(value) {
|
|
@@ -1146,7 +1253,7 @@ function nonEmptyString(value) {
|
|
|
1146
1253
|
}
|
|
1147
1254
|
function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSource) {
|
|
1148
1255
|
const dictionary = parseInfoPlist(app.infoPlist);
|
|
1149
|
-
if (!
|
|
1256
|
+
if (!isRecord2(dictionary)) throw new Error("native app Info.plist is not a dictionary");
|
|
1150
1257
|
const settings = app.settings;
|
|
1151
1258
|
const bundleIdentifier = nonEmptyString(dictionary.CFBundleIdentifier) ?? nonEmptyString(settings?.("PRODUCT_BUNDLE_IDENTIFIER"));
|
|
1152
1259
|
if (!bundleIdentifier) throw new Error("native app has no bundle identifier");
|
|
@@ -1160,10 +1267,11 @@ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSo
|
|
|
1160
1267
|
const applicationName = applicationDisplayName ?? bundleName;
|
|
1161
1268
|
const declaredBackgroundColor = dictionary.RCTRootViewBackgroundColor;
|
|
1162
1269
|
const rootViewBackgroundColor = typeof declaredBackgroundColor === "number" && Number.isInteger(declaredBackgroundColor) ? declaredBackgroundColor : void 0;
|
|
1270
|
+
const designRequiresCompatibility = dictionary.UIDesignRequiresCompatibility === true;
|
|
1163
1271
|
const alternateIconNames = /* @__PURE__ */ new Set();
|
|
1164
1272
|
const icons = dictionary.CFBundleIcons;
|
|
1165
|
-
const alternates =
|
|
1166
|
-
if (
|
|
1273
|
+
const alternates = isRecord2(icons) ? icons.CFBundleAlternateIcons : void 0;
|
|
1274
|
+
if (isRecord2(alternates)) {
|
|
1167
1275
|
for (const name of Object.keys(alternates)) {
|
|
1168
1276
|
if (name) alternateIconNames.add(name);
|
|
1169
1277
|
}
|
|
@@ -1196,10 +1304,16 @@ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSo
|
|
|
1196
1304
|
dictionary.EXDefaultScreenOrientationMask
|
|
1197
1305
|
);
|
|
1198
1306
|
const shareIntoAppGroupId = nonEmptyString(dictionary.ExpoShareIntoAppGroupId);
|
|
1307
|
+
const rootModuleName = readRootModuleName(
|
|
1308
|
+
app.allSources.filter((file) => /\.(?:swift|mm|m)$/.test(file) && fs2.existsSync(file)).map((file) => fs2.readFileSync(file, "utf8"))
|
|
1309
|
+
);
|
|
1199
1310
|
return {
|
|
1200
1311
|
applicationName,
|
|
1201
1312
|
...applicationDisplayName ? { applicationDisplayName } : {},
|
|
1313
|
+
...rootModuleName ? { rootModuleName } : {},
|
|
1202
1314
|
...rootViewBackgroundColor !== void 0 ? { rootViewBackgroundColor } : {},
|
|
1315
|
+
...designRequiresCompatibility ? { designRequiresCompatibility } : {},
|
|
1316
|
+
...typeof dictionary.DTPlatformVersion === "string" ? { dtPlatformVersion: dictionary.DTPlatformVersion } : {},
|
|
1203
1317
|
bundleName,
|
|
1204
1318
|
appVersion,
|
|
1205
1319
|
buildVersion,
|
|
@@ -1209,6 +1323,19 @@ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSo
|
|
|
1209
1323
|
ipadSupportedInterfaceOrientations,
|
|
1210
1324
|
...defaultScreenOrientationMask ? { defaultScreenOrientationMask } : {},
|
|
1211
1325
|
alternateIconNames: [...alternateIconNames],
|
|
1326
|
+
appIconArtwork: resolveNativeAppIconArtwork(
|
|
1327
|
+
app.resources,
|
|
1328
|
+
(file) => fs2.readFileSync(file, "utf8"),
|
|
1329
|
+
(file) => {
|
|
1330
|
+
const extension = path3.extname(file).toLowerCase();
|
|
1331
|
+
const contentType = extension === ".jpg" || extension === ".jpeg" ? "image/jpeg" : extension === ".webp" ? "image/webp" : "image/png";
|
|
1332
|
+
return `data:${contentType};base64,${fs2.readFileSync(file).toString("base64")}`;
|
|
1333
|
+
},
|
|
1334
|
+
icons,
|
|
1335
|
+
app.appIconName,
|
|
1336
|
+
[...alternateIconNames],
|
|
1337
|
+
(value) => value
|
|
1338
|
+
),
|
|
1212
1339
|
permissionUsageDescriptions,
|
|
1213
1340
|
urlQuerySchemes,
|
|
1214
1341
|
...shareIntoAppGroupId ? { shareIntoAppGroupId } : {},
|
|
@@ -1217,6 +1344,8 @@ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSo
|
|
|
1217
1344
|
appIntentIdentifiers
|
|
1218
1345
|
};
|
|
1219
1346
|
}
|
|
1347
|
+
var NativeAppTargetSelectionError = class extends Error {
|
|
1348
|
+
};
|
|
1220
1349
|
function readNativeAppIdentityFromProject(projectRoot, platform, parseInfoPlist = parsePlistSource, iosTarget) {
|
|
1221
1350
|
if (!canExtractNativeAppIdentity(platform)) return null;
|
|
1222
1351
|
const iosRoot = path3.join(projectRoot, "ios");
|
|
@@ -1224,12 +1353,16 @@ function readNativeAppIdentityFromProject(projectRoot, platform, parseInfoPlist
|
|
|
1224
1353
|
const projects = fs2.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
|
|
1225
1354
|
if (projects.length === 0) return null;
|
|
1226
1355
|
if (projects.length > 1 && !iosTarget) {
|
|
1227
|
-
throw new
|
|
1356
|
+
throw new NativeAppTargetSelectionError(
|
|
1357
|
+
`native app identity requires a selected Xcode project; set withPeach's iosTarget to an app target in one of: ${projects.map((entry) => entry.name).join(", ")}`
|
|
1358
|
+
);
|
|
1228
1359
|
}
|
|
1229
1360
|
let project = projects[0];
|
|
1230
1361
|
if (iosTarget && projects.length > 1) {
|
|
1231
1362
|
const matches = projects.filter(
|
|
1232
|
-
(entry) => listXcodeAppTargets(path3.join(iosRoot, entry.name)
|
|
1363
|
+
(entry) => listXcodeAppTargets(path3.join(iosRoot, entry.name), {
|
|
1364
|
+
requireSources: false
|
|
1365
|
+
}).includes(iosTarget)
|
|
1233
1366
|
);
|
|
1234
1367
|
if (matches.length === 0) {
|
|
1235
1368
|
throw new Error(`native app identity has no application target ${iosTarget}`);
|
|
@@ -1242,16 +1375,69 @@ function readNativeAppIdentityFromProject(projectRoot, platform, parseInfoPlist
|
|
|
1242
1375
|
project = matches[0];
|
|
1243
1376
|
}
|
|
1244
1377
|
const xcodeproj = path3.join(iosRoot, project.name);
|
|
1245
|
-
const appTargets = listXcodeAppTargets(xcodeproj);
|
|
1378
|
+
const appTargets = listXcodeAppTargets(xcodeproj, { requireSources: false });
|
|
1246
1379
|
if (!iosTarget && appTargets.length > 1) {
|
|
1247
|
-
throw new
|
|
1380
|
+
throw new NativeAppTargetSelectionError(
|
|
1381
|
+
`native app identity requires a selected app target; set withPeach's iosTarget to one of: ${appTargets.join(", ")}`
|
|
1382
|
+
);
|
|
1248
1383
|
}
|
|
1249
1384
|
const app = readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
|
|
1250
1385
|
requireSources: false
|
|
1251
1386
|
});
|
|
1252
|
-
|
|
1387
|
+
const identity = readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist);
|
|
1388
|
+
const projectManifestPath = path3.join(projectRoot, "package.json");
|
|
1389
|
+
const projectRequire = createRequire(projectManifestPath);
|
|
1390
|
+
let reanimatedManifestPath;
|
|
1391
|
+
try {
|
|
1392
|
+
reanimatedManifestPath = projectRequire.resolve(
|
|
1393
|
+
"react-native-reanimated/package.json"
|
|
1394
|
+
);
|
|
1395
|
+
} catch (error) {
|
|
1396
|
+
if (error instanceof Error && "code" in error && error.code === "MODULE_NOT_FOUND") {
|
|
1397
|
+
return identity;
|
|
1398
|
+
}
|
|
1399
|
+
throw error;
|
|
1400
|
+
}
|
|
1401
|
+
const installedManifest = JSON.parse(
|
|
1402
|
+
fs2.readFileSync(reanimatedManifestPath, "utf8")
|
|
1403
|
+
);
|
|
1404
|
+
const installedVersion = isRecord2(installedManifest) ? nonEmptyString(installedManifest.version) : void 0;
|
|
1405
|
+
if (!installedVersion) throw new Error("Reanimated package version is malformed");
|
|
1406
|
+
if (installedVersion.startsWith("3.")) return identity;
|
|
1407
|
+
const defaults = JSON.parse(
|
|
1408
|
+
fs2.readFileSync(
|
|
1409
|
+
path3.join(
|
|
1410
|
+
path3.dirname(reanimatedManifestPath),
|
|
1411
|
+
"src/featureFlags/staticFlags.json"
|
|
1412
|
+
),
|
|
1413
|
+
"utf8"
|
|
1414
|
+
)
|
|
1415
|
+
);
|
|
1416
|
+
if (!isRecord2(defaults)) throw new Error("Reanimated static flags are malformed");
|
|
1417
|
+
const manifest = JSON.parse(fs2.readFileSync(projectManifestPath, "utf8"));
|
|
1418
|
+
const reanimated = isRecord2(manifest) ? manifest.reanimated : void 0;
|
|
1419
|
+
const overrides = isRecord2(reanimated) ? reanimated.staticFeatureFlags : void 0;
|
|
1420
|
+
if (overrides !== void 0 && !isRecord2(overrides)) {
|
|
1421
|
+
throw new Error("Reanimated static flag overrides are malformed");
|
|
1422
|
+
}
|
|
1423
|
+
const flags = {};
|
|
1424
|
+
for (const [name, value] of Object.entries({ ...defaults, ...overrides })) {
|
|
1425
|
+
flags[name] = String(value) === "true";
|
|
1426
|
+
}
|
|
1427
|
+
if (flags.USE_LEGACY_LAYOUT_ANIMATIONS_PROXY && flags.ENABLE_SHARED_ELEMENT_TRANSITIONS) {
|
|
1428
|
+
throw new Error(
|
|
1429
|
+
"Reanimated legacy layout animations cannot enable shared element transitions"
|
|
1430
|
+
);
|
|
1431
|
+
}
|
|
1432
|
+
if (flags.USE_ANIMATION_BACKEND && flags.FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS) {
|
|
1433
|
+
throw new Error(
|
|
1434
|
+
"Reanimated animation backend requires settled React renders to be disabled"
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
return { ...identity, reanimatedStaticFeatureFlags: flags };
|
|
1253
1438
|
}
|
|
1254
1439
|
export {
|
|
1440
|
+
NativeAppTargetSelectionError,
|
|
1255
1441
|
readNativeAppIdentityFromProject,
|
|
1256
1442
|
readNativeAppIdentityFromXcodeTarget
|
|
1257
1443
|
};
|