peachsim 0.1.1635 → 0.1.1640
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 +5 -1
- package/cli/app-config.ts +14 -5
- package/cli/app-stubs.ts +62 -13
- package/cli/bridge-flow-runner.ts +2 -2
- package/cli/cloud-client.ts +60 -40
- package/cli/commands/doctor.ts +13 -5
- package/cli/commands/flow.ts +1 -1
- package/cli/commands/inspect/shared.ts +9 -4
- package/cli/commands/inspect.ts +65 -47
- package/cli/commands/preview.ts +1 -1
- package/cli/commands/record.ts +97 -47
- package/cli/commands/swift.ts +9 -3
- package/cli/commands/upload.ts +48 -42
- package/cli/drivers/playwright-sim-host.ts +65 -42
- package/cli/main.ts +1 -1
- package/cli/outbound-endpoints.ts +7 -5
- package/cli/pause-aware-timeout.ts +4 -0
- package/cli/ws-bridge.ts +19 -10
- package/detox/attempt-events.cjs +62 -5
- package/detox/attempt-events.d.cts +7 -0
- package/detox/expectations.ts +7 -3
- package/detox/index.ts +121 -47
- package/detox/motion-change.cjs +170 -21
- package/detox/motion-change.d.cts +32 -0
- package/detox/navigation-lifecycle.ts +35 -3
- 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 +8 -7
- 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 +4038 -1983
- 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 +509 -86
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +3551 -1574
- package/dist-lib/expo-swift-metadata.cjs +9 -7
- package/dist-lib/expo-swift-metadata.mjs +9 -7
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +43633 -2635
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- 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 +2748 -128
- 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 +1 -1
- 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 +2547 -83
- package/dist-lib/native-app-identity-project.cjs +237 -50
- package/dist-lib/native-app-identity-project.mjs +237 -50
- package/dist-lib/native-app-identity.cjs +29 -30
- package/dist-lib/native-app-identity.mjs +29 -30
- 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 +2 -2
- package/dist-lib/react-native-host-modules.mjs +2 -2
- package/dist-lib/scripts/dev-server-scanner.cjs +8 -6
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +65403 -22739
- package/dist-lib/swift-compile.cjs +93 -32
- package/dist-lib/swift-compile.mjs +93 -32
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +7 -5
- package/dist-lib/swift-submit.mjs +7 -5
- package/dist-lib/swift-toolchain.cjs +316 -41
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +7335 -5432
- package/dist-lib/vite.cjs +2857 -12
- package/dist-lib/worklet-executable.cjs +14 -2
- package/dist-lib/worklet-executable.mjs +14 -2
- package/package.json +1 -1
- package/src/backend-origin.ts +13 -6
- package/src/expo-swift-host.ts +5 -2
- package/src/expoKotlinContract.ts +4 -7
- package/src/expoSwiftContract.ts +4 -6
- package/src/host/staged-host-files.ts +9 -0
- package/src/native-app-identity-project.ts +1 -4
- package/src/native-app-identity.ts +1 -4
- package/src/nativeAppIconContract.ts +1 -4
- package/src/output-lock-stdio.ts +36 -0
- package/src/react-native-bridge-modules.ts +21 -6
- package/src/react-native-host-modules.ts +4 -1
- package/src/settings-bundle.ts +1 -4
- package/src/swift-compile.ts +91 -33
- package/src/swift-distribution.lock.json +22 -12
- package/src/swift-distribution.ts +103 -4
- package/src/swift-host.ts +89 -26
- package/src/swift-icu.ts +16 -10
- package/src/swift-objc-compile.ts +355 -0
- package/src/swift-objc-sdk.ts +689 -18
- package/src/swift-objc-standin.ts +126 -14
- package/src/swift-package-manifest.ts +39 -1
- package/src/swift-packages.ts +35 -21
- package/src/swift-standin-emit.ts +40 -7
- package/src/swift-standins.ts +404 -138
- package/src/swift-submit.ts +3 -5
- package/src/swift-toolchain.ts +378 -46
- package/src/worker-system-chunks.ts +11 -12
- package/src/worklet-executable.ts +19 -1
- package/src/xcode-project.ts +270 -30
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/native-app-identity-project.ts
|
|
4
4
|
import fs2 from "node:fs";
|
|
@@ -187,10 +187,12 @@ function androidMergedResourceValuesDirectory(manifestFile) {
|
|
|
187
187
|
return `${intermediates}incremental/${variant}/merge${taskVariant}Resources/merged.dir`;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
// src/
|
|
190
|
+
// src/is-record.ts
|
|
191
191
|
function isRecord(value) {
|
|
192
192
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
193
193
|
}
|
|
194
|
+
|
|
195
|
+
// src/nativeAppIconContract.ts
|
|
194
196
|
function resolveNativeAppIconArtwork(resources, readText, resourceUri, icons, primaryName, alternateNames, resolveReference) {
|
|
195
197
|
const members = new Set(resources);
|
|
196
198
|
const dictionary = isRecord(icons) ? icons : {};
|
|
@@ -444,21 +446,18 @@ function visitXcodeTargetMembers(objects, targetId, resolvePath, filesUnder, joi
|
|
|
444
446
|
}
|
|
445
447
|
|
|
446
448
|
// src/native-app-identity.ts
|
|
447
|
-
function isRecord2(value) {
|
|
448
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
449
|
-
}
|
|
450
449
|
function nonEmptyString(value) {
|
|
451
450
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
452
451
|
}
|
|
453
452
|
function readGoogleSignInConfiguration(plist3, resources) {
|
|
454
453
|
const clientIds = {};
|
|
455
454
|
for (const [file, value] of Object.entries(resources)) {
|
|
456
|
-
if (
|
|
455
|
+
if (isRecord(value) && typeof value.CLIENT_ID === "string")
|
|
457
456
|
clientIds[file.split("/").pop()?.replace(/\.plist$/, "") ?? file] = value.CLIENT_ID;
|
|
458
457
|
}
|
|
459
458
|
const urlSchemes = [];
|
|
460
459
|
for (const entry of Array.isArray(plist3.CFBundleURLTypes) ? plist3.CFBundleURLTypes : []) {
|
|
461
|
-
if (!
|
|
460
|
+
if (!isRecord(entry) || !Array.isArray(entry.CFBundleURLSchemes)) continue;
|
|
462
461
|
for (const scheme of entry.CFBundleURLSchemes)
|
|
463
462
|
if (typeof scheme === "string") urlSchemes.push(scheme);
|
|
464
463
|
}
|
|
@@ -566,14 +565,14 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
566
565
|
let objects = {};
|
|
567
566
|
try {
|
|
568
567
|
const parsed = parseOpenStepPlist(pbxproj);
|
|
569
|
-
if (
|
|
570
|
-
objects =
|
|
568
|
+
if (isRecord(parsed)) {
|
|
569
|
+
objects = isRecord(parsed.objects) ? parsed.objects : parsed;
|
|
571
570
|
}
|
|
572
571
|
} catch {
|
|
573
572
|
}
|
|
574
573
|
const targets = [];
|
|
575
574
|
for (const [id, obj] of Object.entries(objects)) {
|
|
576
|
-
if (
|
|
575
|
+
if (isRecord(obj) && obj.isa === "PBXNativeTarget" && typeof obj.name === "string") {
|
|
577
576
|
targets.push({
|
|
578
577
|
id,
|
|
579
578
|
name: obj.name,
|
|
@@ -619,13 +618,13 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
619
618
|
PRODUCT_NAME: targetName
|
|
620
619
|
};
|
|
621
620
|
for (const obj of Object.values(objects)) {
|
|
622
|
-
if (
|
|
621
|
+
if (isRecord(obj) && obj.isa === "PBXProject" && typeof obj.buildConfigurationList === "string") {
|
|
623
622
|
const listObj = objects[obj.buildConfigurationList];
|
|
624
|
-
if (
|
|
623
|
+
if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
|
|
625
624
|
for (const configId of listObj.buildConfigurations) {
|
|
626
625
|
if (typeof configId === "string") {
|
|
627
626
|
const configObj = objects[configId];
|
|
628
|
-
if (
|
|
627
|
+
if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
|
|
629
628
|
for (const [k, v] of Object.entries(configObj.buildSettings)) {
|
|
630
629
|
if (typeof v === "string") settings[k] = v;
|
|
631
630
|
}
|
|
@@ -637,11 +636,11 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
637
636
|
}
|
|
638
637
|
if (selectedTarget?.buildConfigurationList) {
|
|
639
638
|
const listObj = objects[selectedTarget.buildConfigurationList];
|
|
640
|
-
if (
|
|
639
|
+
if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
|
|
641
640
|
for (const configId of listObj.buildConfigurations) {
|
|
642
641
|
if (typeof configId === "string") {
|
|
643
642
|
const configObj = objects[configId];
|
|
644
|
-
if (
|
|
643
|
+
if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
|
|
645
644
|
for (const [k, v] of Object.entries(configObj.buildSettings)) {
|
|
646
645
|
if (typeof v === "string") settings[k] = v;
|
|
647
646
|
}
|
|
@@ -692,7 +691,7 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
692
691
|
if (!bundleName) return null;
|
|
693
692
|
const applicationName = identityFieldFrom(settings, plistString(plist3, "CFBundleDisplayName"), void 0) ?? bundleName;
|
|
694
693
|
const dictionary = parseInfoPlist(plist3);
|
|
695
|
-
if (!
|
|
694
|
+
if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
|
|
696
695
|
const declaredDisplayName = dictionary.CFBundleDisplayName;
|
|
697
696
|
const applicationDisplayName = typeof declaredDisplayName === "string" ? resolveBuildSetting(declaredDisplayName, settings) : void 0;
|
|
698
697
|
if (applicationDisplayName === null)
|
|
@@ -705,9 +704,9 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
705
704
|
if (dtPlatformVersion === null)
|
|
706
705
|
throw new Error("native app Info.plist DTPlatformVersion is unresolved");
|
|
707
706
|
const icons = dictionary.CFBundleIcons;
|
|
708
|
-
const alternates =
|
|
707
|
+
const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
|
|
709
708
|
const alternateIconNames = /* @__PURE__ */ new Set();
|
|
710
|
-
for (const name of
|
|
709
|
+
for (const name of isRecord(alternates) ? Object.keys(alternates) : []) {
|
|
711
710
|
const resolved = resolveBuildSetting(name, settings);
|
|
712
711
|
if (resolved === null) throw new Error("native alternate icon name is unresolved");
|
|
713
712
|
alternateIconNames.add(resolved);
|
|
@@ -811,11 +810,11 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
811
810
|
return `${base.startsWith("/") ? "/" : ""}${segments.join("/")}`;
|
|
812
811
|
};
|
|
813
812
|
const project = Object.values(objects).find(
|
|
814
|
-
(object) =>
|
|
813
|
+
(object) => isRecord(object) && object.isa === "PBXProject"
|
|
815
814
|
);
|
|
816
815
|
const projectDir = join(
|
|
817
816
|
pbxprojPath.replace(/(?:^|\/)[^/]+\.xcodeproj\/project\.pbxproj$/, ""),
|
|
818
|
-
|
|
817
|
+
isRecord(project) && typeof project.projectDirPath === "string" ? project.projectDirPath : ""
|
|
819
818
|
);
|
|
820
819
|
const paths = Object.keys(files);
|
|
821
820
|
visitXcodeTargetMembers(
|
|
@@ -928,6 +927,8 @@ function parsePlistSource(source) {
|
|
|
928
927
|
}
|
|
929
928
|
|
|
930
929
|
// src/xcode-project.ts
|
|
930
|
+
import { execFileSync } from "node:child_process";
|
|
931
|
+
import { createHash } from "node:crypto";
|
|
931
932
|
import fs from "node:fs";
|
|
932
933
|
import path2 from "node:path";
|
|
933
934
|
import plist2 from "plist";
|
|
@@ -1535,33 +1536,131 @@ function expand(value, lookup) {
|
|
|
1535
1536
|
}
|
|
1536
1537
|
);
|
|
1537
1538
|
}
|
|
1538
|
-
|
|
1539
|
+
var preparedSourcePhases = /* @__PURE__ */ new Map();
|
|
1540
|
+
function targetMembers(ref, settings, options, settingKeys, projectInputs) {
|
|
1539
1541
|
const { project, target, id: targetId } = ref;
|
|
1540
1542
|
const targetName = str(target.name) ?? targetId;
|
|
1541
1543
|
const sources = /* @__PURE__ */ new Set();
|
|
1542
1544
|
const allSources = /* @__PURE__ */ new Set();
|
|
1543
1545
|
const resources = /* @__PURE__ */ new Set();
|
|
1544
1546
|
const scriptForOutput = /* @__PURE__ */ new Map();
|
|
1545
|
-
const noteScriptOutput = (raw, script) => {
|
|
1546
|
-
const expanded = expand(raw, settings);
|
|
1547
|
-
if (!expanded.endsWith(".swift")) return;
|
|
1548
|
-
const absolute = path2.isAbsolute(expanded) ? path2.normalize(expanded) : path2.resolve(project.projectDir, expanded);
|
|
1549
|
-
if (!scriptForOutput.has(absolute)) scriptForOutput.set(absolute, script);
|
|
1550
|
-
};
|
|
1551
1547
|
for (const phaseId of list(target.buildPhases)) {
|
|
1552
1548
|
const phase = project.object(phaseId);
|
|
1553
1549
|
if (phase?.isa !== "PBXShellScriptBuildPhase") continue;
|
|
1554
1550
|
const script = str(phase.name) ?? phaseId;
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1551
|
+
const absolute = (raw) => path2.resolve(project.projectDir, expand(raw, settings));
|
|
1552
|
+
const inputs = list(phase.inputPaths).map(absolute);
|
|
1553
|
+
const outputs = list(phase.outputPaths).map(absolute);
|
|
1554
|
+
const fileLists = /* @__PURE__ */ new Map();
|
|
1555
|
+
for (const kind of ["INPUT", "OUTPUT"]) {
|
|
1556
|
+
const lists = list(
|
|
1557
|
+
kind === "INPUT" ? phase.inputFileListPaths : phase.outputFileListPaths
|
|
1558
|
+
).map((raw) => {
|
|
1559
|
+
const file = absolute(raw);
|
|
1560
|
+
if (!fs.existsSync(file)) {
|
|
1561
|
+
return { file, entries: [] };
|
|
1562
|
+
}
|
|
1563
|
+
const entries = fs.readFileSync(file, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#")).map(absolute);
|
|
1564
|
+
return { file, entries };
|
|
1565
|
+
});
|
|
1566
|
+
fileLists.set(kind, lists);
|
|
1567
|
+
}
|
|
1568
|
+
const allOutputs = [
|
|
1569
|
+
...outputs,
|
|
1570
|
+
...fileLists.get("OUTPUT").flatMap((item) => item.entries)
|
|
1571
|
+
];
|
|
1572
|
+
for (const output of allOutputs)
|
|
1573
|
+
if (output.endsWith(".swift") && !scriptForOutput.has(output))
|
|
1574
|
+
scriptForOutput.set(output, script);
|
|
1575
|
+
const inputFiles = [
|
|
1576
|
+
...inputs,
|
|
1577
|
+
...fileLists.get("INPUT").flatMap((item) => [item.file, ...item.entries]),
|
|
1578
|
+
...fileLists.get("OUTPUT").map((item) => item.file)
|
|
1579
|
+
];
|
|
1580
|
+
if (allOutputs.some((file) => file.endsWith(".swift"))) {
|
|
1581
|
+
for (const file of inputFiles) if (fs.existsSync(file)) projectInputs.add(file);
|
|
1582
|
+
}
|
|
1583
|
+
if (options.prepareGeneratedSources && options.requireSources !== false && allOutputs.some((file) => file.endsWith(".swift"))) {
|
|
1584
|
+
const phaseDir = path2.join(settings("TARGET_TEMP_DIR"), `Script-${phaseId}`);
|
|
1585
|
+
for (const lists of fileLists.values())
|
|
1586
|
+
for (const { file } of lists)
|
|
1587
|
+
if (!fs.existsSync(file))
|
|
1588
|
+
throw new Error(
|
|
1589
|
+
`${targetName}: Run Script "${script}" missing file list ${file}`
|
|
1590
|
+
);
|
|
1591
|
+
const env = {
|
|
1592
|
+
...process.env,
|
|
1593
|
+
...Object.fromEntries(
|
|
1594
|
+
[...settingKeys].filter((key2) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(key2)).map((key2) => [key2, settings(key2)])
|
|
1595
|
+
)
|
|
1596
|
+
};
|
|
1597
|
+
const declared = { INPUT: inputs, OUTPUT: outputs };
|
|
1598
|
+
for (const kind of ["INPUT", "OUTPUT"]) {
|
|
1599
|
+
env[`SCRIPT_${kind}_FILE_COUNT`] = String(declared[kind].length);
|
|
1600
|
+
declared[kind].forEach((file, index) => {
|
|
1601
|
+
env[`SCRIPT_${kind}_FILE_${index}`] = file;
|
|
1602
|
+
});
|
|
1603
|
+
const lists = fileLists.get(kind);
|
|
1604
|
+
env[`SCRIPT_${kind}_FILE_LIST_COUNT`] = String(lists.length);
|
|
1605
|
+
lists.forEach((_item, index) => {
|
|
1606
|
+
env[`SCRIPT_${kind}_FILE_LIST_${index}`] = path2.join(
|
|
1607
|
+
phaseDir,
|
|
1608
|
+
`${kind}-${index}.xcfilelist`
|
|
1609
|
+
);
|
|
1610
|
+
});
|
|
1564
1611
|
}
|
|
1612
|
+
const signature = createHash("sha256").update(
|
|
1613
|
+
JSON.stringify([phase, [...settingKeys].map((key2) => [key2, settings(key2)])])
|
|
1614
|
+
);
|
|
1615
|
+
for (const file of inputFiles) {
|
|
1616
|
+
signature.update(file);
|
|
1617
|
+
if (fs.existsSync(file)) {
|
|
1618
|
+
const stat = fs.statSync(file);
|
|
1619
|
+
signature.update(`${stat.mtimeMs}:${stat.ctimeMs}:${stat.size}`);
|
|
1620
|
+
} else signature.update("missing");
|
|
1621
|
+
}
|
|
1622
|
+
const stamp = signature.digest("hex");
|
|
1623
|
+
const key = `${project.projectFile}:${targetId}:${phaseId}:${settings("CONFIGURATION")}`;
|
|
1624
|
+
if (preparedSourcePhases.get(key) === stamp && allOutputs.every((file) => fs.existsSync(file)))
|
|
1625
|
+
continue;
|
|
1626
|
+
fs.mkdirSync(phaseDir, { recursive: true });
|
|
1627
|
+
fs.mkdirSync(settings("BUILT_PRODUCTS_DIR"), { recursive: true });
|
|
1628
|
+
fs.mkdirSync(settings("DERIVED_FILE_DIR"), { recursive: true });
|
|
1629
|
+
for (const [kind, lists] of fileLists)
|
|
1630
|
+
lists.forEach((item, index) => {
|
|
1631
|
+
fs.writeFileSync(
|
|
1632
|
+
env[`SCRIPT_${kind}_FILE_LIST_${index}`],
|
|
1633
|
+
`${item.entries.join("\n")}
|
|
1634
|
+
`
|
|
1635
|
+
);
|
|
1636
|
+
});
|
|
1637
|
+
try {
|
|
1638
|
+
execFileSync(
|
|
1639
|
+
str(phase.shellPath) ?? "/bin/sh",
|
|
1640
|
+
["-c", str(phase.shellScript) ?? ""],
|
|
1641
|
+
{
|
|
1642
|
+
cwd: project.projectDir,
|
|
1643
|
+
env,
|
|
1644
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1645
|
+
timeout: 12e4
|
|
1646
|
+
}
|
|
1647
|
+
);
|
|
1648
|
+
} catch (error) {
|
|
1649
|
+
const output = error instanceof Error ? `${error.message}
|
|
1650
|
+
${"stdout" in error ? String(error.stdout) : ""}${"stderr" in error ? String(error.stderr) : ""}` : String(error);
|
|
1651
|
+
throw new Error(
|
|
1652
|
+
`${targetName}: Run Script "${script}" failed preparing generated Swift sources:
|
|
1653
|
+
${output}`
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1656
|
+
const missing = allOutputs.filter(
|
|
1657
|
+
(file) => file.endsWith(".swift") && !fs.existsSync(file)
|
|
1658
|
+
);
|
|
1659
|
+
if (missing.length > 0)
|
|
1660
|
+
throw new Error(
|
|
1661
|
+
`${targetName}: Run Script "${script}" did not produce ${missing.join(", ")}`
|
|
1662
|
+
);
|
|
1663
|
+
preparedSourcePhases.set(key, stamp);
|
|
1565
1664
|
}
|
|
1566
1665
|
}
|
|
1567
1666
|
visitXcodeTargetMembers(
|
|
@@ -1751,22 +1850,95 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
1751
1850
|
SRCROOT: ref.project.projectDir,
|
|
1752
1851
|
SOURCE_ROOT: ref.project.projectDir,
|
|
1753
1852
|
PROJECT_DIR: ref.project.projectDir,
|
|
1853
|
+
SYMROOT: path2.join(ref.project.projectDir, ".build/peach-xcode/Build/Products"),
|
|
1854
|
+
BUILD_DIR: "$(SYMROOT)",
|
|
1855
|
+
OBJROOT: path2.join(
|
|
1856
|
+
ref.project.projectDir,
|
|
1857
|
+
".build/peach-xcode/Build/Intermediates.noindex"
|
|
1858
|
+
),
|
|
1859
|
+
CONFIGURATION_BUILD_DIR: "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)",
|
|
1860
|
+
BUILT_PRODUCTS_DIR: "$(CONFIGURATION_BUILD_DIR)",
|
|
1861
|
+
TARGET_BUILD_DIR: "$(CONFIGURATION_BUILD_DIR)",
|
|
1862
|
+
PROJECT_TEMP_DIR: "$(OBJROOT)/$(PROJECT_NAME).build",
|
|
1863
|
+
CONFIGURATION_TEMP_DIR: "$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)",
|
|
1864
|
+
TARGET_TEMP_DIR: "$(CONFIGURATION_TEMP_DIR)/$(TARGET_NAME).build",
|
|
1865
|
+
DERIVED_FILE_DIR: "$(TARGET_TEMP_DIR)/DerivedSources",
|
|
1866
|
+
DERIVED_FILES_DIR: "$(DERIVED_FILE_DIR)",
|
|
1867
|
+
PLATFORM_NAME: "iphonesimulator",
|
|
1868
|
+
EFFECTIVE_PLATFORM_NAME: "-iphonesimulator",
|
|
1869
|
+
CURRENT_ARCH: "arm64",
|
|
1870
|
+
ARCHS: "arm64",
|
|
1871
|
+
ACTION: "build",
|
|
1754
1872
|
DEVELOPMENT_LANGUAGE: str(ref.project.project.developmentRegion) ?? "en"
|
|
1755
1873
|
},
|
|
1756
1874
|
options
|
|
1757
1875
|
);
|
|
1758
1876
|
for (const file of read) xcconfigs.add(file);
|
|
1759
1877
|
const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
|
|
1878
|
+
const members = targetMembers(ref, settings2, options, keys, xcconfigs);
|
|
1879
|
+
const implementations = members.allSources.filter(
|
|
1880
|
+
(file) => /\.(c|cc|cpp|cxx|m|mm)$/.test(file)
|
|
1881
|
+
);
|
|
1882
|
+
const absolute = (file) => path2.resolve(ref.project.projectDir, file);
|
|
1883
|
+
const fileFlags = {};
|
|
1884
|
+
for (const phaseId of list(ref.target.buildPhases)) {
|
|
1885
|
+
const phase = ref.project.object(phaseId);
|
|
1886
|
+
if (phase?.isa !== "PBXSourcesBuildPhase") continue;
|
|
1887
|
+
for (const id of list(phase.files)) {
|
|
1888
|
+
const file = ref.project.object(id);
|
|
1889
|
+
const resolved = ref.project.resolvePath(str(file?.fileRef) ?? "");
|
|
1890
|
+
if (resolved && implementations.includes(resolved))
|
|
1891
|
+
fileFlags[resolved] = settingList(
|
|
1892
|
+
expand(
|
|
1893
|
+
str(isDict(file?.settings) ? file.settings.COMPILER_FLAGS : void 0) ?? "",
|
|
1894
|
+
settings2
|
|
1895
|
+
)
|
|
1896
|
+
);
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1760
1899
|
return {
|
|
1761
1900
|
settings: settings2,
|
|
1762
1901
|
keys,
|
|
1763
1902
|
module: {
|
|
1764
1903
|
name,
|
|
1765
1904
|
moduleName: applyOperator(settings2("PRODUCT_MODULE_NAME"), "c99extidentifier"),
|
|
1766
|
-
...
|
|
1905
|
+
...members,
|
|
1767
1906
|
languageMode: swiftVersion >= 6 ? 6 : 5,
|
|
1768
1907
|
mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor",
|
|
1769
|
-
defines: compilationConditions(settings2)
|
|
1908
|
+
defines: compilationConditions(settings2),
|
|
1909
|
+
iosDeploymentTarget: settings2("IPHONEOS_DEPLOYMENT_TARGET") || null,
|
|
1910
|
+
...implementations.some((file) => /\.mm?$/.test(file)) ? {
|
|
1911
|
+
objc: {
|
|
1912
|
+
headers: Object.keys(ref.project.objects).flatMap((id) => {
|
|
1913
|
+
const file = ref.project.resolvePath(id);
|
|
1914
|
+
return file && /\.(h|hh|hpp|hxx|pch)$/.test(file) && fs.existsSync(file) ? [file] : [];
|
|
1915
|
+
}),
|
|
1916
|
+
prefixHeader: settings2("GCC_PREFIX_HEADER") ? absolute(settings2("GCC_PREFIX_HEADER")) : null,
|
|
1917
|
+
bridgingHeader: settings2("SWIFT_OBJC_BRIDGING_HEADER") ? absolute(settings2("SWIFT_OBJC_BRIDGING_HEADER")) : null,
|
|
1918
|
+
headerSearchPaths: [
|
|
1919
|
+
...settingList(settings2("HEADER_SEARCH_PATHS")),
|
|
1920
|
+
...settingList(settings2("USER_HEADER_SEARCH_PATHS"))
|
|
1921
|
+
].map(absolute),
|
|
1922
|
+
frameworkSearchPaths: settingList(settings2("FRAMEWORK_SEARCH_PATHS")).map(
|
|
1923
|
+
absolute
|
|
1924
|
+
),
|
|
1925
|
+
flags: [
|
|
1926
|
+
...settings2("CLANG_ENABLE_OBJC_ARC") === "YES" ? ["-fobjc-arc"] : [],
|
|
1927
|
+
...settings2("CLANG_ENABLE_OBJC_WEAK") === "YES" ? ["-fobjc-weak"] : [],
|
|
1928
|
+
...settings2("CLANG_ENABLE_MODULES") === "YES" ? ["-fmodules"] : [],
|
|
1929
|
+
...settings2("GCC_C_LANGUAGE_STANDARD") ? [`-std=${settings2("GCC_C_LANGUAGE_STANDARD")}`] : [],
|
|
1930
|
+
...settingList(settings2("GCC_PREPROCESSOR_DEFINITIONS")).map(
|
|
1931
|
+
(value) => `-D${value}`
|
|
1932
|
+
),
|
|
1933
|
+
...settingList(settings2("OTHER_CFLAGS"))
|
|
1934
|
+
],
|
|
1935
|
+
cxxFlags: [
|
|
1936
|
+
...settings2("CLANG_CXX_LANGUAGE_STANDARD") ? [`-std=${settings2("CLANG_CXX_LANGUAGE_STANDARD")}`] : [],
|
|
1937
|
+
...settingList(settings2("OTHER_CPLUSPLUSFLAGS"))
|
|
1938
|
+
],
|
|
1939
|
+
fileFlags
|
|
1940
|
+
}
|
|
1941
|
+
} : {}
|
|
1770
1942
|
}
|
|
1771
1943
|
};
|
|
1772
1944
|
};
|
|
@@ -1815,6 +1987,23 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
1815
1987
|
...projects.flatMap(
|
|
1816
1988
|
(project) => Object.entries(project.objects).flatMap(([id, entry]) => {
|
|
1817
1989
|
if (!isDict(entry)) return [];
|
|
1990
|
+
if (entry.isa === "PBXFileSystemSynchronizedRootGroup") {
|
|
1991
|
+
const folder = project.resolvePath(id);
|
|
1992
|
+
const pending = folder ? [folder] : [];
|
|
1993
|
+
const packages = [];
|
|
1994
|
+
while (pending.length > 0) {
|
|
1995
|
+
const dir = pending.pop();
|
|
1996
|
+
if (fs.existsSync(path2.join(dir, "Package.swift"))) {
|
|
1997
|
+
packages.push(dir);
|
|
1998
|
+
continue;
|
|
1999
|
+
}
|
|
2000
|
+
if (!isDirectory(dir)) continue;
|
|
2001
|
+
for (const child of fs.readdirSync(dir, { withFileTypes: true }))
|
|
2002
|
+
if (child.isDirectory() && !child.name.startsWith("."))
|
|
2003
|
+
pending.push(path2.join(dir, child.name));
|
|
2004
|
+
}
|
|
2005
|
+
return packages;
|
|
2006
|
+
}
|
|
1818
2007
|
const candidate = entry.isa === "XCLocalSwiftPackageReference" ? path2.resolve(project.projectDir, str(entry.relativePath) ?? "") : entry.isa === "PBXFileReference" ? project.resolvePath(id) : null;
|
|
1819
2008
|
return candidate && fs.existsSync(path2.join(candidate, "Package.swift")) ? [candidate] : [];
|
|
1820
2009
|
})
|
|
@@ -1869,6 +2058,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
1869
2058
|
"swiftpm",
|
|
1870
2059
|
"Package.resolved"
|
|
1871
2060
|
);
|
|
2061
|
+
const packageResolved = fs.existsSync(resolvedFile) ? [fs.realpathSync(resolvedFile)] : [...new Set(localPackageDirs.map((dir) => path2.join(dir, "Package.resolved")))].filter((file) => fs.existsSync(file)).map((file) => fs.realpathSync(file)).sort();
|
|
1872
2062
|
const used = order.map((ref) => ref.project);
|
|
1873
2063
|
return {
|
|
1874
2064
|
...module,
|
|
@@ -1894,7 +2084,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
1894
2084
|
...new Set(localPackageDirs.map((dir) => fs.realpathSync(dir)))
|
|
1895
2085
|
].sort(),
|
|
1896
2086
|
binaryFrameworks: [...binaryFrameworks].map(([name, file]) => ({ name, path: file })).sort((left, right) => left.name.localeCompare(right.name)),
|
|
1897
|
-
packageResolved
|
|
2087
|
+
packageResolved,
|
|
1898
2088
|
appTargets: appTargetNames,
|
|
1899
2089
|
configuration,
|
|
1900
2090
|
settings
|
|
@@ -1902,15 +2092,12 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
|
|
|
1902
2092
|
}
|
|
1903
2093
|
|
|
1904
2094
|
// src/native-app-identity-project.ts
|
|
1905
|
-
function isRecord3(value) {
|
|
1906
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1907
|
-
}
|
|
1908
2095
|
function nonEmptyString2(value) {
|
|
1909
2096
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1910
2097
|
}
|
|
1911
2098
|
function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSource) {
|
|
1912
2099
|
const dictionary = parseInfoPlist(app.infoPlist);
|
|
1913
|
-
if (!
|
|
2100
|
+
if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
|
|
1914
2101
|
const settings = app.settings;
|
|
1915
2102
|
const bundleIdentifier = nonEmptyString2(dictionary.CFBundleIdentifier) ?? nonEmptyString2(settings?.("PRODUCT_BUNDLE_IDENTIFIER"));
|
|
1916
2103
|
if (!bundleIdentifier) throw new Error("native app has no bundle identifier");
|
|
@@ -1927,8 +2114,8 @@ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSo
|
|
|
1927
2114
|
const designRequiresCompatibility = dictionary.UIDesignRequiresCompatibility === true;
|
|
1928
2115
|
const alternateIconNames = /* @__PURE__ */ new Set();
|
|
1929
2116
|
const icons = dictionary.CFBundleIcons;
|
|
1930
|
-
const alternates =
|
|
1931
|
-
if (
|
|
2117
|
+
const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
|
|
2118
|
+
if (isRecord(alternates)) {
|
|
1932
2119
|
for (const name of Object.keys(alternates)) {
|
|
1933
2120
|
if (name) alternateIconNames.add(name);
|
|
1934
2121
|
}
|
|
@@ -2160,7 +2347,7 @@ function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
|
|
|
2160
2347
|
const installedManifest = JSON.parse(
|
|
2161
2348
|
fs2.readFileSync(reanimatedManifestPath, "utf8")
|
|
2162
2349
|
);
|
|
2163
|
-
const installedVersion =
|
|
2350
|
+
const installedVersion = isRecord(installedManifest) ? nonEmptyString2(installedManifest.version) : void 0;
|
|
2164
2351
|
if (!installedVersion) throw new Error("Reanimated package version is malformed");
|
|
2165
2352
|
if (Number.parseInt(installedVersion, 10) < 4) return identity;
|
|
2166
2353
|
const defaults = JSON.parse(
|
|
@@ -2172,11 +2359,11 @@ function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
|
|
|
2172
2359
|
"utf8"
|
|
2173
2360
|
)
|
|
2174
2361
|
);
|
|
2175
|
-
if (!
|
|
2362
|
+
if (!isRecord(defaults)) throw new Error("Reanimated static flags are malformed");
|
|
2176
2363
|
const manifest = JSON.parse(fs2.readFileSync(projectManifestPath, "utf8"));
|
|
2177
|
-
const reanimated =
|
|
2178
|
-
const overrides =
|
|
2179
|
-
if (overrides !== void 0 && !
|
|
2364
|
+
const reanimated = isRecord(manifest) ? manifest.reanimated : void 0;
|
|
2365
|
+
const overrides = isRecord(reanimated) ? reanimated.staticFeatureFlags : void 0;
|
|
2366
|
+
if (overrides !== void 0 && !isRecord(overrides)) {
|
|
2180
2367
|
throw new Error("Reanimated static flag overrides are malformed");
|
|
2181
2368
|
}
|
|
2182
2369
|
const flags = {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -241,6 +241,11 @@ function isFooterBlockLine(source, line, end) {
|
|
|
241
241
|
return line === end || source.startsWith("globalThis.", line) || source.startsWith("//", line);
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
// src/is-record.ts
|
|
245
|
+
function isRecord(value) {
|
|
246
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
247
|
+
}
|
|
248
|
+
|
|
244
249
|
// src/assetCatalogContract.ts
|
|
245
250
|
function isSwiftImageVariants(value) {
|
|
246
251
|
return Array.isArray(value) && value.length > 0 && value.every(
|
|
@@ -249,9 +254,6 @@ function isSwiftImageVariants(value) {
|
|
|
249
254
|
}
|
|
250
255
|
|
|
251
256
|
// src/nativeAppIconContract.ts
|
|
252
|
-
function isRecord(value) {
|
|
253
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
254
|
-
}
|
|
255
257
|
function isNativeAppIconArtwork(value) {
|
|
256
258
|
return isRecord(value) && (value.primary === void 0 || isSwiftImageVariants(value.primary)) && isRecord(value.alternates) && Object.values(value.alternates).every(isSwiftImageVariants);
|
|
257
259
|
}
|
|
@@ -525,35 +527,32 @@ function visitXcodeTargetMembers(objects, targetId, resolvePath, filesUnder, joi
|
|
|
525
527
|
var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
|
|
526
528
|
var METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
|
|
527
529
|
var NATIVE_APP_IDENTITY_HEADER = "Peach-Native-App-Identity";
|
|
528
|
-
function isRecord2(value) {
|
|
529
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
530
|
-
}
|
|
531
530
|
function nonEmptyString(value) {
|
|
532
531
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
533
532
|
}
|
|
534
533
|
function isNativeAppIdentity(value) {
|
|
535
|
-
if (!
|
|
534
|
+
if (!isRecord(value)) return false;
|
|
536
535
|
for (const key of ["statusBarHidden", "viewControllerBasedStatusBarAppearance"]) {
|
|
537
536
|
if (value[key] !== void 0 && typeof value[key] !== "boolean") return false;
|
|
538
537
|
}
|
|
539
538
|
const oneUpdates = value.oneUpdates;
|
|
540
|
-
if (oneUpdates !== void 0 && (!
|
|
539
|
+
if (oneUpdates !== void 0 && (!isRecord(oneUpdates) || typeof oneUpdates.enabled !== "boolean" || oneUpdates.url !== null && typeof oneUpdates.url !== "string" || oneUpdates.runtimeVersion !== null && typeof oneUpdates.runtimeVersion !== "string" || oneUpdates.embeddedManifestJson !== null && typeof oneUpdates.embeddedManifestJson !== "string" || oneUpdates.enabled && (typeof oneUpdates.url !== "string" || oneUpdates.url.length === 0 || typeof oneUpdates.runtimeVersion !== "string" || oneUpdates.runtimeVersion.length === 0))) {
|
|
541
540
|
return false;
|
|
542
541
|
}
|
|
543
542
|
if (value.dtPlatformVersion !== void 0 && typeof value.dtPlatformVersion !== "string")
|
|
544
543
|
return false;
|
|
545
544
|
if (value.androidManifestPermissions !== void 0 && (!Array.isArray(value.androidManifestPermissions) || !value.androidManifestPermissions.every(
|
|
546
|
-
(permission) =>
|
|
545
|
+
(permission) => isRecord(permission) && typeof permission.name === "string" && permission.name.length > 0 && Number.isInteger(permission.minSdkVersion) && typeof permission.minSdkVersion === "number" && permission.minSdkVersion > 0 && (permission.maxSdkVersion === void 0 || typeof permission.maxSdkVersion === "number" && Number.isInteger(permission.maxSdkVersion) && permission.maxSdkVersion >= 0)
|
|
547
546
|
)))
|
|
548
547
|
return false;
|
|
549
|
-
if (value.googleSignIn !== void 0 && !
|
|
548
|
+
if (value.googleSignIn !== void 0 && !isRecord(value.googleSignIn)) return false;
|
|
550
549
|
const descriptions = value.permissionUsageDescriptions;
|
|
551
|
-
if (value.reanimatedStaticFeatureFlags !== void 0 && (!
|
|
550
|
+
if (value.reanimatedStaticFeatureFlags !== void 0 && (!isRecord(value.reanimatedStaticFeatureFlags) || !Object.values(value.reanimatedStaticFeatureFlags).every(
|
|
552
551
|
(flag) => typeof flag === "boolean"
|
|
553
552
|
)))
|
|
554
553
|
return false;
|
|
555
|
-
if (descriptions !== void 0 && !
|
|
556
|
-
if (value.infoPlistStrings !== void 0 && (!
|
|
554
|
+
if (descriptions !== void 0 && !isRecord(descriptions)) return false;
|
|
555
|
+
if (value.infoPlistStrings !== void 0 && (!isRecord(value.infoPlistStrings) || !Object.values(value.infoPlistStrings).every((entry) => typeof entry === "string")))
|
|
557
556
|
return false;
|
|
558
557
|
if (value.urlQuerySchemes !== void 0 && !Array.isArray(value.urlQuerySchemes))
|
|
559
558
|
return false;
|
|
@@ -673,7 +672,7 @@ function equalIdentityValues(left, right) {
|
|
|
673
672
|
if (Array.isArray(left) && Array.isArray(right)) {
|
|
674
673
|
return left.length === right.length && left.every((value, index) => equalIdentityValues(value, right[index]));
|
|
675
674
|
}
|
|
676
|
-
if (!
|
|
675
|
+
if (!isRecord(left) || !isRecord(right)) return false;
|
|
677
676
|
const keys = Object.keys(left);
|
|
678
677
|
return keys.length === Object.keys(right).length && keys.every(
|
|
679
678
|
(key) => Object.hasOwn(right, key) && equalIdentityValues(left[key], right[key])
|
|
@@ -763,12 +762,12 @@ function insertNativeAppIdentityFooter(source, identity) {
|
|
|
763
762
|
function readGoogleSignInConfiguration(plist, resources) {
|
|
764
763
|
const clientIds = {};
|
|
765
764
|
for (const [file, value] of Object.entries(resources)) {
|
|
766
|
-
if (
|
|
765
|
+
if (isRecord(value) && typeof value.CLIENT_ID === "string")
|
|
767
766
|
clientIds[file.split("/").pop()?.replace(/\.plist$/, "") ?? file] = value.CLIENT_ID;
|
|
768
767
|
}
|
|
769
768
|
const urlSchemes = [];
|
|
770
769
|
for (const entry of Array.isArray(plist.CFBundleURLTypes) ? plist.CFBundleURLTypes : []) {
|
|
771
|
-
if (!
|
|
770
|
+
if (!isRecord(entry) || !Array.isArray(entry.CFBundleURLSchemes)) continue;
|
|
772
771
|
for (const scheme of entry.CFBundleURLSchemes)
|
|
773
772
|
if (typeof scheme === "string") urlSchemes.push(scheme);
|
|
774
773
|
}
|
|
@@ -876,14 +875,14 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
876
875
|
let objects = {};
|
|
877
876
|
try {
|
|
878
877
|
const parsed = parseOpenStepPlist(pbxproj);
|
|
879
|
-
if (
|
|
880
|
-
objects =
|
|
878
|
+
if (isRecord(parsed)) {
|
|
879
|
+
objects = isRecord(parsed.objects) ? parsed.objects : parsed;
|
|
881
880
|
}
|
|
882
881
|
} catch {
|
|
883
882
|
}
|
|
884
883
|
const targets = [];
|
|
885
884
|
for (const [id, obj] of Object.entries(objects)) {
|
|
886
|
-
if (
|
|
885
|
+
if (isRecord(obj) && obj.isa === "PBXNativeTarget" && typeof obj.name === "string") {
|
|
887
886
|
targets.push({
|
|
888
887
|
id,
|
|
889
888
|
name: obj.name,
|
|
@@ -929,13 +928,13 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
929
928
|
PRODUCT_NAME: targetName
|
|
930
929
|
};
|
|
931
930
|
for (const obj of Object.values(objects)) {
|
|
932
|
-
if (
|
|
931
|
+
if (isRecord(obj) && obj.isa === "PBXProject" && typeof obj.buildConfigurationList === "string") {
|
|
933
932
|
const listObj = objects[obj.buildConfigurationList];
|
|
934
|
-
if (
|
|
933
|
+
if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
|
|
935
934
|
for (const configId of listObj.buildConfigurations) {
|
|
936
935
|
if (typeof configId === "string") {
|
|
937
936
|
const configObj = objects[configId];
|
|
938
|
-
if (
|
|
937
|
+
if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
|
|
939
938
|
for (const [k, v] of Object.entries(configObj.buildSettings)) {
|
|
940
939
|
if (typeof v === "string") settings[k] = v;
|
|
941
940
|
}
|
|
@@ -947,11 +946,11 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
947
946
|
}
|
|
948
947
|
if (selectedTarget?.buildConfigurationList) {
|
|
949
948
|
const listObj = objects[selectedTarget.buildConfigurationList];
|
|
950
|
-
if (
|
|
949
|
+
if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
|
|
951
950
|
for (const configId of listObj.buildConfigurations) {
|
|
952
951
|
if (typeof configId === "string") {
|
|
953
952
|
const configObj = objects[configId];
|
|
954
|
-
if (
|
|
953
|
+
if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
|
|
955
954
|
for (const [k, v] of Object.entries(configObj.buildSettings)) {
|
|
956
955
|
if (typeof v === "string") settings[k] = v;
|
|
957
956
|
}
|
|
@@ -1002,7 +1001,7 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
1002
1001
|
if (!bundleName) return null;
|
|
1003
1002
|
const applicationName = identityFieldFrom(settings, plistString(plist, "CFBundleDisplayName"), void 0) ?? bundleName;
|
|
1004
1003
|
const dictionary = parseInfoPlist(plist);
|
|
1005
|
-
if (!
|
|
1004
|
+
if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
|
|
1006
1005
|
const declaredDisplayName = dictionary.CFBundleDisplayName;
|
|
1007
1006
|
const applicationDisplayName = typeof declaredDisplayName === "string" ? resolveBuildSetting(declaredDisplayName, settings) : void 0;
|
|
1008
1007
|
if (applicationDisplayName === null)
|
|
@@ -1015,9 +1014,9 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
1015
1014
|
if (dtPlatformVersion === null)
|
|
1016
1015
|
throw new Error("native app Info.plist DTPlatformVersion is unresolved");
|
|
1017
1016
|
const icons = dictionary.CFBundleIcons;
|
|
1018
|
-
const alternates =
|
|
1017
|
+
const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
|
|
1019
1018
|
const alternateIconNames = /* @__PURE__ */ new Set();
|
|
1020
|
-
for (const name of
|
|
1019
|
+
for (const name of isRecord(alternates) ? Object.keys(alternates) : []) {
|
|
1021
1020
|
const resolved = resolveBuildSetting(name, settings);
|
|
1022
1021
|
if (resolved === null) throw new Error("native alternate icon name is unresolved");
|
|
1023
1022
|
alternateIconNames.add(resolved);
|
|
@@ -1121,11 +1120,11 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
|
|
|
1121
1120
|
return `${base.startsWith("/") ? "/" : ""}${segments.join("/")}`;
|
|
1122
1121
|
};
|
|
1123
1122
|
const project = Object.values(objects).find(
|
|
1124
|
-
(object) =>
|
|
1123
|
+
(object) => isRecord(object) && object.isa === "PBXProject"
|
|
1125
1124
|
);
|
|
1126
1125
|
const projectDir = join(
|
|
1127
1126
|
pbxprojPath.replace(/(?:^|\/)[^/]+\.xcodeproj\/project\.pbxproj$/, ""),
|
|
1128
|
-
|
|
1127
|
+
isRecord(project) && typeof project.projectDirPath === "string" ? project.projectDirPath : ""
|
|
1129
1128
|
);
|
|
1130
1129
|
const paths = Object.keys(files);
|
|
1131
1130
|
visitXcodeTargetMembers(
|