peachsim 0.1.1635 → 0.1.1641

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.
Files changed (142) hide show
  1. package/README.md +10 -1
  2. package/cli/app-config.ts +14 -5
  3. package/cli/app-stubs.ts +96 -22
  4. package/cli/bridge-flow-runner.ts +2 -2
  5. package/cli/cloud-client.ts +60 -40
  6. package/cli/cloud-session.ts +16 -0
  7. package/cli/commands/assert.ts +17 -4
  8. package/cli/commands/box.ts +33 -19
  9. package/cli/commands/doctor.ts +37 -20
  10. package/cli/commands/flow.ts +1 -1
  11. package/cli/commands/inspect/actions.ts +3 -2
  12. package/cli/commands/inspect/core.ts +0 -8
  13. package/cli/commands/inspect/shared.ts +9 -4
  14. package/cli/commands/inspect.ts +65 -61
  15. package/cli/commands/platform.ts +2 -1
  16. package/cli/commands/preview.ts +1 -1
  17. package/cli/commands/record.ts +154 -68
  18. package/cli/commands/swift.ts +18 -4
  19. package/cli/commands/three-mode.ts +4 -38
  20. package/cli/commands/upload.ts +55 -49
  21. package/cli/drivers/playwright-sim-host.ts +65 -42
  22. package/cli/flow-live-status.ts +0 -2
  23. package/cli/main.ts +2 -2
  24. package/cli/outbound-endpoints.ts +7 -5
  25. package/cli/pause-aware-timeout.ts +4 -0
  26. package/cli/ws-bridge.ts +19 -16
  27. package/detox/attempt-events.cjs +99 -6
  28. package/detox/attempt-events.d.cts +7 -0
  29. package/detox/expectations.ts +7 -3
  30. package/detox/index.ts +259 -139
  31. package/detox/jest-environment.cjs +5 -1
  32. package/detox/motion-change.cjs +170 -21
  33. package/detox/motion-change.d.cts +32 -0
  34. package/detox/navigation-lifecycle.ts +35 -3
  35. package/dist-lib/agent-daemon-client.cjs +1 -1
  36. package/dist-lib/agent-events.cjs +1 -1
  37. package/dist-lib/attached-projects.cjs +1 -1
  38. package/dist-lib/auth/shared-session.cjs +1 -1
  39. package/dist-lib/backend-origin.cjs +17 -7
  40. package/dist-lib/beta.cjs +1 -1
  41. package/dist-lib/beta.mjs +1 -1
  42. package/dist-lib/bridge-constants.cjs +1 -1
  43. package/dist-lib/bridge-contract-input.cjs +1 -1
  44. package/dist-lib/bridge-contract-input.mjs +1 -1
  45. package/dist-lib/bridge-contract.cjs +1 -1
  46. package/dist-lib/bridge-contract.mjs +1 -1
  47. package/dist-lib/bundle-channel.cjs +5014 -2268
  48. package/dist-lib/capture-contract.cjs +1 -1
  49. package/dist-lib/capture-contract.mjs +1 -1
  50. package/dist-lib/cloud-contract.cjs +1 -1
  51. package/dist-lib/cloud-contract.mjs +1 -1
  52. package/dist-lib/cloud-test-args.cjs +1 -1
  53. package/dist-lib/cloud-test-args.mjs +1 -1
  54. package/dist-lib/cloud.cjs +1 -1
  55. package/dist-lib/cloud.mjs +1 -1
  56. package/dist-lib/config.cjs +1 -1
  57. package/dist-lib/config.mjs +1 -1
  58. package/dist-lib/detox/index.cjs +1036 -166
  59. package/dist-lib/detox/jest-environment.cjs +5 -1
  60. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  61. package/dist-lib/expo-swift-bundle.cjs +4613 -1963
  62. package/dist-lib/expo-swift-metadata.cjs +9 -7
  63. package/dist-lib/expo-swift-metadata.mjs +9 -7
  64. package/dist-lib/home-paths.cjs +1 -1
  65. package/dist-lib/host/bridge-host.cjs +58072 -16400
  66. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  67. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  68. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  69. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  70. package/dist-lib/host/websocket-proxy.cjs +1 -1
  71. package/dist-lib/index.cjs +2790 -143
  72. package/dist-lib/jump-to-source-babel.cjs +1 -1
  73. package/dist-lib/jump-to-source-native.cjs +1 -1
  74. package/dist-lib/kotlin-host.cjs +1 -1
  75. package/dist-lib/menu.cjs +1 -1
  76. package/dist-lib/menu.mjs +1 -1
  77. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  78. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  79. package/dist-lib/metro-production-bundle.cjs +1 -1
  80. package/dist-lib/metro-production-bundle.mjs +1 -1
  81. package/dist-lib/metro.cjs +2579 -95
  82. package/dist-lib/native-app-identity-project.cjs +243 -53
  83. package/dist-lib/native-app-identity-project.mjs +243 -53
  84. package/dist-lib/native-app-identity.cjs +29 -30
  85. package/dist-lib/native-app-identity.mjs +29 -30
  86. package/dist-lib/native-firebase-metadata.cjs +1 -1
  87. package/dist-lib/native-firebase-metadata.mjs +1 -1
  88. package/dist-lib/plist.cjs +1 -1
  89. package/dist-lib/plist.mjs +1 -1
  90. package/dist-lib/profiles.cjs +1 -1
  91. package/dist-lib/public-brand.cjs +1 -1
  92. package/dist-lib/react-native-host-modules.cjs +2 -2
  93. package/dist-lib/react-native-host-modules.mjs +2 -2
  94. package/dist-lib/scripts/dev-server-scanner.cjs +8 -6
  95. package/dist-lib/sdk.cjs +4 -3
  96. package/dist-lib/sdk.mjs +4 -3
  97. package/dist-lib/skills.cjs +66475 -23097
  98. package/dist-lib/swift-compile.cjs +452 -260
  99. package/dist-lib/swift-compile.mjs +451 -252
  100. package/dist-lib/swift-package.cjs +1 -1
  101. package/dist-lib/swift-package.mjs +1 -1
  102. package/dist-lib/swift-submit.cjs +14 -7
  103. package/dist-lib/swift-submit.mjs +14 -7
  104. package/dist-lib/swift-toolchain.cjs +316 -41
  105. package/dist-lib/swift.cjs +1 -1
  106. package/dist-lib/vite-swift.cjs +8188 -5636
  107. package/dist-lib/vite.cjs +2857 -12
  108. package/dist-lib/worklet-executable.cjs +14 -2
  109. package/dist-lib/worklet-executable.mjs +14 -2
  110. package/package.json +1 -1
  111. package/src/backend-origin.ts +21 -6
  112. package/src/expo-swift-host.ts +5 -2
  113. package/src/expoKotlinContract.ts +4 -7
  114. package/src/expoSwiftContract.ts +4 -6
  115. package/src/host/staged-host-files.ts +9 -0
  116. package/src/native-app-identity-project.ts +1 -4
  117. package/src/native-app-identity.ts +1 -4
  118. package/src/nativeAppIconContract.ts +1 -4
  119. package/src/output-lock-stdio.ts +36 -0
  120. package/src/react-native-bridge-modules.ts +106 -78
  121. package/src/react-native-host-modules.ts +4 -1
  122. package/src/settings-bundle.ts +1 -4
  123. package/src/swift-compile.ts +224 -139
  124. package/src/swift-distribution.lock.json +23 -12
  125. package/src/swift-distribution.ts +103 -4
  126. package/src/swift-host.ts +95 -30
  127. package/src/swift-icu.ts +16 -10
  128. package/src/swift-objc-compile.ts +547 -0
  129. package/src/swift-objc-metadata.ts +204 -0
  130. package/src/swift-objc-sdk.ts +883 -19
  131. package/src/swift-objc-standin.ts +126 -14
  132. package/src/swift-package-manifest.ts +42 -1
  133. package/src/swift-packages.ts +35 -21
  134. package/src/swift-root-lock.ts +153 -0
  135. package/src/swift-standin-emit.ts +40 -7
  136. package/src/swift-standins.ts +404 -138
  137. package/src/swift-submit.ts +18 -7
  138. package/src/swift-toolchain.ts +378 -46
  139. package/src/swiftContract.ts +12 -0
  140. package/src/worker-system-chunks.ts +11 -12
  141. package/src/worklet-executable.ts +19 -1
  142. package/src/xcode-project.ts +280 -33
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1641 | (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 __create = Object.create;
@@ -1578,10 +1578,12 @@ function androidMergedResourceValuesDirectory(manifestFile) {
1578
1578
  return `${intermediates}incremental/${variant}/merge${taskVariant}Resources/merged.dir`;
1579
1579
  }
1580
1580
 
1581
- // src/nativeAppIconContract.ts
1581
+ // src/is-record.ts
1582
1582
  function isRecord(value) {
1583
1583
  return typeof value === "object" && value !== null && !Array.isArray(value);
1584
1584
  }
1585
+
1586
+ // src/nativeAppIconContract.ts
1585
1587
  function resolveNativeAppIconArtwork(resources, readText, resourceUri, icons, primaryName, alternateNames, resolveReference) {
1586
1588
  const members = new Set(resources);
1587
1589
  const dictionary = isRecord(icons) ? icons : {};
@@ -1835,21 +1837,18 @@ function visitXcodeTargetMembers(objects, targetId, resolvePath, filesUnder, joi
1835
1837
  }
1836
1838
 
1837
1839
  // src/native-app-identity.ts
1838
- function isRecord2(value) {
1839
- return typeof value === "object" && value !== null && !Array.isArray(value);
1840
- }
1841
1840
  function nonEmptyString(value) {
1842
1841
  return typeof value === "string" && value.length > 0 ? value : null;
1843
1842
  }
1844
1843
  function readGoogleSignInConfiguration(plist3, resources) {
1845
1844
  const clientIds = {};
1846
1845
  for (const [file, value] of Object.entries(resources)) {
1847
- if (isRecord2(value) && typeof value.CLIENT_ID === "string")
1846
+ if (isRecord(value) && typeof value.CLIENT_ID === "string")
1848
1847
  clientIds[file.split("/").pop()?.replace(/\.plist$/, "") ?? file] = value.CLIENT_ID;
1849
1848
  }
1850
1849
  const urlSchemes = [];
1851
1850
  for (const entry of Array.isArray(plist3.CFBundleURLTypes) ? plist3.CFBundleURLTypes : []) {
1852
- if (!isRecord2(entry) || !Array.isArray(entry.CFBundleURLSchemes)) continue;
1851
+ if (!isRecord(entry) || !Array.isArray(entry.CFBundleURLSchemes)) continue;
1853
1852
  for (const scheme of entry.CFBundleURLSchemes)
1854
1853
  if (typeof scheme === "string") urlSchemes.push(scheme);
1855
1854
  }
@@ -1957,14 +1956,14 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
1957
1956
  let objects = {};
1958
1957
  try {
1959
1958
  const parsed = parseOpenStepPlist(pbxproj);
1960
- if (isRecord2(parsed)) {
1961
- objects = isRecord2(parsed.objects) ? parsed.objects : parsed;
1959
+ if (isRecord(parsed)) {
1960
+ objects = isRecord(parsed.objects) ? parsed.objects : parsed;
1962
1961
  }
1963
1962
  } catch {
1964
1963
  }
1965
1964
  const targets = [];
1966
1965
  for (const [id, obj] of Object.entries(objects)) {
1967
- if (isRecord2(obj) && obj.isa === "PBXNativeTarget" && typeof obj.name === "string") {
1966
+ if (isRecord(obj) && obj.isa === "PBXNativeTarget" && typeof obj.name === "string") {
1968
1967
  targets.push({
1969
1968
  id,
1970
1969
  name: obj.name,
@@ -2010,13 +2009,13 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
2010
2009
  PRODUCT_NAME: targetName
2011
2010
  };
2012
2011
  for (const obj of Object.values(objects)) {
2013
- if (isRecord2(obj) && obj.isa === "PBXProject" && typeof obj.buildConfigurationList === "string") {
2012
+ if (isRecord(obj) && obj.isa === "PBXProject" && typeof obj.buildConfigurationList === "string") {
2014
2013
  const listObj = objects[obj.buildConfigurationList];
2015
- if (isRecord2(listObj) && Array.isArray(listObj.buildConfigurations)) {
2014
+ if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
2016
2015
  for (const configId of listObj.buildConfigurations) {
2017
2016
  if (typeof configId === "string") {
2018
2017
  const configObj = objects[configId];
2019
- if (isRecord2(configObj) && configObj.name === "Release" && isRecord2(configObj.buildSettings)) {
2018
+ if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
2020
2019
  for (const [k, v] of Object.entries(configObj.buildSettings)) {
2021
2020
  if (typeof v === "string") settings[k] = v;
2022
2021
  }
@@ -2028,11 +2027,11 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
2028
2027
  }
2029
2028
  if (selectedTarget?.buildConfigurationList) {
2030
2029
  const listObj = objects[selectedTarget.buildConfigurationList];
2031
- if (isRecord2(listObj) && Array.isArray(listObj.buildConfigurations)) {
2030
+ if (isRecord(listObj) && Array.isArray(listObj.buildConfigurations)) {
2032
2031
  for (const configId of listObj.buildConfigurations) {
2033
2032
  if (typeof configId === "string") {
2034
2033
  const configObj = objects[configId];
2035
- if (isRecord2(configObj) && configObj.name === "Release" && isRecord2(configObj.buildSettings)) {
2034
+ if (isRecord(configObj) && configObj.name === "Release" && isRecord(configObj.buildSettings)) {
2036
2035
  for (const [k, v] of Object.entries(configObj.buildSettings)) {
2037
2036
  if (typeof v === "string") settings[k] = v;
2038
2037
  }
@@ -2083,7 +2082,7 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
2083
2082
  if (!bundleName) return null;
2084
2083
  const applicationName = identityFieldFrom(settings, plistString(plist3, "CFBundleDisplayName"), void 0) ?? bundleName;
2085
2084
  const dictionary = parseInfoPlist(plist3);
2086
- if (!isRecord2(dictionary)) throw new Error("native app Info.plist is not a dictionary");
2085
+ if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
2087
2086
  const declaredDisplayName = dictionary.CFBundleDisplayName;
2088
2087
  const applicationDisplayName = typeof declaredDisplayName === "string" ? resolveBuildSetting(declaredDisplayName, settings) : void 0;
2089
2088
  if (applicationDisplayName === null)
@@ -2096,9 +2095,9 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
2096
2095
  if (dtPlatformVersion === null)
2097
2096
  throw new Error("native app Info.plist DTPlatformVersion is unresolved");
2098
2097
  const icons = dictionary.CFBundleIcons;
2099
- const alternates = isRecord2(icons) ? icons.CFBundleAlternateIcons : void 0;
2098
+ const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
2100
2099
  const alternateIconNames = /* @__PURE__ */ new Set();
2101
- for (const name of isRecord2(alternates) ? Object.keys(alternates) : []) {
2100
+ for (const name of isRecord(alternates) ? Object.keys(alternates) : []) {
2102
2101
  const resolved = resolveBuildSetting(name, settings);
2103
2102
  if (resolved === null) throw new Error("native alternate icon name is unresolved");
2104
2103
  alternateIconNames.add(resolved);
@@ -2202,11 +2201,11 @@ function nativeAppIdentityFromIos(files, parseInfoPlist, iosTarget, resourceUri)
2202
2201
  return `${base.startsWith("/") ? "/" : ""}${segments.join("/")}`;
2203
2202
  };
2204
2203
  const project = Object.values(objects).find(
2205
- (object) => isRecord2(object) && object.isa === "PBXProject"
2204
+ (object) => isRecord(object) && object.isa === "PBXProject"
2206
2205
  );
2207
2206
  const projectDir = join(
2208
2207
  pbxprojPath.replace(/(?:^|\/)[^/]+\.xcodeproj\/project\.pbxproj$/, ""),
2209
- isRecord2(project) && typeof project.projectDirPath === "string" ? project.projectDirPath : ""
2208
+ isRecord(project) && typeof project.projectDirPath === "string" ? project.projectDirPath : ""
2210
2209
  );
2211
2210
  const paths = Object.keys(files);
2212
2211
  visitXcodeTargetMembers(
@@ -2319,6 +2318,8 @@ function parsePlistSource(source) {
2319
2318
  }
2320
2319
 
2321
2320
  // src/xcode-project.ts
2321
+ var import_node_child_process = require("node:child_process");
2322
+ var import_node_crypto = require("node:crypto");
2322
2323
  var import_node_fs = __toESM(require("node:fs"), 1);
2323
2324
  var import_node_path2 = __toESM(require("node:path"), 1);
2324
2325
  var import_plist2 = __toESM(require_plist(), 1);
@@ -2831,11 +2832,14 @@ function targetSettings(ref, configuration, builtins, options = {}) {
2831
2832
  if (!config) return [];
2832
2833
  const name = str(config.name) ?? configuration;
2833
2834
  const base = str(config.baseConfigurationReference);
2835
+ const anchor = str(config.baseConfigurationReferenceAnchor);
2836
+ const relative = str(config.baseConfigurationReferenceRelativePath);
2834
2837
  const own = isDict(config.buildSettings) ? config.buildSettings : {};
2835
- const baseFile = base ? project.resolvePath(base) : null;
2836
- if (options.requireSources !== false && base && (!baseFile || !import_node_fs.default.existsSync(baseFile)))
2838
+ const directory = anchor ? project.resolvePath(anchor) : null;
2839
+ const baseFile = base ? project.resolvePath(base) : directory && relative ? import_node_path2.default.resolve(directory, relative) : null;
2840
+ if (options.requireSources !== false && (base || anchor || relative) && (!baseFile || !import_node_fs.default.existsSync(baseFile)))
2837
2841
  throw new Error(
2838
- `Unable to open base configuration reference file '${baseFile ?? base}'`
2842
+ `Unable to open base configuration reference file '${baseFile ?? base ?? relative ?? anchor}'`
2839
2843
  );
2840
2844
  const read = [];
2841
2845
  const fromFile = baseFile ? readXcconfig(baseFile, read) : {};
@@ -2926,33 +2930,131 @@ function expand(value, lookup) {
2926
2930
  }
2927
2931
  );
2928
2932
  }
2929
- function targetMembers(ref, settings, options = {}) {
2933
+ var preparedSourcePhases = /* @__PURE__ */ new Map();
2934
+ function targetMembers(ref, settings, options, settingKeys, projectInputs) {
2930
2935
  const { project, target, id: targetId } = ref;
2931
2936
  const targetName = str(target.name) ?? targetId;
2932
2937
  const sources = /* @__PURE__ */ new Set();
2933
2938
  const allSources = /* @__PURE__ */ new Set();
2934
2939
  const resources = /* @__PURE__ */ new Set();
2935
2940
  const scriptForOutput = /* @__PURE__ */ new Map();
2936
- const noteScriptOutput = (raw, script) => {
2937
- const expanded = expand(raw, settings);
2938
- if (!expanded.endsWith(".swift")) return;
2939
- const absolute = import_node_path2.default.isAbsolute(expanded) ? import_node_path2.default.normalize(expanded) : import_node_path2.default.resolve(project.projectDir, expanded);
2940
- if (!scriptForOutput.has(absolute)) scriptForOutput.set(absolute, script);
2941
- };
2942
2941
  for (const phaseId of list(target.buildPhases)) {
2943
2942
  const phase = project.object(phaseId);
2944
2943
  if (phase?.isa !== "PBXShellScriptBuildPhase") continue;
2945
2944
  const script = str(phase.name) ?? phaseId;
2946
- for (const raw of list(phase.outputPaths)) noteScriptOutput(raw, script);
2947
- for (const listPath of list(phase.outputFileListPaths)) {
2948
- const expandedList = expand(listPath, settings);
2949
- const absoluteList = import_node_path2.default.isAbsolute(expandedList) ? expandedList : import_node_path2.default.resolve(project.projectDir, expandedList);
2950
- if (!import_node_fs.default.existsSync(absoluteList)) continue;
2951
- for (const line of import_node_fs.default.readFileSync(absoluteList, "utf8").split("\n")) {
2952
- const trimmed = line.trim();
2953
- if (trimmed === "" || trimmed.startsWith("#")) continue;
2954
- noteScriptOutput(trimmed, script);
2945
+ const absolute = (raw) => import_node_path2.default.resolve(project.projectDir, expand(raw, settings));
2946
+ const inputs = list(phase.inputPaths).map(absolute);
2947
+ const outputs = list(phase.outputPaths).map(absolute);
2948
+ const fileLists = /* @__PURE__ */ new Map();
2949
+ for (const kind of ["INPUT", "OUTPUT"]) {
2950
+ const lists = list(
2951
+ kind === "INPUT" ? phase.inputFileListPaths : phase.outputFileListPaths
2952
+ ).map((raw) => {
2953
+ const file = absolute(raw);
2954
+ if (!import_node_fs.default.existsSync(file)) {
2955
+ return { file, entries: [] };
2956
+ }
2957
+ const entries = import_node_fs.default.readFileSync(file, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#")).map(absolute);
2958
+ return { file, entries };
2959
+ });
2960
+ fileLists.set(kind, lists);
2961
+ }
2962
+ const allOutputs = [
2963
+ ...outputs,
2964
+ ...fileLists.get("OUTPUT").flatMap((item) => item.entries)
2965
+ ];
2966
+ for (const output of allOutputs)
2967
+ if (output.endsWith(".swift") && !scriptForOutput.has(output))
2968
+ scriptForOutput.set(output, script);
2969
+ const inputFiles = [
2970
+ ...inputs,
2971
+ ...fileLists.get("INPUT").flatMap((item) => [item.file, ...item.entries]),
2972
+ ...fileLists.get("OUTPUT").map((item) => item.file)
2973
+ ];
2974
+ if (allOutputs.some((file) => file.endsWith(".swift"))) {
2975
+ for (const file of inputFiles) if (import_node_fs.default.existsSync(file)) projectInputs.add(file);
2976
+ }
2977
+ if (options.prepareGeneratedSources && options.requireSources !== false && allOutputs.some((file) => file.endsWith(".swift"))) {
2978
+ const phaseDir = import_node_path2.default.join(settings("TARGET_TEMP_DIR"), `Script-${phaseId}`);
2979
+ for (const lists of fileLists.values())
2980
+ for (const { file } of lists)
2981
+ if (!import_node_fs.default.existsSync(file))
2982
+ throw new Error(
2983
+ `${targetName}: Run Script "${script}" missing file list ${file}`
2984
+ );
2985
+ const env = {
2986
+ ...process.env,
2987
+ ...Object.fromEntries(
2988
+ [...settingKeys].filter((key2) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(key2)).map((key2) => [key2, settings(key2)])
2989
+ )
2990
+ };
2991
+ const declared = { INPUT: inputs, OUTPUT: outputs };
2992
+ for (const kind of ["INPUT", "OUTPUT"]) {
2993
+ env[`SCRIPT_${kind}_FILE_COUNT`] = String(declared[kind].length);
2994
+ declared[kind].forEach((file, index) => {
2995
+ env[`SCRIPT_${kind}_FILE_${index}`] = file;
2996
+ });
2997
+ const lists = fileLists.get(kind);
2998
+ env[`SCRIPT_${kind}_FILE_LIST_COUNT`] = String(lists.length);
2999
+ lists.forEach((_item, index) => {
3000
+ env[`SCRIPT_${kind}_FILE_LIST_${index}`] = import_node_path2.default.join(
3001
+ phaseDir,
3002
+ `${kind}-${index}.xcfilelist`
3003
+ );
3004
+ });
3005
+ }
3006
+ const signature = (0, import_node_crypto.createHash)("sha256").update(
3007
+ JSON.stringify([phase, [...settingKeys].map((key2) => [key2, settings(key2)])])
3008
+ );
3009
+ for (const file of inputFiles) {
3010
+ signature.update(file);
3011
+ if (import_node_fs.default.existsSync(file)) {
3012
+ const stat = import_node_fs.default.statSync(file);
3013
+ signature.update(`${stat.mtimeMs}:${stat.ctimeMs}:${stat.size}`);
3014
+ } else signature.update("missing");
3015
+ }
3016
+ const stamp = signature.digest("hex");
3017
+ const key = `${project.projectFile}:${targetId}:${phaseId}:${settings("CONFIGURATION")}`;
3018
+ if (preparedSourcePhases.get(key) === stamp && allOutputs.every((file) => import_node_fs.default.existsSync(file)))
3019
+ continue;
3020
+ import_node_fs.default.mkdirSync(phaseDir, { recursive: true });
3021
+ import_node_fs.default.mkdirSync(settings("BUILT_PRODUCTS_DIR"), { recursive: true });
3022
+ import_node_fs.default.mkdirSync(settings("DERIVED_FILE_DIR"), { recursive: true });
3023
+ for (const [kind, lists] of fileLists)
3024
+ lists.forEach((item, index) => {
3025
+ import_node_fs.default.writeFileSync(
3026
+ env[`SCRIPT_${kind}_FILE_LIST_${index}`],
3027
+ `${item.entries.join("\n")}
3028
+ `
3029
+ );
3030
+ });
3031
+ try {
3032
+ (0, import_node_child_process.execFileSync)(
3033
+ str(phase.shellPath) ?? "/bin/sh",
3034
+ ["-c", str(phase.shellScript) ?? ""],
3035
+ {
3036
+ cwd: project.projectDir,
3037
+ env,
3038
+ stdio: ["ignore", "pipe", "pipe"],
3039
+ timeout: 12e4
3040
+ }
3041
+ );
3042
+ } catch (error) {
3043
+ const output = error instanceof Error ? `${error.message}
3044
+ ${"stdout" in error ? String(error.stdout) : ""}${"stderr" in error ? String(error.stderr) : ""}` : String(error);
3045
+ throw new Error(
3046
+ `${targetName}: Run Script "${script}" failed preparing generated Swift sources:
3047
+ ${output}`
3048
+ );
2955
3049
  }
3050
+ const missing = allOutputs.filter(
3051
+ (file) => file.endsWith(".swift") && !import_node_fs.default.existsSync(file)
3052
+ );
3053
+ if (missing.length > 0)
3054
+ throw new Error(
3055
+ `${targetName}: Run Script "${script}" did not produce ${missing.join(", ")}`
3056
+ );
3057
+ preparedSourcePhases.set(key, stamp);
2956
3058
  }
2957
3059
  }
2958
3060
  visitXcodeTargetMembers(
@@ -3142,22 +3244,95 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3142
3244
  SRCROOT: ref.project.projectDir,
3143
3245
  SOURCE_ROOT: ref.project.projectDir,
3144
3246
  PROJECT_DIR: ref.project.projectDir,
3247
+ SYMROOT: import_node_path2.default.join(ref.project.projectDir, ".build/peach-xcode/Build/Products"),
3248
+ BUILD_DIR: "$(SYMROOT)",
3249
+ OBJROOT: import_node_path2.default.join(
3250
+ ref.project.projectDir,
3251
+ ".build/peach-xcode/Build/Intermediates.noindex"
3252
+ ),
3253
+ CONFIGURATION_BUILD_DIR: "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)",
3254
+ BUILT_PRODUCTS_DIR: "$(CONFIGURATION_BUILD_DIR)",
3255
+ TARGET_BUILD_DIR: "$(CONFIGURATION_BUILD_DIR)",
3256
+ PROJECT_TEMP_DIR: "$(OBJROOT)/$(PROJECT_NAME).build",
3257
+ CONFIGURATION_TEMP_DIR: "$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)",
3258
+ TARGET_TEMP_DIR: "$(CONFIGURATION_TEMP_DIR)/$(TARGET_NAME).build",
3259
+ DERIVED_FILE_DIR: "$(TARGET_TEMP_DIR)/DerivedSources",
3260
+ DERIVED_FILES_DIR: "$(DERIVED_FILE_DIR)",
3261
+ PLATFORM_NAME: "iphonesimulator",
3262
+ EFFECTIVE_PLATFORM_NAME: "-iphonesimulator",
3263
+ CURRENT_ARCH: "arm64",
3264
+ ARCHS: "arm64",
3265
+ ACTION: "build",
3145
3266
  DEVELOPMENT_LANGUAGE: str(ref.project.project.developmentRegion) ?? "en"
3146
3267
  },
3147
3268
  options
3148
3269
  );
3149
3270
  for (const file of read) xcconfigs.add(file);
3150
3271
  const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
3272
+ const members = targetMembers(ref, settings2, options, keys, xcconfigs);
3273
+ const implementations = members.allSources.filter(
3274
+ (file) => /\.(c|cc|cpp|cxx|m|mm)$/.test(file)
3275
+ );
3276
+ const absolute = (file) => import_node_path2.default.resolve(ref.project.projectDir, file);
3277
+ const fileFlags = {};
3278
+ for (const phaseId of list(ref.target.buildPhases)) {
3279
+ const phase = ref.project.object(phaseId);
3280
+ if (phase?.isa !== "PBXSourcesBuildPhase") continue;
3281
+ for (const id of list(phase.files)) {
3282
+ const file = ref.project.object(id);
3283
+ const resolved = ref.project.resolvePath(str(file?.fileRef) ?? "");
3284
+ if (resolved && implementations.includes(resolved))
3285
+ fileFlags[resolved] = settingList(
3286
+ expand(
3287
+ str(isDict(file?.settings) ? file.settings.COMPILER_FLAGS : void 0) ?? "",
3288
+ settings2
3289
+ )
3290
+ );
3291
+ }
3292
+ }
3151
3293
  return {
3152
3294
  settings: settings2,
3153
3295
  keys,
3154
3296
  module: {
3155
3297
  name,
3156
3298
  moduleName: applyOperator(settings2("PRODUCT_MODULE_NAME"), "c99extidentifier"),
3157
- ...targetMembers(ref, settings2, options),
3299
+ ...members,
3158
3300
  languageMode: swiftVersion >= 6 ? 6 : 5,
3159
3301
  mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor",
3160
- defines: compilationConditions(settings2)
3302
+ defines: compilationConditions(settings2),
3303
+ iosDeploymentTarget: settings2("IPHONEOS_DEPLOYMENT_TARGET") || null,
3304
+ ...implementations.some((file) => /\.mm?$/.test(file)) ? {
3305
+ objc: {
3306
+ headers: Object.keys(ref.project.objects).flatMap((id) => {
3307
+ const file = ref.project.resolvePath(id);
3308
+ return file && /\.(h|hh|hpp|hxx|pch)$/.test(file) && import_node_fs.default.existsSync(file) ? [file] : [];
3309
+ }),
3310
+ prefixHeader: settings2("GCC_PREFIX_HEADER") ? absolute(settings2("GCC_PREFIX_HEADER")) : null,
3311
+ bridgingHeader: settings2("SWIFT_OBJC_BRIDGING_HEADER") ? absolute(settings2("SWIFT_OBJC_BRIDGING_HEADER")) : null,
3312
+ headerSearchPaths: [
3313
+ ...settingList(settings2("HEADER_SEARCH_PATHS")),
3314
+ ...settingList(settings2("USER_HEADER_SEARCH_PATHS"))
3315
+ ].map(absolute),
3316
+ frameworkSearchPaths: settingList(settings2("FRAMEWORK_SEARCH_PATHS")).map(
3317
+ absolute
3318
+ ),
3319
+ flags: [
3320
+ ...settings2("CLANG_ENABLE_OBJC_ARC") === "YES" ? ["-fobjc-arc"] : [],
3321
+ ...settings2("CLANG_ENABLE_OBJC_WEAK") === "YES" ? ["-fobjc-weak"] : [],
3322
+ ...settings2("CLANG_ENABLE_MODULES") === "YES" ? ["-fmodules"] : [],
3323
+ ...settings2("GCC_C_LANGUAGE_STANDARD") ? [`-std=${settings2("GCC_C_LANGUAGE_STANDARD")}`] : [],
3324
+ ...settingList(settings2("GCC_PREPROCESSOR_DEFINITIONS")).map(
3325
+ (value) => `-D${value}`
3326
+ ),
3327
+ ...settingList(settings2("OTHER_CFLAGS"))
3328
+ ],
3329
+ cxxFlags: [
3330
+ ...settings2("CLANG_CXX_LANGUAGE_STANDARD") ? [`-std=${settings2("CLANG_CXX_LANGUAGE_STANDARD")}`] : [],
3331
+ ...settingList(settings2("OTHER_CPLUSPLUSFLAGS"))
3332
+ ],
3333
+ fileFlags
3334
+ }
3335
+ } : {}
3161
3336
  }
3162
3337
  };
3163
3338
  };
@@ -3206,6 +3381,23 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3206
3381
  ...projects.flatMap(
3207
3382
  (project) => Object.entries(project.objects).flatMap(([id, entry]) => {
3208
3383
  if (!isDict(entry)) return [];
3384
+ if (entry.isa === "PBXFileSystemSynchronizedRootGroup") {
3385
+ const folder = project.resolvePath(id);
3386
+ const pending = folder ? [folder] : [];
3387
+ const packages = [];
3388
+ while (pending.length > 0) {
3389
+ const dir = pending.pop();
3390
+ if (import_node_fs.default.existsSync(import_node_path2.default.join(dir, "Package.swift"))) {
3391
+ packages.push(dir);
3392
+ continue;
3393
+ }
3394
+ if (!isDirectory(dir)) continue;
3395
+ for (const child of import_node_fs.default.readdirSync(dir, { withFileTypes: true }))
3396
+ if (child.isDirectory() && !child.name.startsWith("."))
3397
+ pending.push(import_node_path2.default.join(dir, child.name));
3398
+ }
3399
+ return packages;
3400
+ }
3209
3401
  const candidate = entry.isa === "XCLocalSwiftPackageReference" ? import_node_path2.default.resolve(project.projectDir, str(entry.relativePath) ?? "") : entry.isa === "PBXFileReference" ? project.resolvePath(id) : null;
3210
3402
  return candidate && import_node_fs.default.existsSync(import_node_path2.default.join(candidate, "Package.swift")) ? [candidate] : [];
3211
3403
  })
@@ -3260,6 +3452,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3260
3452
  "swiftpm",
3261
3453
  "Package.resolved"
3262
3454
  );
3455
+ const packageResolved = import_node_fs.default.existsSync(resolvedFile) ? [import_node_fs.default.realpathSync(resolvedFile)] : [...new Set(localPackageDirs.map((dir) => import_node_path2.default.join(dir, "Package.resolved")))].filter((file) => import_node_fs.default.existsSync(file)).map((file) => import_node_fs.default.realpathSync(file)).sort();
3263
3456
  const used = order.map((ref) => ref.project);
3264
3457
  return {
3265
3458
  ...module2,
@@ -3285,7 +3478,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3285
3478
  ...new Set(localPackageDirs.map((dir) => import_node_fs.default.realpathSync(dir)))
3286
3479
  ].sort(),
3287
3480
  binaryFrameworks: [...binaryFrameworks].map(([name, file]) => ({ name, path: file })).sort((left, right) => left.name.localeCompare(right.name)),
3288
- packageResolved: import_node_fs.default.existsSync(resolvedFile) ? resolvedFile : null,
3481
+ packageResolved,
3289
3482
  appTargets: appTargetNames,
3290
3483
  configuration,
3291
3484
  settings
@@ -3293,15 +3486,12 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3293
3486
  }
3294
3487
 
3295
3488
  // src/native-app-identity-project.ts
3296
- function isRecord3(value) {
3297
- return typeof value === "object" && value !== null && !Array.isArray(value);
3298
- }
3299
3489
  function nonEmptyString2(value) {
3300
3490
  return typeof value === "string" && value.length > 0 ? value : void 0;
3301
3491
  }
3302
3492
  function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSource) {
3303
3493
  const dictionary = parseInfoPlist(app.infoPlist);
3304
- if (!isRecord3(dictionary)) throw new Error("native app Info.plist is not a dictionary");
3494
+ if (!isRecord(dictionary)) throw new Error("native app Info.plist is not a dictionary");
3305
3495
  const settings = app.settings;
3306
3496
  const bundleIdentifier = nonEmptyString2(dictionary.CFBundleIdentifier) ?? nonEmptyString2(settings?.("PRODUCT_BUNDLE_IDENTIFIER"));
3307
3497
  if (!bundleIdentifier) throw new Error("native app has no bundle identifier");
@@ -3318,8 +3508,8 @@ function readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist = parsePlistSo
3318
3508
  const designRequiresCompatibility = dictionary.UIDesignRequiresCompatibility === true;
3319
3509
  const alternateIconNames = /* @__PURE__ */ new Set();
3320
3510
  const icons = dictionary.CFBundleIcons;
3321
- const alternates = isRecord3(icons) ? icons.CFBundleAlternateIcons : void 0;
3322
- if (isRecord3(alternates)) {
3511
+ const alternates = isRecord(icons) ? icons.CFBundleAlternateIcons : void 0;
3512
+ if (isRecord(alternates)) {
3323
3513
  for (const name of Object.keys(alternates)) {
3324
3514
  if (name) alternateIconNames.add(name);
3325
3515
  }
@@ -3551,7 +3741,7 @@ function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
3551
3741
  const installedManifest = JSON.parse(
3552
3742
  import_node_fs2.default.readFileSync(reanimatedManifestPath, "utf8")
3553
3743
  );
3554
- const installedVersion = isRecord3(installedManifest) ? nonEmptyString2(installedManifest.version) : void 0;
3744
+ const installedVersion = isRecord(installedManifest) ? nonEmptyString2(installedManifest.version) : void 0;
3555
3745
  if (!installedVersion) throw new Error("Reanimated package version is malformed");
3556
3746
  if (Number.parseInt(installedVersion, 10) < 4) return identity;
3557
3747
  const defaults = JSON.parse(
@@ -3563,11 +3753,11 @@ function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
3563
3753
  "utf8"
3564
3754
  )
3565
3755
  );
3566
- if (!isRecord3(defaults)) throw new Error("Reanimated static flags are malformed");
3756
+ if (!isRecord(defaults)) throw new Error("Reanimated static flags are malformed");
3567
3757
  const manifest = JSON.parse(import_node_fs2.default.readFileSync(projectManifestPath, "utf8"));
3568
- const reanimated = isRecord3(manifest) ? manifest.reanimated : void 0;
3569
- const overrides = isRecord3(reanimated) ? reanimated.staticFeatureFlags : void 0;
3570
- if (overrides !== void 0 && !isRecord3(overrides)) {
3758
+ const reanimated = isRecord(manifest) ? manifest.reanimated : void 0;
3759
+ const overrides = isRecord(reanimated) ? reanimated.staticFeatureFlags : void 0;
3760
+ if (overrides !== void 0 && !isRecord(overrides)) {
3571
3761
  throw new Error("Reanimated static flag overrides are malformed");
3572
3762
  }
3573
3763
  const flags = {};