@absolutejs/absolute 0.20.0-beta.104 → 0.20.0-beta.105

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 (31) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/changelog.json +22 -0
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  4. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  5. package/dist/cli/{compile-g8vmvr0w.js → compile-hsbs1xf6.js} +2 -2
  6. package/dist/cli/{dev-m4r4zs2k.js → dev-9cp5t2n1.js} +4 -4
  7. package/dist/cli/{expoProject-780thyfd.js → expoProject-zkprmjjz.js} +1 -1
  8. package/dist/cli/{index-d5fr1xp3.js → index-0zcebhm4.js} +59 -1
  9. package/dist/cli/{index-wpfvpsk7.js → index-5skbydh0.js} +1 -1
  10. package/dist/cli/{index-3sdvzrv2.js → index-7fxrgx5q.js} +1 -1
  11. package/dist/cli/{index-67kedtn7.js → index-hrzd7e5x.js} +1 -1
  12. package/dist/cli/{index-27hhdgtg.js → index-mazxtfh4.js} +1 -1
  13. package/dist/cli/{index-qxnptvwn.js → index-q1d4ns4n.js} +100 -9
  14. package/dist/cli/index.js +5 -5
  15. package/dist/cli/{iosNativeWatcher-3k715hq0.js → iosNativeWatcher-t6gv0p1w.js} +2 -2
  16. package/dist/cli/{iosSimulatorController-dr98a0p9.js → iosSimulatorController-5n2a9fxv.js} +2 -2
  17. package/dist/cli/{mobile-njmnd7vc.js → mobile-fbtq3s5x.js} +896 -172
  18. package/dist/cli/{remoteMacProtocol-kqvkp0qd.js → remoteMacProtocol-bbramzh6.js} +2 -2
  19. package/dist/cli/{start-39aqmr5n.js → start-5grq7nfr.js} +3 -3
  20. package/dist/mobile/index.js +1191 -573
  21. package/dist/mobile/index.js.map +8 -7
  22. package/dist/mobile/remoteMacAgentEntry.js +296 -249
  23. package/dist/src/mobile/index.d.ts +1 -0
  24. package/dist/src/mobile/iosRelease.d.ts +31 -7
  25. package/dist/src/mobile/iosReleaseAcceptance.d.ts +63 -0
  26. package/dist/src/mobile/iosTestReport.d.ts +1 -0
  27. package/dist/src/mobile/nativeReleaseReadiness.d.ts +1 -1
  28. package/dist/src/mobile/nativeTestReport.d.ts +15 -0
  29. package/dist/src/mobile/remoteMacProtocol.d.ts +7 -1
  30. package/dist/src/mobile/shellReleaseReadiness.d.ts +1 -1
  31. package/package.json +1 -1
@@ -611,11 +611,11 @@ __export(exports_config, {
611
611
  normalizeAbsoluteMobileConfig: () => normalizeAbsoluteMobileConfig
612
612
  });
613
613
  import { readFileSync as readFileSync2 } from "fs";
614
- import { resolve as resolve7 } from "path";
615
- import { createHash as createHash9, createPublicKey, X509Certificate as X509Certificate2 } from "crypto";
614
+ import { resolve as resolve8 } from "path";
615
+ import { createHash as createHash10, createPublicKey, X509Certificate as X509Certificate2 } from "crypto";
616
616
  var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, UPDATE_NAME_PATTERN, UPDATE_PUBLIC_KEY_PATTERN, ENVIRONMENT_NAME_PATTERN, DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000, DEFAULT_UPDATE_HEALTH_FAILURE_RATE = 0.2, DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS = 20, DEFAULT_UPDATE_ROLLOUT_FAILURE_RATE = 0.05, DEFAULT_UPDATE_ROLLOUT_OBSERVATION_MINUTES = 60, MINUTE_MS, DEFAULT_UPDATE_ROLLOUT_STAGES, MINIMUM_UPDATE_BOOT_TIMEOUT_MS = 5000, MAXIMUM_UPDATE_BOOT_TIMEOUT_MS = 120000, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field2) => {
617
- const root = resolve7(projectRoot);
618
- const path = resolve7(root, value);
617
+ const root = resolve8(projectRoot);
618
+ const path = resolve8(root, value);
619
619
  if (path !== root && !path.startsWith(`${root}/`)) {
620
620
  throw new TypeError(`${field2} must remain inside the project root.`);
621
621
  }
@@ -787,7 +787,7 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
787
787
  expoCodeSigning = {
788
788
  algorithm: "rsa-v1_5-sha256",
789
789
  certificatePem,
790
- certificateSha256: createHash9("sha256").update(certificate.raw).digest("hex"),
790
+ certificateSha256: createHash10("sha256").update(certificate.raw).digest("hex"),
791
791
  keyId
792
792
  };
793
793
  }
@@ -1017,14 +1017,14 @@ __export(exports_associationFiles, {
1017
1017
  verifyAbsoluteMobileAssociationFiles: () => verifyAbsoluteMobileAssociationFiles
1018
1018
  });
1019
1019
  import {
1020
- access as access9,
1021
- mkdir as mkdir8,
1022
- readFile as readFile11,
1020
+ access as access10,
1021
+ mkdir as mkdir9,
1022
+ readFile as readFile12,
1023
1023
  rename as rename9,
1024
- rm as rm8,
1024
+ rm as rm9,
1025
1025
  writeFile as writeFile9
1026
1026
  } from "fs/promises";
1027
- import { resolve as resolve8 } from "path";
1027
+ import { resolve as resolve9 } from "path";
1028
1028
  import { Elysia } from "elysia";
1029
1029
  var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERIFY_TIMEOUT_MS = 1e4, ANDROID_ASSOCIATION_PATH = "/.well-known/assetlinks.json", APPLE_ASSOCIATION_PATH = "/.well-known/apple-app-site-association", missingIdentity = (field2, platform2) => new TypeError(`${field2} is required to publish ${platform2} deep-link association files.`), createAppleDocument = (config, requireAll) => {
1030
1030
  if (!config.platforms.includes("ios"))
@@ -1091,7 +1091,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1091
1091
  }, writeAtomic = async (path, source) => {
1092
1092
  let current;
1093
1093
  try {
1094
- current = await readFile11(path, "utf8");
1094
+ current = await readFile12(path, "utf8");
1095
1095
  } catch (error) {
1096
1096
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
1097
1097
  throw error;
@@ -1103,18 +1103,18 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1103
1103
  await writeFile9(temporary, source, { flag: "wx" });
1104
1104
  await rename9(temporary, path);
1105
1105
  return true;
1106
- }, exists3 = async (path) => {
1106
+ }, exists4 = async (path) => {
1107
1107
  try {
1108
- await access9(path);
1108
+ await access10(path);
1109
1109
  return true;
1110
1110
  } catch {
1111
1111
  return false;
1112
1112
  }
1113
1113
  }, assertOwnedOutput = async (root) => {
1114
- const path = resolve8(root, OWNERSHIP_FILE);
1114
+ const path = resolve9(root, OWNERSHIP_FILE);
1115
1115
  let ownership;
1116
1116
  try {
1117
- ownership = JSON.parse(await readFile11(path, "utf8"));
1117
+ ownership = JSON.parse(await readFile12(path, "utf8"));
1118
1118
  } catch {
1119
1119
  throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
1120
1120
  }
@@ -1122,7 +1122,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1122
1122
  throw new TypeError(`Association output ${root} has an unsupported ownership manifest.`);
1123
1123
  }
1124
1124
  }, publishGeneratedDirectory = async (temporary, root) => {
1125
- const hasCurrent = await exists3(root);
1125
+ const hasCurrent = await exists4(root);
1126
1126
  if (hasCurrent)
1127
1127
  await assertOwnedOutput(root);
1128
1128
  const backup = `${root}.${crypto.randomUUID()}.previous`;
@@ -1136,12 +1136,12 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1136
1136
  throw error;
1137
1137
  }
1138
1138
  if (hasCurrent)
1139
- await rm8(backup, { force: true, recursive: true });
1139
+ await rm9(backup, { force: true, recursive: true });
1140
1140
  }, materializeHost = async (root, host, files) => {
1141
- const directory = resolve8(root, host, ".well-known");
1142
- await mkdir8(directory, { recursive: true });
1141
+ const directory = resolve9(root, host, ".well-known");
1142
+ await mkdir9(directory, { recursive: true });
1143
1143
  return Promise.all(files.map(async ([name, document2]) => {
1144
- const path = resolve8(directory, name);
1144
+ const path = resolve9(directory, name);
1145
1145
  await writeAtomic(path, `${JSON.stringify(document2, null, 2)}
1146
1146
  `);
1147
1147
  return path;
@@ -1164,7 +1164,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1164
1164
  });
1165
1165
  return endpoints;
1166
1166
  }), materializeAbsoluteMobileAssociationFiles = async (config, outputDirectory) => {
1167
- const root = resolve8(outputDirectory);
1167
+ const root = resolve9(outputDirectory);
1168
1168
  const temporary = `${root}.${crypto.randomUUID()}.tmp`;
1169
1169
  const documents = createAbsoluteMobileAssociationDocuments(config, {
1170
1170
  requireAll: true
@@ -1175,16 +1175,16 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1175
1175
  if (documents.apple) {
1176
1176
  files.push(["apple-app-site-association", documents.apple]);
1177
1177
  }
1178
- await mkdir8(temporary, { recursive: true });
1178
+ await mkdir9(temporary, { recursive: true });
1179
1179
  try {
1180
1180
  const temporaryPaths = (await Promise.all(config.deepLinkHosts.map((host) => materializeHost(temporary, host, files)))).flat();
1181
- await writeAtomic(resolve8(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
1181
+ await writeAtomic(resolve9(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
1182
1182
  `);
1183
1183
  await publishGeneratedDirectory(temporary, root);
1184
- const written = temporaryPaths.map((path) => resolve8(root, path.slice(temporary.length + 1)));
1184
+ const written = temporaryPaths.map((path) => resolve9(root, path.slice(temporary.length + 1)));
1185
1185
  return { root, written };
1186
1186
  } catch (error) {
1187
- await rm8(temporary, { force: true, recursive: true });
1187
+ await rm9(temporary, { force: true, recursive: true });
1188
1188
  throw error;
1189
1189
  }
1190
1190
  }, verifyAbsoluteMobileAssociationFiles = async (config, request = globalThis.fetch) => {
@@ -1607,24 +1607,24 @@ __export(exports_materializedBundle, {
1607
1607
  materializeAbsoluteMobileCompatibilityBundle: () => materializeAbsoluteMobileCompatibilityBundle,
1608
1608
  readAbsoluteMobileMaterializedReleases: () => readAbsoluteMobileMaterializedReleases
1609
1609
  });
1610
- import { createHash as createHash11 } from "crypto";
1610
+ import { createHash as createHash12 } from "crypto";
1611
1611
  import {
1612
- access as access10,
1613
- mkdir as mkdir11,
1614
- mkdtemp as mkdtemp7,
1615
- readFile as readFile14,
1612
+ access as access11,
1613
+ mkdir as mkdir12,
1614
+ mkdtemp as mkdtemp8,
1615
+ readFile as readFile15,
1616
1616
  rename as rename11,
1617
- rm as rm10,
1617
+ rm as rm11,
1618
1618
  writeFile as writeFile12
1619
1619
  } from "fs/promises";
1620
- import { dirname as dirname9, join as join12, resolve as resolvePath4 } from "path";
1620
+ import { dirname as dirname10, join as join13, resolve as resolvePath4 } from "path";
1621
1621
  import { pathToFileURL } from "url";
1622
1622
  var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE2 = "artifact.json", BUNDLE_ID_PATTERN, isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), errorHasCode3 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, bundleIdFor = (currentReleaseId, releases) => {
1623
1623
  const identity = JSON.stringify({
1624
1624
  currentReleaseId,
1625
1625
  releases: releases.map(({ releaseId }) => releaseId)
1626
1626
  });
1627
- return `amb_${createHash11("sha256").update(identity).digest("hex")}`;
1627
+ return `amb_${createHash12("sha256").update(identity).digest("hex")}`;
1628
1628
  }, parseBundleIndex = (value) => {
1629
1629
  if (!isRecord8(value) || value.format !== ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT || typeof value.bundleId !== "string" || !BUNDLE_ID_PATTERN.test(value.bundleId) || typeof value.currentReleaseId !== "string" || !Array.isArray(value.releases)) {
1630
1630
  throw new TypeError("Invalid materialized mobile compatibility bundle.");
@@ -1648,29 +1648,29 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1648
1648
  releases
1649
1649
  };
1650
1650
  }, writeRelease = async (root, release) => {
1651
- const directory = join12(root, release.artifact.releaseId);
1652
- const producerPath = join12(directory, release.artifact.producer.module);
1653
- await mkdir11(dirname9(producerPath), { recursive: true });
1651
+ const directory = join13(root, release.artifact.releaseId);
1652
+ const producerPath = join13(directory, release.artifact.producer.module);
1653
+ await mkdir12(dirname10(producerPath), { recursive: true });
1654
1654
  await Promise.all([
1655
- writeFile12(join12(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
1655
+ writeFile12(join13(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
1656
1656
  `),
1657
1657
  writeFile12(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
1658
1658
  ]);
1659
1659
  }, installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
1660
- const destination = join12(bundlesRoot, bundleId);
1660
+ const destination = join13(bundlesRoot, bundleId);
1661
1661
  try {
1662
- await access10(destination);
1662
+ await access11(destination);
1663
1663
  return destination;
1664
1664
  } catch (error) {
1665
1665
  if (!errorHasCode3(error, "ENOENT"))
1666
1666
  throw error;
1667
1667
  }
1668
- const staging = await mkdtemp7(join12(bundlesRoot, ".stage-"));
1668
+ const staging = await mkdtemp8(join13(bundlesRoot, ".stage-"));
1669
1669
  try {
1670
1670
  await Promise.all(releases.map((release) => writeRelease(staging, release)));
1671
1671
  await rename11(staging, destination);
1672
1672
  } catch (error) {
1673
- await rm10(staging, { force: true, recursive: true });
1673
+ await rm11(staging, { force: true, recursive: true });
1674
1674
  if (errorHasCode3(error, "EEXIST") || errorHasCode3(error, "ENOTEMPTY")) {
1675
1675
  return destination;
1676
1676
  }
@@ -1696,15 +1696,15 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1696
1696
  };
1697
1697
  }, loadAbsoluteMobileMaterializedBundle = async (root) => {
1698
1698
  const resolvedRoot = resolvePath4(root);
1699
- const serialized = await readFile14(join12(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
1699
+ const serialized = await readFile15(join13(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
1700
1700
  const parsed = JSON.parse(serialized);
1701
1701
  const index = parseBundleIndex(parsed);
1702
- const bundleRoot = join12(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
1702
+ const bundleRoot = join13(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
1703
1703
  return {
1704
1704
  artifacts: index.releases,
1705
1705
  currentReleaseId: index.currentReleaseId,
1706
1706
  loadProducer: async (artifact) => {
1707
- const modulePath = join12(bundleRoot, artifact.releaseId, artifact.producer.module);
1707
+ const modulePath = join13(bundleRoot, artifact.releaseId, artifact.producer.module);
1708
1708
  await verifyAbsoluteMobileCompatibilityProducer({
1709
1709
  artifact,
1710
1710
  producer: Bun.file(modulePath)
@@ -1730,8 +1730,8 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1730
1730
  return release;
1731
1731
  });
1732
1732
  const root = resolvePath4(input.root);
1733
- const bundlesRoot = join12(root, BUNDLES_DIRECTORY);
1734
- await mkdir11(bundlesRoot, { recursive: true });
1733
+ const bundlesRoot = join13(root, BUNDLES_DIRECTORY);
1734
+ await mkdir12(bundlesRoot, { recursive: true });
1735
1735
  const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
1736
1736
  await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
1737
1737
  const index = {
@@ -1740,8 +1740,8 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1740
1740
  format: ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
1741
1741
  releases: artifacts
1742
1742
  };
1743
- const pointerPath = join12(root, CURRENT_BUNDLE_FILE);
1744
- const temporaryPointerPath = join12(root, `.current-${crypto.randomUUID()}.json`);
1743
+ const pointerPath = join13(root, CURRENT_BUNDLE_FILE);
1744
+ const temporaryPointerPath = join13(root, `.current-${crypto.randomUUID()}.json`);
1745
1745
  await writeFile12(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
1746
1746
  `, { flag: "wx" });
1747
1747
  await rename11(temporaryPointerPath, pointerPath);
@@ -1749,12 +1749,12 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1749
1749
  }, readAbsoluteMobileMaterializedReleases = async (root) => {
1750
1750
  const resolvedRoot = resolvePath4(root);
1751
1751
  try {
1752
- const serialized = await readFile14(join12(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
1752
+ const serialized = await readFile15(join13(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
1753
1753
  const parsed = JSON.parse(serialized);
1754
1754
  const index = parseBundleIndex(parsed);
1755
- const bundleRoot = join12(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
1755
+ const bundleRoot = join13(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
1756
1756
  return Promise.all(index.releases.map(async (artifact) => {
1757
- const producer = Bun.file(join12(bundleRoot, artifact.releaseId, artifact.producer.module));
1757
+ const producer = Bun.file(join13(bundleRoot, artifact.releaseId, artifact.producer.module));
1758
1758
  await verifyAbsoluteMobileCompatibilityProducer({
1759
1759
  artifact,
1760
1760
  producer
@@ -1775,7 +1775,7 @@ var init_materializedBundle = __esm(() => {
1775
1775
 
1776
1776
  // src/mobile/deviceCapabilities.ts
1777
1777
  import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
1778
- import { extname as extname3, join as join13, relative as relative10, resolve as resolve11 } from "path";
1778
+ import { extname as extname3, join as join14, relative as relative11, resolve as resolve12 } from "path";
1779
1779
  import { fileURLToPath } from "url";
1780
1780
  import ts from "typescript";
1781
1781
  var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES, ADAPTERS, SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, providerModulePattern = (provider) => new RegExp(`^@absolutejs/devices-${provider}/[a-z][a-z0-9-]*$`, "u"), providerPackagePattern = (provider) => provider === "capacitor" ? /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u : /^(?:expo-[a-z][a-z0-9-]*|@react-native-[a-z0-9-]+\/[a-z][a-z0-9-]*)@\d+\.\d+\.\d+$/u, providerLabel = (provider) => provider === "capacitor" ? "Capacitor" : "Expo", ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, IOS_PRIVACY_ACCESSED_API_REASONS, IOS_PRIVACY_ACCESSED_APIS, object = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
@@ -1903,7 +1903,7 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
1903
1903
  };
1904
1904
  }, loadAbsoluteDeviceCapabilityProviders = (projectRoot, provider = "capacitor") => {
1905
1905
  const adapter = ADAPTERS[provider];
1906
- let path = join13(resolve11(projectRoot), "node_modules", adapter, "package.json");
1906
+ let path = join14(resolve12(projectRoot), "node_modules", adapter, "package.json");
1907
1907
  try {
1908
1908
  readFileSync3(path, "utf8");
1909
1909
  } catch {
@@ -1958,7 +1958,7 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
1958
1958
  if (missing.includes(spec))
1959
1959
  return false;
1960
1960
  try {
1961
- return readJson(join13(resolve11(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
1961
+ return readJson(join14(resolve12(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
1962
1962
  } catch {
1963
1963
  return true;
1964
1964
  }
@@ -1967,7 +1967,7 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
1967
1967
  if (unmet.length > 0)
1968
1968
  throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
1969
1969
  }, directAbsoluteProjectPackages = (projectRoot) => {
1970
- const manifest = readJson(join13(resolve11(projectRoot), "package.json"));
1970
+ const manifest = readJson(join14(resolve12(projectRoot), "package.json"));
1971
1971
  const packages = new Set;
1972
1972
  for (const field2 of ["dependencies", "devDependencies"]) {
1973
1973
  const dependencies = manifest[field2];
@@ -1977,16 +1977,16 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
1977
1977
  }
1978
1978
  return packages;
1979
1979
  }, discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
1980
- const root = resolve11(projectRoot);
1980
+ const root = resolve12(projectRoot);
1981
1981
  if (!existsSync3(root))
1982
1982
  return [];
1983
1983
  const known = new Set(Object.keys(providers));
1984
1984
  const capabilities = new Set;
1985
1985
  for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
1986
- const portable = relative10(root, resolve11(root, path)).replaceAll("\\", "/");
1986
+ const portable = relative11(root, resolve12(root, path)).replaceAll("\\", "/");
1987
1987
  if (isIgnored(portable))
1988
1988
  continue;
1989
- const source = readFileSync3(resolve11(root, portable), "utf8");
1989
+ const source = readFileSync3(resolve12(root, portable), "utf8");
1990
1990
  for (const name of importedCapabilities(source, portable))
1991
1991
  if (known.has(name))
1992
1992
  capabilities.add(name);
@@ -1996,12 +1996,12 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
1996
1996
  const packageName = spec.slice(0, spec.lastIndexOf("@"));
1997
1997
  return !directPackages.has(packageName);
1998
1998
  }), projectImportsAbsoluteDeviceCapability = (projectRoot, capability) => {
1999
- const root = resolve11(projectRoot);
1999
+ const root = resolve12(projectRoot);
2000
2000
  for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
2001
- const portable = relative10(root, resolve11(root, path)).replaceAll("\\", "/");
2001
+ const portable = relative11(root, resolve12(root, path)).replaceAll("\\", "/");
2002
2002
  if (isIgnored(portable))
2003
2003
  continue;
2004
- const source = readFileSync3(resolve11(root, portable), "utf8");
2004
+ const source = readFileSync3(resolve12(root, portable), "utf8");
2005
2005
  if (importedCapabilities(source, portable).has(capability))
2006
2006
  return true;
2007
2007
  }
@@ -2068,10 +2068,10 @@ var init_deviceCapabilities = __esm(() => {
2068
2068
 
2069
2069
  // src/mobile/nativeAuth.ts
2070
2070
  import { readFileSync as readFileSync4 } from "fs";
2071
- import { join as join14 } from "path";
2071
+ import { join as join15 } from "path";
2072
2072
  var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth", ABSOLUTE_EXPO_AUTH_CORE_VERSION = "0.76.3", ABSOLUTE_EXPO_AUTH_PACKAGE = "@absolutejs/auth-expo", ABSOLUTE_EXPO_AUTH_VERSION = "0.0.6", ABSOLUTE_EXPO_SYNC_CORE_VERSION = "2.31.0", ABSOLUTE_EXPO_SYNC_PACKAGE = "@absolutejs/sync-expo", ABSOLUTE_EXPO_SYNC_VERSION = "0.0.4", ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS", ABSOLUTE_NATIVE_AUTH_SCOPES, ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync", readPackageManifest = (projectRoot) => {
2073
2073
  try {
2074
- return JSON.parse(readFileSync4(join14(projectRoot, "package.json"), "utf8"));
2074
+ return JSON.parse(readFileSync4(join15(projectRoot, "package.json"), "utf8"));
2075
2075
  } catch {
2076
2076
  return;
2077
2077
  }
@@ -2241,7 +2241,7 @@ var init_client = __esm(() => {
2241
2241
 
2242
2242
  // src/mobile/syncSchema.ts
2243
2243
  import { readFileSync as readFileSync5 } from "fs";
2244
- import { dirname as dirname10, join as join15, resolve as resolve12 } from "path";
2244
+ import { dirname as dirname11, join as join16, resolve as resolve13 } from "path";
2245
2245
  var object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), manifestAt = (path) => {
2246
2246
  try {
2247
2247
  const value = JSON.parse(readFileSync5(path, "utf8"));
@@ -2258,13 +2258,13 @@ var object2 = (value) => typeof value === "object" && value !== null && !Array.i
2258
2258
  return;
2259
2259
  return Reflect.get(sync, "localSchema");
2260
2260
  }, packageManifestPath = (projectRoot, packageName) => {
2261
- let directory = resolve12(projectRoot);
2261
+ let directory = resolve13(projectRoot);
2262
2262
  while (true) {
2263
- const candidate = join15(directory, "node_modules", packageName, "package.json");
2263
+ const candidate = join16(directory, "node_modules", packageName, "package.json");
2264
2264
  const manifest = manifestAt(candidate);
2265
2265
  if (manifest && Reflect.get(manifest, "name") === packageName)
2266
2266
  return candidate;
2267
- const parent = dirname10(directory);
2267
+ const parent = dirname11(directory);
2268
2268
  if (parent === directory)
2269
2269
  return;
2270
2270
  directory = parent;
@@ -2491,7 +2491,7 @@ var object2 = (value) => typeof value === "object" && value !== null && !Array.i
2491
2491
  Reflect.get(manifest, "devDependencies"),
2492
2492
  Reflect.get(manifest, "peerDependencies")
2493
2493
  ].flatMap((dependencies) => object2(dependencies) ? Object.keys(dependencies) : []).filter((name, index, names) => names.indexOf(name) === index).sort(), discoverAbsoluteSyncSchema = (projectRoot) => {
2494
- const appManifestPath = join15(resolve12(projectRoot), "package.json");
2494
+ const appManifestPath = join16(resolve13(projectRoot), "package.json");
2495
2495
  const appManifest = manifestAt(appManifestPath);
2496
2496
  if (!appManifest)
2497
2497
  return {
@@ -6838,9 +6838,9 @@ var require_sha256 = __commonJS(function(exports, module) {
6838
6838
  var forge = require_forge();
6839
6839
  require_md();
6840
6840
  require_util();
6841
- var sha2563 = module.exports = forge.sha256 = forge.sha256 || {};
6842
- forge.md.sha256 = forge.md.algorithms.sha256 = sha2563;
6843
- sha2563.create = function() {
6841
+ var sha2564 = module.exports = forge.sha256 = forge.sha256 || {};
6842
+ forge.md.sha256 = forge.md.algorithms.sha256 = sha2564;
6843
+ sha2564.create = function() {
6844
6844
  if (!_initialized) {
6845
6845
  _init();
6846
6846
  }
@@ -19351,7 +19351,7 @@ var init_compatibilityDispatcher = __esm(() => {
19351
19351
  // src/cli/scripts/telemetry.ts
19352
19352
  import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
19353
19353
  import { homedir as homedir4 } from "os";
19354
- import { join as join22 } from "path";
19354
+ import { join as join23 } from "path";
19355
19355
  var configDir, configPath, getTelemetryConfig = () => {
19356
19356
  try {
19357
19357
  if (!existsSync5(configPath))
@@ -19364,14 +19364,14 @@ var configDir, configPath, getTelemetryConfig = () => {
19364
19364
  }
19365
19365
  };
19366
19366
  var init_telemetry = __esm(() => {
19367
- configDir = join22(homedir4(), ".absolutejs");
19368
- configPath = join22(configDir, "telemetry.json");
19367
+ configDir = join23(homedir4(), ".absolutejs");
19368
+ configPath = join23(configDir, "telemetry.json");
19369
19369
  });
19370
19370
 
19371
19371
  // src/cli/telemetryEvent.ts
19372
19372
  import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
19373
19373
  import { arch, platform as platform3 } from "os";
19374
- import { dirname as dirname15, join as join23, parse } from "path";
19374
+ import { dirname as dirname16, join as join24, parse } from "path";
19375
19375
  var checkCandidate = (candidate) => {
19376
19376
  if (!existsSync6(candidate)) {
19377
19377
  return null;
@@ -19391,12 +19391,12 @@ var checkCandidate = (candidate) => {
19391
19391
  }, findPackageVersion = () => {
19392
19392
  let { dir } = import.meta;
19393
19393
  while (dir !== parse(dir).root) {
19394
- const candidate = join23(dir, "package.json");
19394
+ const candidate = join24(dir, "package.json");
19395
19395
  const version = checkCandidate(candidate);
19396
19396
  if (version) {
19397
19397
  return version;
19398
19398
  }
19399
- dir = dirname15(dir);
19399
+ dir = dirname16(dir);
19400
19400
  }
19401
19401
  return "unknown";
19402
19402
  }, sendTelemetryEvent = (event, payload) => {
@@ -20032,7 +20032,7 @@ __export(exports_mobileUpdate, {
20032
20032
  parseMobileUpdateManifest: () => parseMobileUpdateManifest
20033
20033
  });
20034
20034
  import {
20035
- createHash as createHash17,
20035
+ createHash as createHash18,
20036
20036
  createHmac,
20037
20037
  createPrivateKey,
20038
20038
  createPublicKey as createPublicKey2,
@@ -20042,7 +20042,7 @@ import {
20042
20042
  verify as verify2,
20043
20043
  X509Certificate as X509Certificate3
20044
20044
  } from "crypto";
20045
- import { readFile as readFile26, stat as stat6 } from "fs/promises";
20045
+ import { readFile as readFile27, stat as stat7 } from "fs/promises";
20046
20046
  import path from "path";
20047
20047
  var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updates", MAX_FILE_BYTES, MAX_TOTAL_BYTES, DAY_MS, DEFAULT_MIN_AGE_MS, DEFAULT_GRACE_PERIOD_MS, DEFAULT_RETAIN_RECENT = 5, HASH, RELEASE, APP_ID, NAME, EXPO_DESCRIPTOR = "_absolute/expo-update.json", EXPO_CODE_SIGNING_ALGORITHM = "rsa-v1_5-sha256", HEALTH_TOKEN_VERSION = 1, HEALTH_KINDS, FAILURE_HEALTH_KINDS, MobileUpdateRegistryError, object6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), text2 = (value, field2) => {
20048
20048
  if (typeof value !== "string" || value.length === 0)
@@ -20192,7 +20192,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20192
20192
  if (!prefix || prefix.split("/").some((segment) => segment === "." || segment === ".."))
20193
20193
  throw new MobileUpdateRegistryError("Mobile update prefix is invalid");
20194
20194
  return prefix;
20195
- }, appHash = (appId) => createHash17("sha256").update(appId).digest("hex"), digest = (bytes) => createHash17("sha256").update(bytes).digest("hex"), json = (value) => new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
20195
+ }, appHash = (appId) => createHash18("sha256").update(appId).digest("hex"), digest = (bytes) => createHash18("sha256").update(bytes).digest("hex"), json = (value) => new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
20196
20196
  `), decode2 = (value) => JSON.parse(new TextDecoder().decode(value)), fileDigest = async (file) => {
20197
20197
  const hasher = new Bun.CryptoHasher("sha256");
20198
20198
  for await (const chunk of file.stream())
@@ -20203,7 +20203,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20203
20203
  return false;
20204
20204
  if (input.rollout === 1)
20205
20205
  return true;
20206
- const value = createHash17("sha256").update(`${input.appId}\x00${input.channel}\x00${input.releaseId}\x00${input.installationId}`).digest().readUInt32BE(0);
20206
+ const value = createHash18("sha256").update(`${input.appId}\x00${input.channel}\x00${input.releaseId}\x00${input.installationId}`).digest().readUInt32BE(0);
20207
20207
  return value / 4294967296 < input.rollout;
20208
20208
  }, base64Url = (value) => Buffer.from(value).toString("base64url"), healthPromotionId = (channel) => channel.promotionId ?? digest(new TextEncoder().encode(`${channel.appId}\x00${channel.channel}\x00${channel.releaseId ?? "embedded"}\x00${channel.promotedAt}`)), finiteMetric = (value, field2) => {
20209
20209
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
@@ -20243,7 +20243,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20243
20243
  const releaseRoot = (manifest) => `${root(manifest.appId)}/releases/${manifest.releaseId}`;
20244
20244
  const manifestKey = (manifest) => `${releaseRoot(manifest)}/update.json`;
20245
20245
  const fileKey = (manifest, file) => `${releaseRoot(manifest)}/files/${file.path}`;
20246
- const contentBlobKey = (appId, sha2564) => `${root(appId)}/blobs/${sha2564}`;
20246
+ const contentBlobKey = (appId, sha2565) => `${root(appId)}/blobs/${sha2565}`;
20247
20247
  const tombstoneKey = (appId, releaseId) => `${root(appId)}/gc/${releaseId}.json`;
20248
20248
  const healthRoot = (appId, promotionId, releaseId) => `${root(appId)}/health/${promotionId}/${releaseId}`;
20249
20249
  const pauseKey = (appId, promotionId, releaseId) => `${healthRoot(appId, promotionId, releaseId)}/paused.json`;
@@ -20864,10 +20864,10 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20864
20864
  const objectBytesByDigest = new Map;
20865
20865
  for (const blobObject of objects) {
20866
20866
  if (blobObject.key.startsWith(blobPrefix)) {
20867
- const sha2564 = blobObject.key.slice(blobPrefix.length);
20868
- if (HASH.test(sha2564)) {
20869
- objectKeysByDigest.set(sha2564, blobObject.key);
20870
- objectBytesByDigest.set(sha2564, blobObject.size);
20867
+ const sha2565 = blobObject.key.slice(blobPrefix.length);
20868
+ if (HASH.test(sha2565)) {
20869
+ objectKeysByDigest.set(sha2565, blobObject.key);
20870
+ objectBytesByDigest.set(sha2565, blobObject.size);
20871
20871
  }
20872
20872
  }
20873
20873
  if (!blobObject.key.startsWith(releasePrefix))
@@ -20950,7 +20950,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20950
20950
  }).toSorted((left, right) => right.createdAt.localeCompare(left.createdAt));
20951
20951
  const protectedReleaseIds = new Set(releases.filter((release) => release.protectedBy.length > 0).map((release) => release.releaseId));
20952
20952
  const protectedDigests = new Set(manifests.filter((manifest) => protectedReleaseIds.has(manifest.releaseId)).flatMap((manifest) => manifest.files.map((file) => file.sha256)));
20953
- const reclaimableContentBytes = [...objectBytesByDigest].filter(([sha2564]) => !protectedDigests.has(sha2564)).reduce((total, [, bytes]) => total + bytes, 0);
20953
+ const reclaimableContentBytes = [...objectBytesByDigest].filter(([sha2565]) => !protectedDigests.has(sha2565)).reduce((total, [, bytes]) => total + bytes, 0);
20954
20954
  const contentBlobBytes = [...objectBytesByDigest.values()].reduce((total, bytes) => total + bytes, 0);
20955
20955
  const releaseBytes = releases.reduce((total, release) => total + release.bytes, 0);
20956
20956
  const totalBytes = objects.reduce((total, object22) => total + object22.size, 0);
@@ -21047,13 +21047,13 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21047
21047
  for (const file of manifest?.manifest.files ?? [])
21048
21048
  referencedDigests.add(file.sha256);
21049
21049
  }
21050
- for (const [sha2564, key] of afterReleaseSweep.objectKeysByDigest) {
21051
- if (referencedDigests.has(sha2564))
21050
+ for (const [sha2565, key] of afterReleaseSweep.objectKeysByDigest) {
21051
+ if (referencedDigests.has(sha2565))
21052
21052
  continue;
21053
21053
  const head = await options.store.head(key);
21054
21054
  await remove(key);
21055
21055
  result.reclaimedBytes += head?.size ?? 0;
21056
- result.sweptContentBlobs.push(sha2564);
21056
+ result.sweptContentBlobs.push(sha2565);
21057
21057
  }
21058
21058
  return result;
21059
21059
  };
@@ -21075,7 +21075,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21075
21075
  verifyManifestSignature(manifest, options.publicKeys);
21076
21076
  await assertNotMarked(manifest.appId, manifest.releaseId);
21077
21077
  const localRoot = path.resolve(input.releaseDirectory);
21078
- const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile26(path.join(localRoot, "update.json"), "utf8")));
21078
+ const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile27(path.join(localRoot, "update.json"), "utf8")));
21079
21079
  if (JSON.stringify(localManifest) !== JSON.stringify(manifest))
21080
21080
  throw new MobileUpdateRegistryError("Local mobile update manifest changed");
21081
21081
  const existing = await readManifest(manifest.appId, manifest.releaseId);
@@ -21093,7 +21093,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21093
21093
  if (!existing) {
21094
21094
  for (const file of manifest.files) {
21095
21095
  const local = path.join(localRoot, "files", file.path);
21096
- const metadata = await stat6(local).catch(() => null);
21096
+ const metadata = await stat7(local).catch(() => null);
21097
21097
  if (!metadata?.isFile() || metadata.size !== file.bytes)
21098
21098
  throw new MobileUpdateRegistryError(`Mobile update file ${file.path} size changed`);
21099
21099
  if (await fileDigest(Bun.file(local)) !== file.sha256)
@@ -21208,7 +21208,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21208
21208
  }
21209
21209
  };
21210
21210
  }, expoUpdateId = (releaseId) => {
21211
- const hash = RELEASE.test(releaseId) ? releaseId.slice("amu_".length, "amu_".length + 32) : createHash17("sha256").update(releaseId).digest("hex").slice(0, 32);
21211
+ const hash = RELEASE.test(releaseId) ? releaseId.slice("amu_".length, "amu_".length + 32) : createHash18("sha256").update(releaseId).digest("hex").slice(0, 32);
21212
21212
  return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20)}`;
21213
21213
  }, expoContentType = (extension2, launch2) => {
21214
21214
  if (launch2)
@@ -21361,8 +21361,8 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21361
21361
  });
21362
21362
  }
21363
21363
  const pathname = new URL(request.url).pathname.replace(/^\/+/, "");
21364
- const relative19 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
21365
- if (request.method === "POST" && relative19 === "health") {
21364
+ const relative20 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
21365
+ if (request.method === "POST" && relative20 === "health") {
21366
21366
  if (!options.registry.recordUpdateHealth)
21367
21367
  return new Response(null, { status: 404 });
21368
21368
  const appId = request.headers.get("x-absolute-mobile-app");
@@ -21405,7 +21405,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21405
21405
  }
21406
21406
  if (request.method !== "GET")
21407
21407
  return new Response(null, { status: 405 });
21408
- if (relative19 === "update.json") {
21408
+ if (relative20 === "update.json") {
21409
21409
  const expoProtocolVersion = request.headers.get("expo-protocol-version");
21410
21410
  const expoProtocol = expoProtocolVersion !== null;
21411
21411
  if (expoProtocol && expoProtocolVersion !== "1")
@@ -21523,7 +21523,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21523
21523
  }
21524
21524
  });
21525
21525
  }
21526
- const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative19);
21526
+ const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative20);
21527
21527
  if (!match?.[1] || !match[2])
21528
21528
  return new Response(null, { status: 404 });
21529
21529
  const file = await options.registry.readUpdateFile({
@@ -21616,15 +21616,15 @@ import {
21616
21616
  createPublicKey as createPublicKey3,
21617
21617
  X509Certificate as X509Certificate4
21618
21618
  } from "crypto";
21619
- import { access as access18, mkdir as mkdir20 } from "fs/promises";
21620
- import { dirname as dirname21, isAbsolute as isAbsolute10, relative as relative19, resolve as resolve21, sep as sep12 } from "path";
21619
+ import { access as access19, mkdir as mkdir21 } from "fs/promises";
21620
+ import { dirname as dirname22, isAbsolute as isAbsolute11, relative as relative20, resolve as resolve22, sep as sep13 } from "path";
21621
21621
  import { pathToFileURL as pathToFileURL5 } from "url";
21622
21622
  import { Elysia as Elysia4 } from "elysia";
21623
21623
  var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE = "mobile.update.ts", object7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), projectPath3 = (projectRoot, requested) => {
21624
- const root = resolve21(projectRoot);
21625
- const path2 = resolve21(root, requested);
21626
- const projectRelative = relative19(root, path2);
21627
- if (projectRelative === ".." || projectRelative.startsWith(`..${sep12}`) || isAbsolute10(projectRelative))
21624
+ const root = resolve22(projectRoot);
21625
+ const path2 = resolve22(root, requested);
21626
+ const projectRelative = relative20(root, path2);
21627
+ if (projectRelative === ".." || projectRelative.startsWith(`..${sep13}`) || isAbsolute11(projectRelative))
21628
21628
  throw new TypeError("mobile.updates.server.registry must remain inside the project.");
21629
21629
  return path2;
21630
21630
  }, isRegistry4 = (value) => object7(value) && [
@@ -21647,7 +21647,7 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
21647
21647
  return metadata;
21648
21648
  }, loadAbsoluteMobileUpdateServerModule = async (projectRoot, requestedModulePath = DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE) => {
21649
21649
  const modulePath = projectPath3(projectRoot, requestedModulePath);
21650
- await access18(modulePath).catch(() => {
21650
+ await access19(modulePath).catch(() => {
21651
21651
  throw new TypeError(`Mobile update server registry does not exist: ${modulePath}. Run \`absolute mobile update provision\`.`);
21652
21652
  });
21653
21653
  const loaded = await import(pathToFileURL5(modulePath).href);
@@ -21836,13 +21836,13 @@ ${generated}`);
21836
21836
  }, writeAbsoluteMobileUpdateRegistry = async (options) => {
21837
21837
  const path2 = projectPath3(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
21838
21838
  if (!options.force) {
21839
- await access18(path2).then(() => {
21839
+ await access19(path2).then(() => {
21840
21840
  throw new TypeError(`Mobile update registry already exists: ${path2}. Pass --force to replace it.`);
21841
21841
  }, () => {
21842
21842
  return;
21843
21843
  });
21844
21844
  }
21845
- await mkdir20(dirname21(path2), { recursive: true });
21845
+ await mkdir21(dirname22(path2), { recursive: true });
21846
21846
  await Bun.write(path2, renderAbsoluteMobileUpdateRegistry({
21847
21847
  ...options.health ? { health: options.health } : {},
21848
21848
  ...options.rollout ? { rollout: options.rollout } : {},
@@ -25393,6 +25393,25 @@ var safeOutputDirectory2 = (projectRoot, requested) => {
25393
25393
  return output;
25394
25394
  };
25395
25395
  var sha256File2 = async (path) => createHash6("sha256").update(await readFile7(path)).digest("hex");
25396
+ var verifyRegisteredReleaseArtifact = async (releaseRoot, metadata) => {
25397
+ if (!metadata.registeredDevice)
25398
+ return;
25399
+ const destination = join7(releaseRoot, metadata.registeredDevice.artifact);
25400
+ const [bytes, sha2562] = await Promise.all([
25401
+ stat3(destination).then(({ size }) => size),
25402
+ sha256File2(destination)
25403
+ ]);
25404
+ if (bytes !== metadata.registeredDevice.bytes || sha2562 !== metadata.registeredDevice.sha256)
25405
+ throw new TypeError(`Immutable iOS release ${metadata.releaseId} registered-device artifact is missing or modified.`);
25406
+ return destination;
25407
+ };
25408
+ var copyRegisteredReleaseArtifact = async (staging, metadata, registeredArtifactPath) => {
25409
+ if (!metadata.registeredDevice)
25410
+ return;
25411
+ if (!registeredArtifactPath)
25412
+ throw new TypeError("iOS release metadata requires a registered-device artifact.");
25413
+ await copyFile3(registeredArtifactPath, join7(staging, metadata.registeredDevice.artifact));
25414
+ };
25396
25415
  var findByExtension = async (root, extension) => {
25397
25416
  if (!await pathExists4(root))
25398
25417
  return;
@@ -25448,12 +25467,12 @@ var resolveAbsoluteIosXcodeProject = async (nativeDirectory, options = {}) => {
25448
25467
  throw new TypeError(schemes.length > 1 ? `iOS release found multiple shared Xcode schemes: ${schemes.join(", ")}. Pass an explicit scheme.` : "iOS release could not find a shared Xcode scheme.");
25449
25468
  return { scheme: schemes[0], workspacePath };
25450
25469
  };
25451
- var exportOptions = () => `<?xml version="1.0" encoding="UTF-8"?>
25470
+ var exportOptions = (method) => `<?xml version="1.0" encoding="UTF-8"?>
25452
25471
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
25453
25472
  <plist version="1.0"><dict>
25454
25473
  <key>destination</key><string>export</string>
25455
25474
  <key>manageAppVersionAndBuildNumber</key><false/>
25456
- <key>method</key><string>app-store-connect</string>
25475
+ <key>method</key><string>${method}</string>
25457
25476
  <key>signingStyle</key><string>automatic</string>
25458
25477
  <key>stripSwiftSymbols</key><true/>
25459
25478
  <key>uploadSymbols</key><true/>
@@ -25464,7 +25483,19 @@ var requireBuildNumber = (value) => {
25464
25483
  throw new TypeError("iOS build number must be a positive integer.");
25465
25484
  return value;
25466
25485
  };
25486
+ var normalizeRegisteredDevice = (value) => {
25487
+ if (value === undefined)
25488
+ return;
25489
+ if (!isRecord3(value) || value.artifact !== "App.registered.ipa" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || typeof value.sha256 !== "string" || !/^[a-f0-9]{64}$/u.test(value.sha256))
25490
+ throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
25491
+ return {
25492
+ artifact: "App.registered.ipa",
25493
+ bytes: value.bytes,
25494
+ sha256: value.sha256
25495
+ };
25496
+ };
25467
25497
  var requireAbsoluteIosReleaseMetadata = (value) => {
25498
+ const registeredDevice = normalizeRegisteredDevice(isRecord3(value) ? value.registeredDevice : undefined);
25468
25499
  if (!isRecord3(value) || value.artifact !== "App.ipa" || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || value.engine !== "capacitor" && value.engine !== "expo" || value.format !== ABSOLUTE_IOS_RELEASE_FORMAT || typeof value.marketingVersion !== "string" || value.platform !== "ios" || typeof value.releaseId !== "string" || typeof value.runtime !== "string" || typeof value.sha256 !== "string" || typeof value.signed !== "boolean" || value.type !== "ipa" || value.buildNumber !== undefined && (typeof value.buildNumber !== "number" || !Number.isSafeInteger(value.buildNumber) || value.buildNumber < 1) || !/^amobile_ios_[a-f0-9]{64}$/u.test(value.releaseId) || !/^[a-f0-9]{64}$/u.test(value.sha256) || value.releaseId !== `amobile_ios_${value.sha256}`) {
25469
25500
  throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
25470
25501
  }
@@ -25478,6 +25509,7 @@ var requireAbsoluteIosReleaseMetadata = (value) => {
25478
25509
  format: value.format,
25479
25510
  marketingVersion: value.marketingVersion,
25480
25511
  platform: value.platform,
25512
+ ...registeredDevice ? { registeredDevice } : {},
25481
25513
  releaseId: value.releaseId,
25482
25514
  runtime: value.runtime,
25483
25515
  sha256: value.sha256,
@@ -25485,12 +25517,13 @@ var requireAbsoluteIosReleaseMetadata = (value) => {
25485
25517
  type: value.type
25486
25518
  };
25487
25519
  };
25488
- var installRelease2 = async (artifactPath, metadata, outputRoot) => {
25520
+ var installRelease2 = async (artifactPath, metadata, outputRoot, registeredArtifactPath) => {
25489
25521
  const releaseRoot = join7(outputRoot, metadata.releaseId);
25490
25522
  const destination = join7(releaseRoot, "App.ipa");
25491
25523
  if (await pathExists4(releaseRoot)) {
25492
25524
  const value = JSON.parse(await readFile7(join7(releaseRoot, "release.json"), "utf8"));
25493
- if (!isRecord3(value) || value.artifact !== "App.ipa" || Object.entries(metadata).some(([key, expected]) => Reflect.get(value, key) !== expected)) {
25525
+ const existing = requireAbsoluteIosReleaseMetadata(value);
25526
+ if (JSON.stringify(existing) !== JSON.stringify({ ...metadata, artifact: "App.ipa" })) {
25494
25527
  throw new TypeError(`Immutable iOS release ${metadata.releaseId} does not match its content.`);
25495
25528
  }
25496
25529
  const [bytes, sha2562] = await Promise.all([
@@ -25499,12 +25532,14 @@ var installRelease2 = async (artifactPath, metadata, outputRoot) => {
25499
25532
  ]);
25500
25533
  if (bytes !== metadata.bytes || sha2562 !== metadata.sha256)
25501
25534
  throw new TypeError(`Immutable iOS release ${metadata.releaseId} artifact is missing or modified.`);
25535
+ const registeredDestination = await verifyRegisteredReleaseArtifact(releaseRoot, metadata);
25502
25536
  return {
25503
25537
  artifactPath: destination,
25504
25538
  metadata: {
25505
25539
  ...metadata,
25506
25540
  artifact: "App.ipa"
25507
25541
  },
25542
+ ...registeredDestination ? { registeredArtifactPath: registeredDestination } : {},
25508
25543
  releaseRoot
25509
25544
  };
25510
25545
  }
@@ -25512,6 +25547,7 @@ var installRelease2 = async (artifactPath, metadata, outputRoot) => {
25512
25547
  const staging = await mkdtemp4(join7(dirname4(releaseRoot), ".ios-stage-"));
25513
25548
  try {
25514
25549
  await copyFile3(artifactPath, join7(staging, "App.ipa"));
25550
+ await copyRegisteredReleaseArtifact(staging, metadata, registeredArtifactPath);
25515
25551
  const complete = {
25516
25552
  ...metadata,
25517
25553
  artifact: "App.ipa"
@@ -25519,13 +25555,50 @@ var installRelease2 = async (artifactPath, metadata, outputRoot) => {
25519
25555
  await writeFile6(join7(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
25520
25556
  `, { flag: "wx" });
25521
25557
  await rename6(staging, releaseRoot);
25522
- return { artifactPath: destination, metadata: complete, releaseRoot };
25558
+ return {
25559
+ artifactPath: destination,
25560
+ metadata: complete,
25561
+ ...metadata.registeredDevice ? {
25562
+ registeredArtifactPath: join7(releaseRoot, metadata.registeredDevice.artifact)
25563
+ } : {},
25564
+ releaseRoot
25565
+ };
25523
25566
  } finally {
25524
25567
  await rm5(staging, { force: true, recursive: true }).catch(() => {
25525
25568
  return;
25526
25569
  });
25527
25570
  }
25528
25571
  };
25572
+ var exportRegisteredDeviceArtifact = async (options) => {
25573
+ const exportPath = join7(options.staging, "registered-export");
25574
+ const exportPlist = join7(options.staging, "RegisteredExportOptions.plist");
25575
+ await mkdir5(exportPath, { recursive: true });
25576
+ await writeFile6(exportPlist, exportOptions("debugging"));
25577
+ const exitCode = await options.run([
25578
+ "xcodebuild",
25579
+ "-exportArchive",
25580
+ "-archivePath",
25581
+ options.archivePath,
25582
+ "-exportPath",
25583
+ exportPath,
25584
+ "-exportOptionsPlist",
25585
+ exportPlist
25586
+ ], { cwd: options.nativeDirectory, env: options.env });
25587
+ if (exitCode !== 0)
25588
+ throw new TypeError("Xcode failed to export the registered-device IPA. Confirm the selected development team includes the test device.");
25589
+ const artifactPath = await findByExtension(exportPath, ".ipa");
25590
+ if (!artifactPath)
25591
+ throw new TypeError("Xcode did not produce a registered-device IPA.");
25592
+ const [bytes, sha2562] = await Promise.all([
25593
+ stat3(artifactPath).then(({ size }) => size),
25594
+ sha256File2(artifactPath)
25595
+ ]);
25596
+ const metadata = { artifact: "App.registered.ipa", bytes, sha256: sha2562 };
25597
+ return {
25598
+ artifactPath,
25599
+ metadata
25600
+ };
25601
+ };
25529
25602
  var buildAbsoluteIosRelease = async (options) => {
25530
25603
  if (options.buildNumber !== undefined && options.prepareBuildNumber)
25531
25604
  throw new TypeError("iOS release buildNumber and prepareBuildNumber cannot be combined.");
@@ -25555,7 +25628,7 @@ var buildAbsoluteIosRelease = async (options) => {
25555
25628
  const exportPath = join7(staging, "export");
25556
25629
  const exportPlist = join7(staging, "ExportOptions.plist");
25557
25630
  await mkdir5(exportPath, { recursive: true });
25558
- await writeFile6(exportPlist, exportOptions());
25631
+ await writeFile6(exportPlist, exportOptions("app-store-connect"));
25559
25632
  const run = options.run ?? defaultRun2;
25560
25633
  try {
25561
25634
  const developmentTeam = developmentTeamArgument(options.developmentTeam);
@@ -25612,6 +25685,13 @@ var buildAbsoluteIosRelease = async (options) => {
25612
25685
  sha256File2(artifactPath)
25613
25686
  ]);
25614
25687
  const releaseId = `amobile_ios_${sha2562}`;
25688
+ const registered = options.registeredDeviceArtifact ? await exportRegisteredDeviceArtifact({
25689
+ archivePath,
25690
+ ...options.env ? { env: options.env } : {},
25691
+ nativeDirectory,
25692
+ run,
25693
+ staging
25694
+ }) : undefined;
25615
25695
  return await installRelease2(artifactPath, {
25616
25696
  appBuild: manifest.appBuild,
25617
25697
  appId: manifest.appId,
@@ -25621,12 +25701,13 @@ var buildAbsoluteIosRelease = async (options) => {
25621
25701
  format: 1,
25622
25702
  marketingVersion,
25623
25703
  platform: "ios",
25704
+ ...registered ? { registeredDevice: registered.metadata } : {},
25624
25705
  releaseId,
25625
25706
  runtime: manifest.runtime,
25626
25707
  sha256: sha2562,
25627
25708
  signed,
25628
25709
  type: "ipa"
25629
- }, safeOutputDirectory2(options.projectRoot, options.outputDirectory));
25710
+ }, safeOutputDirectory2(options.projectRoot, options.outputDirectory), registered?.artifactPath);
25630
25711
  } finally {
25631
25712
  await rm5(staging, { force: true, recursive: true }).catch(() => {
25632
25713
  return;
@@ -25641,9 +25722,40 @@ var installAbsoluteIosRelease = async (options) => {
25641
25722
  ]);
25642
25723
  if (bytes !== metadata.bytes || sha2562 !== metadata.sha256)
25643
25724
  throw new TypeError("Remote iOS release artifact does not match its signed metadata.");
25725
+ if (metadata.registeredDevice) {
25726
+ if (!options.registeredArtifactPath)
25727
+ throw new TypeError("Remote iOS release metadata requires its registered-device artifact.");
25728
+ const [registeredBytes, registeredSha256] = await Promise.all([
25729
+ stat3(options.registeredArtifactPath).then(({ size }) => size),
25730
+ sha256File2(options.registeredArtifactPath)
25731
+ ]);
25732
+ if (registeredBytes !== metadata.registeredDevice.bytes || registeredSha256 !== metadata.registeredDevice.sha256)
25733
+ throw new TypeError("Remote iOS registered-device artifact does not match its signed metadata.");
25734
+ }
25644
25735
  const { artifact: _artifact, ...releaseMetadata } = metadata;
25645
- return installRelease2(options.artifactPath, releaseMetadata, safeOutputDirectory2(options.projectRoot, options.outputDirectory));
25736
+ return installRelease2(options.artifactPath, releaseMetadata, safeOutputDirectory2(options.projectRoot, options.outputDirectory), options.registeredArtifactPath);
25646
25737
  };
25738
+ // src/mobile/iosReleaseAcceptance.ts
25739
+ import { createHash as createHash7 } from "crypto";
25740
+ import {
25741
+ access as access8,
25742
+ mkdir as mkdir6,
25743
+ mkdtemp as mkdtemp5,
25744
+ readFile as readFile8,
25745
+ readdir as readdir4,
25746
+ rm as rm6,
25747
+ stat as stat4
25748
+ } from "fs/promises";
25749
+ import {
25750
+ basename as basename2,
25751
+ dirname as dirname5,
25752
+ isAbsolute as isAbsolute5,
25753
+ join as join8,
25754
+ relative as relative6,
25755
+ resolve as resolve6,
25756
+ sep as sep5
25757
+ } from "path";
25758
+
25647
25759
  // src/mobile/iosUpgradeConformance.ts
25648
25760
  var captureCommand5 = async (command) => {
25649
25761
  const process2 = Bun.spawn(command, { stderr: "pipe", stdout: "pipe" });
@@ -25714,8 +25826,381 @@ var assertAbsoluteIosInstalledAppUpgrade = (before, after) => {
25714
25826
  if (afterBuild <= beforeBuild)
25715
25827
  throw new Error(`iOS CFBundleVersion did not increase (${before.buildNumber} -> ${after.buildNumber}).`);
25716
25828
  };
25829
+
25830
+ // src/mobile/iosReleaseAcceptance.ts
25831
+ var READY_MARKERS = {
25832
+ capacitor: "Capacitor embedded web content ready",
25833
+ expo: "Expo embedded web content ready"
25834
+ };
25835
+ var READY_TIMEOUT_MS = 30000;
25836
+ var READY_POLL_MS = 250;
25837
+ var defaultRun3 = async (command, options = {}) => {
25838
+ const process2 = Bun.spawn(command, {
25839
+ cwd: options.cwd,
25840
+ env: options.env,
25841
+ stderr: "pipe",
25842
+ stdin: "ignore",
25843
+ stdout: "pipe"
25844
+ });
25845
+ const [exitCode, stderr, stdout] = await Promise.all([
25846
+ process2.exited,
25847
+ new Response(process2.stderr).text(),
25848
+ new Response(process2.stdout).text()
25849
+ ]);
25850
+ return { exitCode, stderr, stdout };
25851
+ };
25852
+ var exists3 = async (path) => {
25853
+ try {
25854
+ await access8(path);
25855
+ return true;
25856
+ } catch {
25857
+ return false;
25858
+ }
25859
+ };
25860
+ var sha2562 = async (path) => createHash7("sha256").update(await readFile8(path)).digest("hex");
25861
+ var inside2 = (root, candidate) => {
25862
+ const path = relative6(resolve6(root), resolve6(candidate));
25863
+ return path === "" || !isAbsolute5(path) && path !== ".." && !path.startsWith(`..${sep5}`);
25864
+ };
25865
+ var requireSuccess3 = async (run, command, label, options) => {
25866
+ const result = await run(command, options);
25867
+ if (result.exitCode !== 0)
25868
+ throw new Error(`${label} failed: ${result.stderr.trim() || result.stdout.trim() || `status ${result.exitCode}`}`);
25869
+ return result;
25870
+ };
25871
+ var findByExtension2 = async (root, extension) => {
25872
+ if (!await exists3(root))
25873
+ return;
25874
+ const entries = await readdir4(root, { withFileTypes: true });
25875
+ const matches2 = await Promise.all(entries.map(async (entry) => {
25876
+ const path = join8(root, entry.name);
25877
+ if (entry.name.endsWith(extension))
25878
+ return path;
25879
+ return entry.isDirectory() ? findByExtension2(path, extension) : undefined;
25880
+ }));
25881
+ return matches2.find((match) => match !== undefined);
25882
+ };
25883
+ var readAbsoluteIosRelease = async (projectRoot, requested) => {
25884
+ const root = resolve6(projectRoot);
25885
+ const selected = resolve6(root, requested);
25886
+ if (!inside2(root, selected))
25887
+ throw new TypeError("mobile test ios --release must remain inside the project.");
25888
+ const metadataPath = basename2(selected) === "release.json" ? selected : join8(selected, "release.json");
25889
+ const releaseRoot = dirname5(metadataPath);
25890
+ const metadata = requireAbsoluteIosReleaseMetadata(JSON.parse(await readFile8(metadataPath, "utf8")));
25891
+ const artifactPath = resolve6(releaseRoot, metadata.artifact);
25892
+ if (!inside2(releaseRoot, artifactPath))
25893
+ throw new TypeError("iOS release artifact path is invalid.");
25894
+ const [artifactStat, artifactSha256] = await Promise.all([
25895
+ stat4(artifactPath),
25896
+ sha2562(artifactPath)
25897
+ ]);
25898
+ if (artifactStat.size !== metadata.bytes || artifactSha256 !== metadata.sha256)
25899
+ throw new TypeError(`Immutable iOS release ${metadata.releaseId} is missing or modified.`);
25900
+ const registered = metadata.registeredDevice;
25901
+ let registeredArtifactPath;
25902
+ if (registered) {
25903
+ registeredArtifactPath = resolve6(releaseRoot, registered.artifact);
25904
+ if (!inside2(releaseRoot, registeredArtifactPath))
25905
+ throw new TypeError("iOS registered-device artifact path is invalid.");
25906
+ const [registeredStat, registeredSha256] = await Promise.all([
25907
+ stat4(registeredArtifactPath),
25908
+ sha2562(registeredArtifactPath)
25909
+ ]);
25910
+ if (registeredStat.size !== registered.bytes || registeredSha256 !== registered.sha256)
25911
+ throw new TypeError(`Registered-device export for ${metadata.releaseId} is missing or modified.`);
25912
+ }
25913
+ return {
25914
+ artifactPath,
25915
+ metadata,
25916
+ metadataPath,
25917
+ registeredArtifactPath,
25918
+ releaseRoot
25919
+ };
25920
+ };
25921
+ var releaseMarker = (release) => {
25922
+ const marker = READY_MARKERS[release.metadata.engine];
25923
+ return release.metadata.buildNumber === undefined ? marker : `${marker}; version=${release.metadata.marketingVersion}; build=${release.metadata.buildNumber}`;
25924
+ };
25925
+ var waitForSimulatorMarker = async (options) => {
25926
+ const startedAt = performance.now();
25927
+ const poll = async () => {
25928
+ if (performance.now() - startedAt >= READY_TIMEOUT_MS)
25929
+ throw new Error("The installed iOS Release app launched but its embedded content did not become ready.");
25930
+ const logs = await options.run([
25931
+ options.xcrun,
25932
+ "simctl",
25933
+ "spawn",
25934
+ options.udid,
25935
+ "log",
25936
+ "show",
25937
+ "--style",
25938
+ "compact",
25939
+ "--start",
25940
+ options.startedAt.toISOString(),
25941
+ "--predicate",
25942
+ `eventMessage CONTAINS "${releaseMarker(options.release)}"`
25943
+ ]);
25944
+ if (logs.exitCode === 0 && logs.stdout.includes(releaseMarker(options.release)))
25945
+ return;
25946
+ await Bun.sleep(READY_POLL_MS);
25947
+ await poll();
25948
+ };
25949
+ await poll();
25950
+ };
25951
+ var launchSimulator = async (options) => {
25952
+ const startedAt = performance.now();
25953
+ const logStartedAt = new Date;
25954
+ await requireSuccess3(options.run, [
25955
+ options.xcrun,
25956
+ "simctl",
25957
+ "launch",
25958
+ "--terminate-running-process",
25959
+ options.udid,
25960
+ options.release.metadata.appId
25961
+ ], "iOS Simulator Release launch");
25962
+ await waitForSimulatorMarker({ ...options, startedAt: logStartedAt });
25963
+ return Math.round(performance.now() - startedAt);
25964
+ };
25965
+ var runAbsoluteIosSimulatorReleaseAcceptance = async (options) => {
25966
+ const run = options.run ?? defaultRun3;
25967
+ const xcodebuild = options.xcodebuild ?? "/usr/bin/xcodebuild";
25968
+ const xcrun = options.xcrun ?? "/usr/bin/xcrun";
25969
+ const startedAt = performance.now();
25970
+ const iosRoot = join8(options.config.nativeProjectDirectory, "ios");
25971
+ const xcode = await resolveAbsoluteIosXcodeProject(iosRoot);
25972
+ const derivedData = join8(options.artifactDirectory, "DerivedData");
25973
+ await mkdir6(options.artifactDirectory, { recursive: true });
25974
+ await requireSuccess3(run, [
25975
+ xcodebuild,
25976
+ "-workspace",
25977
+ xcode.workspacePath,
25978
+ "-scheme",
25979
+ xcode.scheme,
25980
+ "-configuration",
25981
+ "Release",
25982
+ "-destination",
25983
+ `platform=iOS Simulator,id=${options.udid}`,
25984
+ "-derivedDataPath",
25985
+ derivedData,
25986
+ `MARKETING_VERSION=${options.release.metadata.marketingVersion}`,
25987
+ ...options.release.metadata.buildNumber === undefined ? [] : [
25988
+ `CURRENT_PROJECT_VERSION=${options.release.metadata.buildNumber}`
25989
+ ],
25990
+ "build"
25991
+ ], "iOS Simulator Release build", { cwd: iosRoot });
25992
+ const app = await findByExtension2(join8(derivedData, "Build", "Products"), ".app");
25993
+ if (!app)
25994
+ throw new Error("Xcode did not produce a Simulator Release app.");
25995
+ const installStartedAt = performance.now();
25996
+ await requireSuccess3(run, [xcrun, "simctl", "install", options.udid, app], "iOS Simulator Release installation");
25997
+ const installMs = Math.round(performance.now() - installStartedAt);
25998
+ const installed = await inspectAbsoluteIosInstalledApp(xcrun, options.udid, options.release.metadata.appId, (command) => run(command));
25999
+ if (installed.version !== options.release.metadata.marketingVersion)
26000
+ throw new Error(`Installed iOS version ${installed.version ?? "unknown"} does not match release ${options.release.metadata.marketingVersion}.`);
26001
+ if (options.release.metadata.buildNumber !== undefined && installed.buildNumber !== String(options.release.metadata.buildNumber))
26002
+ throw new Error(`Installed iOS build ${installed.buildNumber ?? "unknown"} does not match release ${options.release.metadata.buildNumber}.`);
26003
+ const launchMs = await launchSimulator({
26004
+ release: options.release,
26005
+ run,
26006
+ udid: options.udid,
26007
+ xcrun
26008
+ });
26009
+ await requireSuccess3(run, [
26010
+ xcrun,
26011
+ "simctl",
26012
+ "terminate",
26013
+ options.udid,
26014
+ options.release.metadata.appId
26015
+ ], "iOS Simulator Release termination");
26016
+ const relaunchMs = await launchSimulator({
26017
+ release: options.release,
26018
+ run,
26019
+ udid: options.udid,
26020
+ xcrun
26021
+ });
26022
+ return {
26023
+ artifactBytes: options.release.metadata.bytes,
26024
+ artifactExactness: "source-equivalent",
26025
+ artifactSha256: options.release.metadata.sha256,
26026
+ ...options.release.metadata.buildNumber === undefined ? {} : { buildNumber: options.release.metadata.buildNumber },
26027
+ distribution: "simulator-release",
26028
+ durationMs: Math.round(performance.now() - startedAt),
26029
+ embeddedLocal: true,
26030
+ engine: options.release.metadata.engine,
26031
+ installMs,
26032
+ launchMs,
26033
+ marketingVersion: options.release.metadata.marketingVersion,
26034
+ networkUnavailable: "not-proven",
26035
+ relaunchMs,
26036
+ releaseId: options.release.metadata.releaseId,
26037
+ signed: options.release.metadata.signed,
26038
+ status: "pass",
26039
+ target: "simulator"
26040
+ };
26041
+ };
26042
+ var readUntilMarker = async (reader, marker, output = "") => {
26043
+ const { done, value } = await reader.read();
26044
+ if (done)
26045
+ return { found: false, output };
26046
+ const next = `${output}${new TextDecoder().decode(value)}`;
26047
+ if (next.includes(marker))
26048
+ return { found: true, output: next };
26049
+ return readUntilMarker(reader, marker, next);
26050
+ };
26051
+ var observeDeviceLaunch = async (options) => {
26052
+ const startedAt = performance.now();
26053
+ const process2 = Bun.spawn([
26054
+ options.xcrun,
26055
+ "devicectl",
26056
+ "device",
26057
+ "process",
26058
+ "launch",
26059
+ "--console",
26060
+ "--terminate-existing",
26061
+ "--device",
26062
+ options.device,
26063
+ options.appId
26064
+ ], { stderr: "pipe", stdin: "ignore", stdout: "pipe" });
26065
+ const stdoutReader = process2.stdout.getReader();
26066
+ const stderrReader = process2.stderr.getReader();
26067
+ const requireMarker = async (reader) => {
26068
+ const result = await readUntilMarker(reader, options.marker);
26069
+ if (!result.found)
26070
+ throw new Error(`Console stream closed before readiness.${result.output.trim() ? ` Output: ${result.output.trim()}` : ""}`);
26071
+ return result;
26072
+ };
26073
+ const observed = Promise.any([
26074
+ requireMarker(stdoutReader),
26075
+ requireMarker(stderrReader)
26076
+ ]);
26077
+ try {
26078
+ const result = await Promise.race([
26079
+ observed.then((value) => ({ type: "output", value })).catch(() => ({ type: "closed" })),
26080
+ Bun.sleep(options.timeoutMs ?? READY_TIMEOUT_MS).then(() => ({
26081
+ type: "timeout"
26082
+ }))
26083
+ ]);
26084
+ if (result.type === "output" && result.value.found)
26085
+ return Math.round(performance.now() - startedAt);
26086
+ if (result.type === "closed")
26087
+ throw new Error("The physical iOS app exited before embedded content became ready.");
26088
+ throw new Error("The physical iOS app did not report embedded readiness before the timeout.");
26089
+ } finally {
26090
+ process2.kill();
26091
+ await Promise.all([
26092
+ stdoutReader.cancel().catch(() => {
26093
+ return;
26094
+ }),
26095
+ stderrReader.cancel().catch(() => {
26096
+ return;
26097
+ })
26098
+ ]);
26099
+ stdoutReader.releaseLock();
26100
+ stderrReader.releaseLock();
26101
+ }
26102
+ };
26103
+ var installRegisteredDeviceRelease = async (options) => {
26104
+ if (!options.release.registeredArtifactPath)
26105
+ throw new TypeError("This release has no same-archive registered-device IPA. Rebuild with `absolute mobile build ios --registered-device-artifact`.");
26106
+ const staging = await mkdtemp5(join8(dirname5(options.release.releaseRoot), ".ios-device-"));
26107
+ try {
26108
+ await requireSuccess3(options.run, [
26109
+ "/usr/bin/ditto",
26110
+ "-x",
26111
+ "-k",
26112
+ options.release.registeredArtifactPath,
26113
+ staging
26114
+ ], "iOS registered-device IPA extraction");
26115
+ const app = await findByExtension2(staging, ".app");
26116
+ if (!app)
26117
+ throw new Error("The registered-device IPA contains no installable app.");
26118
+ const startedAt = performance.now();
26119
+ await requireSuccess3(options.run, [
26120
+ options.xcrun,
26121
+ "devicectl",
26122
+ "device",
26123
+ "install",
26124
+ "app",
26125
+ "--device",
26126
+ options.device,
26127
+ app
26128
+ ], "iOS registered-device Release installation");
26129
+ return Math.round(performance.now() - startedAt);
26130
+ } finally {
26131
+ await rm6(staging, { force: true, recursive: true });
26132
+ }
26133
+ };
26134
+ var inspectTestFlightInstallation = async (options) => {
26135
+ const apps = await requireSuccess3(options.run, [
26136
+ options.xcrun,
26137
+ "devicectl",
26138
+ "device",
26139
+ "info",
26140
+ "apps",
26141
+ "--device",
26142
+ options.device
26143
+ ], "TestFlight installation inspection");
26144
+ if (!apps.stdout.includes(options.release.metadata.appId))
26145
+ throw new Error("The selected device does not have the requested TestFlight app installed.");
26146
+ return 0;
26147
+ };
26148
+ var runAbsoluteIosDeviceReleaseAcceptance = async (options) => {
26149
+ if (!options.networkUnavailableConfirmed)
26150
+ throw new TypeError("Physical iOS offline acceptance requires explicit confirmation that Airplane Mode is enabled and Wi-Fi is disabled in Settings.");
26151
+ const run = options.run ?? defaultRun3;
26152
+ const xcrun = options.xcrun ?? "/usr/bin/xcrun";
26153
+ const startedAt = performance.now();
26154
+ await requireSuccess3(run, [
26155
+ xcrun,
26156
+ "devicectl",
26157
+ "device",
26158
+ "info",
26159
+ "details",
26160
+ "--device",
26161
+ options.device
26162
+ ], "iOS physical-device availability inspection");
26163
+ const installation = {
26164
+ device: options.device,
26165
+ release: options.release,
26166
+ run,
26167
+ xcrun
26168
+ };
26169
+ const installMs = options.distribution === "registered-device" ? await installRegisteredDeviceRelease(installation) : await inspectTestFlightInstallation(installation);
26170
+ const observe = options.observeLaunch ?? ((launch2) => observeDeviceLaunch({ ...launch2, xcrun }));
26171
+ const marker = releaseMarker(options.release);
26172
+ const launchMs = await observe({
26173
+ appId: options.release.metadata.appId,
26174
+ device: options.device,
26175
+ marker
26176
+ });
26177
+ const relaunchMs = await observe({
26178
+ appId: options.release.metadata.appId,
26179
+ device: options.device,
26180
+ marker
26181
+ });
26182
+ return {
26183
+ artifactBytes: options.release.metadata.bytes,
26184
+ artifactExactness: options.distribution === "testflight" ? "store-delivered" : "archive-equivalent",
26185
+ artifactSha256: options.release.metadata.sha256,
26186
+ ...options.release.metadata.buildNumber === undefined ? {} : { buildNumber: options.release.metadata.buildNumber },
26187
+ distribution: options.distribution === "testflight" ? "apple-processed" : "registered-device",
26188
+ durationMs: Math.round(performance.now() - startedAt),
26189
+ embeddedLocal: true,
26190
+ engine: options.release.metadata.engine,
26191
+ installMs,
26192
+ launchMs,
26193
+ marketingVersion: options.release.metadata.marketingVersion,
26194
+ networkUnavailable: "user-confirmed",
26195
+ relaunchMs,
26196
+ releaseId: options.release.metadata.releaseId,
26197
+ signed: options.release.metadata.signed,
26198
+ status: "pass",
26199
+ target: "device"
26200
+ };
26201
+ };
25717
26202
  // src/mobile/iosConformance.ts
25718
- import { readFile as readFile8, stat as stat4 } from "fs/promises";
26203
+ import { readFile as readFile9, stat as stat5 } from "fs/promises";
25719
26204
  var HMR_LINE = new RegExp(String.raw`\[hmr:ios\]\s+([^\n]*?)\s+(applied in|falling back to reload after|failed after)\s+(\d+)ms(?:; server\s+(\d+)ms, client\s+(\d+)ms)?`, "u");
25720
26205
  var parseAbsoluteIosHmrLog = (line) => {
25721
26206
  const match = HMR_LINE.exec(line);
@@ -25747,13 +26232,13 @@ var waitForAbsoluteIosHmrLog = async (options) => {
25747
26232
  const sleep = options.sleep ?? Bun.sleep;
25748
26233
  const timeoutMs = options.timeoutMs ?? 30000;
25749
26234
  const deadline = Date.now() + timeoutMs;
25750
- let offset = options.startOffset ?? await stat4(options.logPath).then(({ size }) => size).catch(() => 0);
26235
+ let offset = options.startOffset ?? await stat5(options.logPath).then(({ size }) => size).catch(() => 0);
25751
26236
  let buffered = "";
25752
26237
  const poll = async () => {
25753
26238
  if (Date.now() > deadline)
25754
26239
  throw new Error(`No iOS native HMR acknowledgement was observed within ${timeoutMs}ms.`);
25755
26240
  options.signal?.throwIfAborted();
25756
- const contents = await readFile8(options.logPath).catch(() => Buffer.alloc(0));
26241
+ const contents = await readFile9(options.logPath).catch(() => Buffer.alloc(0));
25757
26242
  if (contents.byteLength < offset) {
25758
26243
  offset = 0;
25759
26244
  buffered = "";
@@ -25773,18 +26258,18 @@ var waitForAbsoluteIosHmrLog = async (options) => {
25773
26258
  return poll();
25774
26259
  };
25775
26260
  // src/mobile/iosSimulatorController.ts
25776
- import { createHash as createHash7, randomUUID as randomUUID3 } from "crypto";
26261
+ import { createHash as createHash8, randomUUID as randomUUID3 } from "crypto";
25777
26262
  import {
25778
- access as access8,
26263
+ access as access9,
25779
26264
  copyFile as copyFile4,
25780
- mkdir as mkdir6,
25781
- readFile as readFile9,
26265
+ mkdir as mkdir7,
26266
+ readFile as readFile10,
25782
26267
  rename as rename7,
25783
- rm as rm6,
26268
+ rm as rm7,
25784
26269
  writeFile as writeFile7
25785
26270
  } from "fs/promises";
25786
26271
  import { isIP as isIP2 } from "net";
25787
- import { dirname as dirname5, isAbsolute as isAbsolute5, join as join8, relative as relative6, resolve as resolve6, sep as sep5 } from "path";
26272
+ import { dirname as dirname6, isAbsolute as isAbsolute6, join as join9, relative as relative7, resolve as resolve7, sep as sep6 } from "path";
25788
26273
  init_getDurationString();
25789
26274
  var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone";
25790
26275
  var BOOT_TIMEOUT_MS = 180000;
@@ -25794,7 +26279,7 @@ var NATIVE_CACHE_FORMAT = 1;
25794
26279
  var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
25795
26280
  var pathExists5 = async (path) => {
25796
26281
  try {
25797
- await access8(path);
26282
+ await access9(path);
25798
26283
  return true;
25799
26284
  } catch {
25800
26285
  return false;
@@ -25823,7 +26308,7 @@ var defaultCapture3 = (command, options = {}) => {
25823
26308
  };
25824
26309
  }
25825
26310
  };
25826
- var defaultRun3 = async (command, options = {}) => {
26311
+ var defaultRun4 = async (command, options = {}) => {
25827
26312
  const process2 = Bun.spawn(command, {
25828
26313
  cwd: options.cwd,
25829
26314
  env: options.env,
@@ -25889,7 +26374,7 @@ var defaultStartNativeLogs = (command, options, onLine) => {
25889
26374
  }
25890
26375
  };
25891
26376
  };
25892
- var requireSuccess3 = async (command, label, run, options) => {
26377
+ var requireSuccess4 = async (command, label, run, options) => {
25893
26378
  const exitCode = await run(command, options);
25894
26379
  if (exitCode !== 0)
25895
26380
  throw new Error(`${label} failed with status ${exitCode}.`);
@@ -25900,7 +26385,7 @@ var trustIosSimulatorDevelopmentCa = async (options, udid, run, log) => {
25900
26385
  if (!options.certificateAuthorityPath) {
25901
26386
  throw new Error("iOS Simulator HTTPS requires the AbsoluteJS development CA certificate.");
25902
26387
  }
25903
- await requireSuccess3([
26388
+ await requireSuccess4([
25904
26389
  options.project.xcrun,
25905
26390
  "simctl",
25906
26391
  "keychain",
@@ -26029,18 +26514,18 @@ var preferredIphoneType = (types) => types.filter((type) => type.name.startsWith
26029
26514
  return rightPro - leftPro;
26030
26515
  })[0];
26031
26516
  var journalPaths = (projectRoot) => {
26032
- const root = join8(projectRoot, ".absolutejs", "mobile", "ios-dev-session");
26517
+ const root = join9(projectRoot, ".absolutejs", "mobile", "ios-dev-session");
26033
26518
  return {
26034
- configBackup: join8(root, "capacitor-config.backup"),
26035
- infoBackup: join8(root, "Info.plist.backup"),
26036
- journal: join8(root, "journal.json"),
26519
+ configBackup: join9(root, "capacitor-config.backup"),
26520
+ infoBackup: join9(root, "Info.plist.backup"),
26521
+ journal: join9(root, "journal.json"),
26037
26522
  root
26038
26523
  };
26039
26524
  };
26040
- var nativeCachePath = (projectRoot) => join8(projectRoot, ".absolutejs", "mobile", "ios-native-cache.json");
26525
+ var nativeCachePath = (projectRoot) => join9(projectRoot, ".absolutejs", "mobile", "ios-native-cache.json");
26041
26526
  var isInside = (root, path) => {
26042
- const value = relative6(resolve6(root), resolve6(path));
26043
- return value === "" || !value.startsWith(`..${sep5}`) && value !== ".." && !isAbsolute5(value);
26527
+ const value = relative7(resolve7(root), resolve7(path));
26528
+ return value === "" || !value.startsWith(`..${sep6}`) && value !== ".." && !isAbsolute6(value);
26044
26529
  };
26045
26530
  var parseJournal = (value) => {
26046
26531
  if (!isRecord4(value) || value.format !== DEV_JOURNAL_FORMAT)
@@ -26062,10 +26547,10 @@ var parseJournal = (value) => {
26062
26547
  var repairAbsoluteIosDevSession = async (projectRoot) => {
26063
26548
  const paths = journalPaths(projectRoot);
26064
26549
  if (!await pathExists5(paths.journal)) {
26065
- await rm6(paths.root, { force: true, recursive: true });
26550
+ await rm7(paths.root, { force: true, recursive: true });
26066
26551
  return false;
26067
26552
  }
26068
- const journal = await readFile9(paths.journal, "utf8").then((source) => parseJournal(JSON.parse(source))).catch(() => null);
26553
+ const journal = await readFile10(paths.journal, "utf8").then((source) => parseJournal(JSON.parse(source))).catch(() => null);
26069
26554
  if (!journal || !isInside(projectRoot, journal.nativeConfigPath) || !isInside(projectRoot, journal.infoPath) || !isInside(paths.root, journal.configBackupPath) || !isInside(paths.root, journal.infoBackupPath)) {
26070
26555
  throw new Error(`Refusing unsafe or invalid iOS dev journal at ${paths.journal}.`);
26071
26556
  }
@@ -26073,7 +26558,7 @@ var repairAbsoluteIosDevSession = async (projectRoot) => {
26073
26558
  await copyFile4(journal.configBackupPath, journal.nativeConfigPath);
26074
26559
  if (await pathExists5(journal.infoBackupPath))
26075
26560
  await copyFile4(journal.infoBackupPath, journal.infoPath);
26076
- await rm6(paths.root, { force: true, recursive: true });
26561
+ await rm7(paths.root, { force: true, recursive: true });
26077
26562
  return true;
26078
26563
  };
26079
26564
  var iosDevelopmentInfoPlist = (source, cleartext) => {
@@ -26099,16 +26584,16 @@ var iosDevelopmentInfoPlist = (source, cleartext) => {
26099
26584
  var writeDevProjection = async (project, port, https, serverHost = "localhost") => {
26100
26585
  const paths = journalPaths(project.projectRoot);
26101
26586
  await repairAbsoluteIosDevSession(project.projectRoot);
26102
- const nativeConfigPath = join8(project.nativeDirectory, "App", "App", "capacitor.config.json");
26103
- const infoPath = join8(project.nativeDirectory, "App", "App", "Info.plist");
26587
+ const nativeConfigPath = join9(project.nativeDirectory, "App", "App", "capacitor.config.json");
26588
+ const infoPath = join9(project.nativeDirectory, "App", "App", "Info.plist");
26104
26589
  const [configSource, infoSource] = await Promise.all([
26105
- readFile9(nativeConfigPath, "utf8"),
26106
- readFile9(infoPath, "utf8")
26590
+ readFile10(nativeConfigPath, "utf8"),
26591
+ readFile10(infoPath, "utf8")
26107
26592
  ]);
26108
26593
  const parsed = JSON.parse(configSource);
26109
26594
  if (!isRecord4(parsed))
26110
26595
  throw new Error(`Invalid Capacitor native config at ${nativeConfigPath}.`);
26111
- await mkdir6(paths.root, { recursive: true });
26596
+ await mkdir7(paths.root, { recursive: true });
26112
26597
  await Promise.all([
26113
26598
  writeFile7(paths.configBackup, configSource, { flag: "wx" }),
26114
26599
  writeFile7(paths.infoBackup, infoSource, { flag: "wx" })
@@ -26155,11 +26640,11 @@ var parseNativeCache = (value) => {
26155
26640
  ]))
26156
26641
  };
26157
26642
  };
26158
- var readNativeCache = (projectRoot) => readFile9(nativeCachePath(projectRoot), "utf8").then((source) => parseNativeCache(JSON.parse(source))).catch(() => null);
26643
+ var readNativeCache = (projectRoot) => readFile10(nativeCachePath(projectRoot), "utf8").then((source) => parseNativeCache(JSON.parse(source))).catch(() => null);
26159
26644
  var writeNativeCache = async (projectRoot, cache) => {
26160
26645
  const destination = nativeCachePath(projectRoot);
26161
26646
  const temporary = `${destination}.${process.pid}.${randomUUID3()}.tmp`;
26162
- await mkdir6(dirname5(destination), { recursive: true });
26647
+ await mkdir7(dirname6(destination), { recursive: true });
26163
26648
  try {
26164
26649
  await writeFile7(temporary, `${JSON.stringify(cache, null, "\t")}
26165
26650
  `, {
@@ -26167,7 +26652,7 @@ var writeNativeCache = async (projectRoot, cache) => {
26167
26652
  });
26168
26653
  await rename7(temporary, destination);
26169
26654
  } finally {
26170
- await rm6(temporary, { force: true }).catch(() => {
26655
+ await rm7(temporary, { force: true }).catch(() => {
26171
26656
  return;
26172
26657
  });
26173
26658
  }
@@ -26273,12 +26758,12 @@ var physicalIosAppIsInstalled = (project, identifier, capture) => {
26273
26758
  return result.exitCode === 0 && result.stdout.includes(project.config.appId);
26274
26759
  };
26275
26760
  var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
26276
- const derivedDataPath = join8(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash7("sha256").update(project.config.appId).digest("hex").slice(0, 16));
26277
- await mkdir6(derivedDataPath, { recursive: true });
26278
- await requireSuccess3([
26761
+ const derivedDataPath = join9(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash8("sha256").update(project.config.appId).digest("hex").slice(0, 16));
26762
+ await mkdir7(derivedDataPath, { recursive: true });
26763
+ await requireSuccess4([
26279
26764
  project.xcodebuild,
26280
26765
  "-workspace",
26281
- join8(project.nativeDirectory, "App", "App.xcworkspace"),
26766
+ join9(project.nativeDirectory, "App", "App.xcworkspace"),
26282
26767
  "-scheme",
26283
26768
  "App",
26284
26769
  "-configuration",
@@ -26289,18 +26774,18 @@ var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
26289
26774
  derivedDataPath,
26290
26775
  "build"
26291
26776
  ], "iOS simulator build", run, { cwd: project.nativeDirectory, signal });
26292
- const appPath = join8(derivedDataPath, "Build", "Products", "Debug-iphonesimulator", "App.app");
26777
+ const appPath = join9(derivedDataPath, "Build", "Products", "Debug-iphonesimulator", "App.app");
26293
26778
  if (!await pathExists5(appPath))
26294
26779
  throw new Error(`Xcode did not produce the simulator app at ${appPath}.`);
26295
26780
  return appPath;
26296
26781
  };
26297
26782
  var buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
26298
- const derivedDataPath = join8(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash7("sha256").update(project.config.appId).digest("hex").slice(0, 16));
26299
- await mkdir6(derivedDataPath, { recursive: true });
26300
- await requireSuccess3([
26783
+ const derivedDataPath = join9(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash8("sha256").update(project.config.appId).digest("hex").slice(0, 16));
26784
+ await mkdir7(derivedDataPath, { recursive: true });
26785
+ await requireSuccess4([
26301
26786
  project.xcodebuild,
26302
26787
  "-workspace",
26303
- join8(project.nativeDirectory, "App", "App.xcworkspace"),
26788
+ join9(project.nativeDirectory, "App", "App.xcworkspace"),
26304
26789
  "-scheme",
26305
26790
  "App",
26306
26791
  "-configuration",
@@ -26312,7 +26797,7 @@ var buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
26312
26797
  "-allowProvisioningUpdates",
26313
26798
  "build"
26314
26799
  ], "iOS physical-device build (configure automatic signing and a Development Team in Xcode if this is the first run)", run, { cwd: project.nativeDirectory, signal });
26315
- const appPath = join8(derivedDataPath, "Build", "Products", "Debug-iphoneos", "App.app");
26800
+ const appPath = join9(derivedDataPath, "Build", "Products", "Debug-iphoneos", "App.app");
26316
26801
  if (!await pathExists5(appPath))
26317
26802
  throw new Error(`Xcode did not produce the physical-device app at ${appPath}.`);
26318
26803
  return appPath;
@@ -26328,7 +26813,7 @@ var ensurePhysicalIosDebugApp = async (options) => {
26328
26813
  const appPath = await buildPhysicalIosDebugApp(options.project, options.identifier, options.run, options.signal);
26329
26814
  throwIfAborted2(options.signal);
26330
26815
  options.transition("installing");
26331
- await requireSuccess3([
26816
+ await requireSuccess4([
26332
26817
  options.project.xcrun,
26333
26818
  "devicectl",
26334
26819
  "device",
@@ -26361,7 +26846,7 @@ var ensureIosDebugApp = async (options) => {
26361
26846
  const appPath = await buildIosDebugApp(options.project, options.udid, options.fingerprint, options.run, options.signal);
26362
26847
  throwIfAborted2(options.signal);
26363
26848
  options.transition("installing");
26364
- await requireSuccess3([options.project.xcrun, "simctl", "install", options.udid, appPath], "iOS simulator app installation", options.run, { signal: options.signal });
26849
+ await requireSuccess4([options.project.xcrun, "simctl", "install", options.udid, appPath], "iOS simulator app installation", options.run, { signal: options.signal });
26365
26850
  const updated = installedAppIdentity(options.project, options.udid, options.capture);
26366
26851
  if (updated) {
26367
26852
  await writeNativeCache(options.project.projectRoot, {
@@ -26447,7 +26932,7 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
26447
26932
  if (detectAbsoluteMobileHost() !== "macos")
26448
26933
  throw new Error("iOS development requires macOS and Xcode.");
26449
26934
  const target = options.target ?? "simulator";
26450
- const projectRoot = resolve6(options.projectRoot);
26935
+ const projectRoot = resolve7(options.projectRoot);
26451
26936
  const checks = await inspectAbsoluteMobileToolchain({ host: "macos" });
26452
26937
  const failed = checks.filter((check) => check.platform === "ios" && !(target === "device" && check.id === "ios.runtime") && (check.status === "fail" || check.status === "warn"));
26453
26938
  if (failed.length > 0)
@@ -26456,20 +26941,20 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
26456
26941
  const xcodebuild = checks.find((check) => check.id === "ios.xcodebuild")?.path;
26457
26942
  if (!xcrun || !xcodebuild)
26458
26943
  throw new Error("Xcode tools disappeared after readiness checks.");
26459
- const cap = join8(projectRoot, "node_modules", ".bin", "cap");
26944
+ const cap = join9(projectRoot, "node_modules", ".bin", "cap");
26460
26945
  if (!await pathExists5(cap))
26461
26946
  throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
26462
26947
  await writeAbsoluteCapacitorConfig(config, { projectRoot });
26463
- await mkdir6(config.bundleDirectory, { recursive: true });
26464
- const placeholder = join8(config.bundleDirectory, "index.html");
26948
+ await mkdir7(config.bundleDirectory, { recursive: true });
26949
+ const placeholder = join9(config.bundleDirectory, "index.html");
26465
26950
  if (!await pathExists5(placeholder))
26466
26951
  await writeFile7(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
26467
26952
  `);
26468
- const nativeDirectory = join8(config.nativeProjectDirectory, "ios");
26953
+ const nativeDirectory = join9(config.nativeProjectDirectory, "ios");
26469
26954
  if (!await pathExists5(nativeDirectory)) {
26470
26955
  if (!options.createNativeProject)
26471
26956
  throw new Error("iOS native project has not been created.");
26472
- const run = options.run ?? defaultRun3;
26957
+ const run = options.run ?? defaultRun4;
26473
26958
  if (await run([cap, "add", "ios"], { cwd: projectRoot }) !== 0)
26474
26959
  throw new Error("Capacitor iOS project creation failed.");
26475
26960
  }
@@ -26522,7 +27007,7 @@ var prepareIosSimulatorTarget = async (options) => {
26522
27007
  ]);
26523
27008
  options.transition("connecting");
26524
27009
  await waitForBootedSimulator(options.project, device.udid, options.capture, options.sleep, options.startOptions.signal);
26525
- await requireSuccess3([options.project.xcrun, "simctl", "bootstatus", device.udid, "-b"], "iOS simulator boot readiness", options.run, { signal: options.startOptions.signal });
27010
+ await requireSuccess4([options.project.xcrun, "simctl", "bootstatus", device.udid, "-b"], "iOS simulator boot readiness", options.run, { signal: options.startOptions.signal });
26526
27011
  await trustIosSimulatorDevelopmentCa(options.startOptions, device.udid, options.run, options.log);
26527
27012
  return { caEnrollmentServer: null, startedSimulator, udid: device.udid };
26528
27013
  };
@@ -26532,7 +27017,7 @@ var startAbsoluteIosDevSession = async (options) => {
26532
27017
  const targetKind = deviceIdentifier ? "device" : "simulator";
26533
27018
  const serverHost = deviceIdentifier ? normalizeAbsoluteIosDeviceHost(options.serverHost ?? "") : "localhost";
26534
27019
  const capture = options.capture ?? defaultCapture3;
26535
- const run = options.run ?? defaultRun3;
27020
+ const run = options.run ?? defaultRun4;
26536
27021
  const sleep = options.sleep ?? Bun.sleep;
26537
27022
  const spawn2 = options.spawn ?? defaultSpawn;
26538
27023
  const log = options.log ?? console.log;
@@ -26572,13 +27057,13 @@ var startAbsoluteIosDevSession = async (options) => {
26572
27057
  nativeLogs = attachNativeLogs(project, udid, options);
26573
27058
  return;
26574
27059
  }
26575
- await requireSuccess3(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app relaunch", run, { signal: options.signal });
27060
+ await requireSuccess4(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app relaunch", run, { signal: options.signal });
26576
27061
  };
26577
27062
  try {
26578
27063
  await repairAbsoluteIosDevSession(project.projectRoot);
26579
27064
  throwIfAborted2(options.signal);
26580
27065
  transition("syncing");
26581
- await requireSuccess3([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
27066
+ await requireSuccess4([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
26582
27067
  transition("configuring");
26583
27068
  if (options.embeddedBundle !== true)
26584
27069
  await writeDevProjection(project, options.port, options.https === true, serverHost);
@@ -26644,7 +27129,7 @@ var startAbsoluteIosDevSession = async (options) => {
26644
27129
  nativeLogs = attachNativeLogs(project, udid, options);
26645
27130
  transition("launching");
26646
27131
  if (!deviceIdentifier || !nativeLogs)
26647
- await requireSuccess3(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app launch", run, { signal: options.signal });
27132
+ await requireSuccess4(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app launch", run, { signal: options.signal });
26648
27133
  transition("ready");
26649
27134
  timings.total = performance.now() - startedAt;
26650
27135
  log(options.embeddedBundle === true ? `iOS ${targetKind} connected with the embedded bundle and backend on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).` : `iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
@@ -26693,11 +27178,11 @@ var startAbsoluteIosDevSession = async (options) => {
26693
27178
  screenshot: async (destination) => {
26694
27179
  if (deviceIdentifier)
26695
27180
  throw new Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");
26696
- const resolved = resolve6(project.projectRoot, destination);
27181
+ const resolved = resolve7(project.projectRoot, destination);
26697
27182
  if (!isInside(project.projectRoot, resolved))
26698
27183
  throw new Error("iOS screenshot destination must remain inside the project.");
26699
- await mkdir6(dirname5(resolved), { recursive: true });
26700
- await requireSuccess3([
27184
+ await mkdir7(dirname6(resolved), { recursive: true });
27185
+ await requireSuccess4([
26701
27186
  project.xcrun,
26702
27187
  "simctl",
26703
27188
  "io",
@@ -26723,7 +27208,7 @@ var startAbsoluteIosDevSession = async (options) => {
26723
27208
  };
26724
27209
  // src/mobile/iosNativeWatcher.ts
26725
27210
  import { watch } from "fs";
26726
- import { basename as basename2 } from "path";
27211
+ import { basename as basename3 } from "path";
26727
27212
  var NATIVE_CHANGE_DEBOUNCE_MS = 500;
26728
27213
  var ROOT_NATIVE_INPUTS = new Set([
26729
27214
  "absolute.config.js",
@@ -26813,28 +27298,28 @@ var createAbsoluteIosNativeWatcher = async (options) => {
26813
27298
  options.signal?.addEventListener("abort", close, { once: true });
26814
27299
  return { close };
26815
27300
  };
26816
- var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename2(path));
27301
+ var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename3(path));
26817
27302
  // src/mobile/remoteMacProtocol.ts
26818
- import { createHash as createHash8, randomUUID as randomUUID4 } from "crypto";
27303
+ import { createHash as createHash9, randomUUID as randomUUID4 } from "crypto";
26819
27304
  import {
26820
27305
  chmod,
26821
- mkdir as mkdir7,
26822
- mkdtemp as mkdtemp5,
26823
- readFile as readFile10,
27306
+ mkdir as mkdir8,
27307
+ mkdtemp as mkdtemp6,
27308
+ readFile as readFile11,
26824
27309
  rename as rename8,
26825
- rm as rm7,
27310
+ rm as rm8,
26826
27311
  writeFile as writeFile8
26827
27312
  } from "fs/promises";
26828
27313
  import { homedir as homedir3 } from "os";
26829
27314
  import { isIP as isIP3 } from "net";
26830
27315
  import {
26831
- dirname as dirname6,
26832
- isAbsolute as isAbsolute6,
26833
- join as join9,
27316
+ dirname as dirname7,
27317
+ isAbsolute as isAbsolute7,
27318
+ join as join10,
26834
27319
  posix,
26835
- relative as relative7,
27320
+ relative as relative8,
26836
27321
  resolve as resolvePath3,
26837
- sep as sep6
27322
+ sep as sep7
26838
27323
  } from "path";
26839
27324
 
26840
27325
  // src/mobile/remoteMacWire.ts
@@ -26849,14 +27334,14 @@ var REMOTE_RELEASE_LEASE_HEARTBEAT_MS = 15000;
26849
27334
  var REMOTE_RELEASE_LEASE_STALE_SECONDS = 120;
26850
27335
  var PROFILE_NAME = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/u;
26851
27336
  var SSH_DESTINATION = /^(?:[A-Za-z0-9._-]+@)?[A-Za-z0-9._:-]+$/u;
26852
- var defaultProfilePath = () => join9(homedir3(), ".absolutejs", "mobile", "remote-macs.json");
27337
+ var defaultProfilePath = () => join10(homedir3(), ".absolutejs", "mobile", "remote-macs.json");
26853
27338
  var emptyStore = () => ({
26854
27339
  format: PROFILE_FORMAT,
26855
27340
  profiles: {}
26856
27341
  });
26857
27342
  var loadStore = async (path = defaultProfilePath()) => {
26858
27343
  try {
26859
- const parsed = JSON.parse(await readFile10(path, "utf8"));
27344
+ const parsed = JSON.parse(await readFile11(path, "utf8"));
26860
27345
  if (parsed.format !== PROFILE_FORMAT || typeof parsed.profiles !== "object" || parsed.profiles === null || Array.isArray(parsed.profiles))
26861
27346
  throw new Error("Unsupported remote Mac profile format.");
26862
27347
  for (const [key, profile] of Object.entries(parsed.profiles)) {
@@ -26873,7 +27358,7 @@ var loadStore = async (path = defaultProfilePath()) => {
26873
27358
  }
26874
27359
  };
26875
27360
  var saveStore = async (store, path = defaultProfilePath()) => {
26876
- await mkdir7(dirname6(path), { recursive: true });
27361
+ await mkdir8(dirname7(path), { recursive: true });
26877
27362
  const temporary = `${path}.${randomUUID4()}.tmp`;
26878
27363
  await writeFile8(temporary, `${JSON.stringify(store, null, 2)}
26879
27364
  `, {
@@ -27047,16 +27532,16 @@ var removeAbsoluteRemoteMacProfile = async (name, profilePath) => {
27047
27532
  await saveStore(store, profilePath);
27048
27533
  return true;
27049
27534
  };
27050
- var projectIdentity = (projectRoot, appId) => createHash8("sha256").update(`${resolvePath3(projectRoot)}\x00${appId}`).digest("hex").slice(0, 20);
27535
+ var projectIdentity = (projectRoot, appId) => createHash9("sha256").update(`${resolvePath3(projectRoot)}\x00${appId}`).digest("hex").slice(0, 20);
27051
27536
  var createAbsoluteRemoteExpoIosDevProject = (config, projectRoot, profile) => {
27052
27537
  if (config.engine !== "expo")
27053
27538
  throw new TypeError("Remote Expo execution requires mobile.engine: expo.");
27054
27539
  return createAbsoluteRemoteIosDevProject(config, projectRoot, profile);
27055
27540
  };
27056
27541
  var createAbsoluteRemoteIosDevProject = (config, projectRoot, profile) => ({
27057
- cap: join9(resolvePath3(projectRoot), "node_modules", ".bin", "cap"),
27542
+ cap: join10(resolvePath3(projectRoot), "node_modules", ".bin", "cap"),
27058
27543
  config,
27059
- nativeDirectory: join9(config.nativeProjectDirectory, "ios"),
27544
+ nativeDirectory: join10(config.nativeProjectDirectory, "ios"),
27060
27545
  profile,
27061
27546
  projectRoot: resolvePath3(projectRoot),
27062
27547
  remote: true,
@@ -27213,8 +27698,8 @@ var installAbsoluteRemoteMacAgent = async (project) => {
27213
27698
  };
27214
27699
  var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
27215
27700
  const shippedCandidates = [
27216
- join9(import.meta.dir, "remoteMacAgentEntry.js"),
27217
- join9(import.meta.dir, "..", "mobile", "remoteMacAgentEntry.js")
27701
+ join10(import.meta.dir, "remoteMacAgentEntry.js"),
27702
+ join10(import.meta.dir, "..", "mobile", "remoteMacAgentEntry.js")
27218
27703
  ];
27219
27704
  let path;
27220
27705
  for (const candidate of shippedCandidates) {
@@ -27225,14 +27710,14 @@ var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
27225
27710
  }
27226
27711
  if (!path) {
27227
27712
  const sourceCandidates = [
27228
- join9(import.meta.dir, "remoteMacAgentEntry.ts"),
27229
- join9(import.meta.dir, "..", "..", "src", "mobile", "remoteMacAgentEntry.ts")
27713
+ join10(import.meta.dir, "remoteMacAgentEntry.ts"),
27714
+ join10(import.meta.dir, "..", "..", "src", "mobile", "remoteMacAgentEntry.ts")
27230
27715
  ];
27231
27716
  const source = await sourceCandidates.reduce(async (found, candidate) => await found ?? (await Bun.file(candidate).exists() ? candidate : undefined), Promise.resolve(undefined));
27232
27717
  if (!source)
27233
27718
  throw new Error("The AbsoluteJS installation does not contain its remote Mac agent artifact.");
27234
- const outdir = join9(resolvePath3(projectRoot), ".absolutejs", "mobile", "remote-agent");
27235
- await mkdir7(outdir, { recursive: true });
27719
+ const outdir = join10(resolvePath3(projectRoot), ".absolutejs", "mobile", "remote-agent");
27720
+ await mkdir8(outdir, { recursive: true });
27236
27721
  const result = await Bun.build({
27237
27722
  entrypoints: [source],
27238
27723
  minify: true,
@@ -27241,13 +27726,13 @@ var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
27241
27726
  });
27242
27727
  if (!result.success)
27243
27728
  throw new AggregateError(result.logs, "Failed to build the AbsoluteJS remote Mac agent.");
27244
- path = join9(outdir, "remoteMacAgentEntry.js");
27729
+ path = join10(outdir, "remoteMacAgentEntry.js");
27245
27730
  }
27246
27731
  const bytes = await Bun.file(path).arrayBuffer();
27247
- const sha2562 = createHash8("sha256").update(new Uint8Array(bytes)).digest("hex");
27248
- return { bytes: bytes.byteLength, path, sha256: sha2562 };
27732
+ const sha2563 = createHash9("sha256").update(new Uint8Array(bytes)).digest("hex");
27733
+ return { bytes: bytes.byteLength, path, sha256: sha2563 };
27249
27734
  };
27250
- var portableRelativePath = (root, path) => relative7(root, path).split(sep6).join(posix.sep);
27735
+ var portableRelativePath = (root, path) => relative8(root, path).split(sep7).join(posix.sep);
27251
27736
  var portableMobileConfig = (project) => ({
27252
27737
  appId: project.config.appId,
27253
27738
  appName: project.config.appName,
@@ -27428,9 +27913,9 @@ var writeRemoteArtifact = async (path, stream) => {
27428
27913
  };
27429
27914
  var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory) => {
27430
27915
  const releaseRoot = posix.join(project.remoteProjectRoot, ".absolutejs", "mobile", "releases", "ios", metadata.releaseId);
27431
- const stagingParent = join9(project.projectRoot, ".absolutejs", "mobile");
27432
- await mkdir7(stagingParent, { recursive: true });
27433
- const staging = await mkdtemp5(join9(stagingParent, ".remote-ios-"));
27916
+ const stagingParent = join10(project.projectRoot, ".absolutejs", "mobile");
27917
+ await mkdir8(stagingParent, { recursive: true });
27918
+ const staging = await mkdtemp6(join10(stagingParent, ".remote-ios-"));
27434
27919
  try {
27435
27920
  const remoteMetadata = requireRemoteSuccess(await defaultTransport.capture([
27436
27921
  ...absoluteRemoteMacSshBase(project.profile),
@@ -27440,7 +27925,7 @@ var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory
27440
27925
  const downloadedMetadata = JSON.parse(remoteMetadata);
27441
27926
  if (JSON.stringify(requireAbsoluteIosReleaseMetadata(downloadedMetadata)) !== JSON.stringify(metadata))
27442
27927
  throw new TypeError("Remote iOS release metadata changed during retrieval.");
27443
- const artifactPath = join9(staging, "App.ipa");
27928
+ const artifactPath = join10(staging, "App.ipa");
27444
27929
  const download = Bun.spawn([
27445
27930
  ...absoluteRemoteMacSshBase(project.profile),
27446
27931
  "/bin/sh -lc",
@@ -27460,7 +27945,7 @@ var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory
27460
27945
  projectRoot: project.projectRoot
27461
27946
  });
27462
27947
  } finally {
27463
- await rm7(staging, { force: true, recursive: true }).catch(() => {
27948
+ await rm8(staging, { force: true, recursive: true }).catch(() => {
27464
27949
  return;
27465
27950
  });
27466
27951
  }
@@ -27702,7 +28187,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
27702
28187
  await syncProject(options.project);
27703
28188
  const syncDuration = performance.now() - syncStartedAt;
27704
28189
  const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
27705
- const encodedCertificateAuthority = options.certificateAuthorityPath ? (await readFile10(options.certificateAuthorityPath)).toString("base64url") : undefined;
28190
+ const encodedCertificateAuthority = options.certificateAuthorityPath ? (await readFile11(options.certificateAuthorityPath)).toString("base64url") : undefined;
27706
28191
  const physicalDevice = options.deviceIdentifier !== undefined;
27707
28192
  const expo = options.project.config.engine === "expo";
27708
28193
  if (expo && options.metroPort === undefined)
@@ -27769,8 +28254,8 @@ var startAbsoluteRemoteDevSession = async (options) => {
27769
28254
  const pending = new Map;
27770
28255
  let resolveReady;
27771
28256
  let rejectReady;
27772
- const readyPromise = new Promise((resolve7, reject) => {
27773
- resolveReady = resolve7;
28257
+ const readyPromise = new Promise((resolve8, reject) => {
28258
+ resolveReady = resolve8;
27774
28259
  rejectReady = reject;
27775
28260
  });
27776
28261
  const handleEvent = (event) => {
@@ -27873,7 +28358,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
27873
28358
  options.log?.(`Remote Mac connected (${options.project.profile.name}); agent ${agent.uploaded ? "uploaded" : "cache hit"}, project synced, and ${expo ? "Expo " : ""}iOS ready in ${totalDuration.toFixed(2)}ms.`);
27874
28359
  const request = (commandName) => {
27875
28360
  const id = randomUUID4();
27876
- const response = new Promise((resolve7, reject) => pending.set(id, { reject, resolve: resolve7 }));
28361
+ const response = new Promise((resolve8, reject) => pending.set(id, { reject, resolve: resolve8 }));
27877
28362
  process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
27878
28363
  `);
27879
28364
  const flush = async () => {
@@ -27893,7 +28378,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
27893
28378
  if (closed)
27894
28379
  return;
27895
28380
  closed = true;
27896
- const timeout = () => new Promise((resolve7) => setTimeout(() => resolve7("timeout"), REMOTE_SESSION_CLOSE_TIMEOUT_MS));
28381
+ const timeout = () => new Promise((resolve8) => setTimeout(() => resolve8("timeout"), REMOTE_SESSION_CLOSE_TIMEOUT_MS));
27897
28382
  const id = randomUUID4();
27898
28383
  process2.stdin.write(`${JSON.stringify({ command: "close", id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
27899
28384
  `);
@@ -27940,10 +28425,10 @@ var startAbsoluteRemoteDevSession = async (options) => {
27940
28425
  screenshot: async (destination) => {
27941
28426
  const result = await request("screenshot");
27942
28427
  const target = resolvePath3(options.project.projectRoot, destination);
27943
- const targetRelative = relative7(options.project.projectRoot, target);
27944
- if (targetRelative.startsWith("..") || isAbsolute6(targetRelative))
28428
+ const targetRelative = relative8(options.project.projectRoot, target);
28429
+ if (targetRelative.startsWith("..") || isAbsolute7(targetRelative))
27945
28430
  throw new Error("iOS screenshot must remain inside the project.");
27946
- await mkdir7(dirname6(target), { recursive: true });
28431
+ await mkdir8(dirname7(target), { recursive: true });
27947
28432
  await writeFile8(target, Buffer.from(result.data, "base64"));
27948
28433
  return target;
27949
28434
  },
@@ -27971,20 +28456,20 @@ var absoluteIosDeviceAcceptanceCommands = (options) => {
27971
28456
  ]
27972
28457
  };
27973
28458
  };
27974
- var requireSuccess4 = (result, message) => {
28459
+ var requireSuccess5 = (result, message) => {
27975
28460
  if (result.exitCode !== 0)
27976
28461
  throw new Error(message);
27977
28462
  return result;
27978
28463
  };
27979
28464
  var testAbsoluteIosPhysicalDevice = async (options) => {
27980
28465
  const commands = absoluteIosDeviceAcceptanceCommands(options);
27981
- requireSuccess4(await options.capture(commands.details), "The selected physical iOS device is unavailable. Pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode.");
27982
- const apps = requireSuccess4(await options.capture(commands.apps), "AbsoluteJS could not inspect installed apps on the physical iOS device.");
28466
+ requireSuccess5(await options.capture(commands.details), "The selected physical iOS device is unavailable. Pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode.");
28467
+ const apps = requireSuccess5(await options.capture(commands.apps), "AbsoluteJS could not inspect installed apps on the physical iOS device.");
27983
28468
  if (!apps.stdout.includes(options.appId))
27984
28469
  throw new Error("The AbsoluteJS app is not installed on the selected physical iOS device. Start bun dev with the same --ios-device value first.");
27985
28470
  const now = options.now ?? performance.now.bind(performance);
27986
28471
  const startedAt = now();
27987
- requireSuccess4(await options.capture(commands.launch), "AbsoluteJS could not relaunch the app on the physical iOS device.");
28472
+ requireSuccess5(await options.capture(commands.launch), "AbsoluteJS could not relaunch the app on the physical iOS device.");
27988
28473
  await options.waitForHmr();
27989
28474
  return {
27990
28475
  hmrConnected: true,
@@ -28024,32 +28509,32 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
28024
28509
  };
28025
28510
  };
28026
28511
  // src/mobile/buildPipeline.ts
28027
- import { readFile as readFile16 } from "fs/promises";
28028
- import { join as join19, resolve as resolve14 } from "path";
28512
+ import { readFile as readFile17 } from "fs/promises";
28513
+ import { join as join20, resolve as resolve15 } from "path";
28029
28514
  import { pathToFileURL as pathToFileURL2 } from "url";
28030
28515
 
28031
28516
  // src/mobile/buildRelease.ts
28032
- import { createHash as createHash10 } from "crypto";
28033
- import { mkdir as mkdir9, readFile as readFile12, writeFile as writeFile10 } from "fs/promises";
28034
- import { basename as basename3, dirname as dirname7, extname, join as join10, relative as relative8, resolve as resolve9 } from "path";
28517
+ import { createHash as createHash11 } from "crypto";
28518
+ import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile10 } from "fs/promises";
28519
+ import { basename as basename4, dirname as dirname8, extname, join as join11, relative as relative9, resolve as resolve10 } from "path";
28035
28520
  init_releaseArtifact();
28036
- var sha2562 = (bytes) => createHash10("sha256").update(bytes).digest("hex");
28521
+ var sha2563 = (bytes) => createHash11("sha256").update(bytes).digest("hex");
28037
28522
  var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
28038
28523
  var rewriteStaticScriptPaths = (source, manifest) => source.replace(STATIC_SCRIPT_PATTERN, (match, prefix, path, suffix) => {
28039
28524
  if (path.endsWith("/htmx.min.js"))
28040
28525
  return match;
28041
- const key = toPascal(basename3(path, extname(path)));
28526
+ const key = toPascal(basename4(path, extname(path)));
28042
28527
  const builtPath = manifest[key];
28043
28528
  return builtPath ? `${prefix}${builtPath}${suffix}` : match;
28044
28529
  });
28045
28530
  var readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]);
28046
28531
  var resolveAssetPath = (buildDirectory, assetPath) => {
28047
- const resolvedBuildDirectory = resolve9(buildDirectory);
28048
- const resolvedAsset = resolve9(assetPath);
28532
+ const resolvedBuildDirectory = resolve10(buildDirectory);
28533
+ const resolvedAsset = resolve10(assetPath);
28049
28534
  if (resolvedAsset.startsWith(`${resolvedBuildDirectory}/`)) {
28050
28535
  return resolvedAsset;
28051
28536
  }
28052
- return join10(buildDirectory, assetPath.replace(/^\/+/, ""));
28537
+ return join11(buildDirectory, assetPath.replace(/^\/+/, ""));
28053
28538
  };
28054
28539
  var pageFor = async (metadata, manifest, buildDirectory) => {
28055
28540
  const assetPath = manifest[metadata.bundleKey];
@@ -28058,11 +28543,11 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
28058
28543
  }
28059
28544
  let resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
28060
28545
  if (metadata.framework === "html" || metadata.framework === "htmx") {
28061
- const source = await readFile12(resolvedAssetPath, "utf8");
28546
+ const source = await readFile13(resolvedAssetPath, "utf8");
28062
28547
  const rewritten = rewriteStaticScriptPaths(source, manifest);
28063
- const documentHash = sha2562(new TextEncoder().encode(rewritten));
28064
- resolvedAssetPath = join10(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
28065
- await mkdir9(dirname7(resolvedAssetPath), { recursive: true });
28548
+ const documentHash = sha2563(new TextEncoder().encode(rewritten));
28549
+ resolvedAssetPath = join11(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
28550
+ await mkdir10(dirname8(resolvedAssetPath), { recursive: true });
28066
28551
  await writeFile10(resolvedAssetPath, rewritten);
28067
28552
  }
28068
28553
  const pageAssetKey = metadata.bundleKey.replace(/Index$/u, "");
@@ -28072,20 +28557,20 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
28072
28557
  ].map((key) => manifest[key]).find((path) => typeof path === "string");
28073
28558
  const resolvedStylePath = styleAssetPath ? resolveAssetPath(buildDirectory, styleAssetPath) : undefined;
28074
28559
  const [bytes, styleBytes] = await Promise.all([
28075
- readFile12(resolvedAssetPath),
28076
- resolvedStylePath ? readFile12(resolvedStylePath) : undefined
28560
+ readFile13(resolvedAssetPath),
28561
+ resolvedStylePath ? readFile13(resolvedStylePath) : undefined
28077
28562
  ]);
28078
- const bundlePath = `/${relative8(resolve9(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
28079
- const styleBundlePath = resolvedStylePath ? `/${relative8(resolve9(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
28563
+ const bundlePath = `/${relative9(resolve10(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
28564
+ const styleBundlePath = resolvedStylePath ? `/${relative9(resolve10(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
28080
28565
  return {
28081
- bundleHash: sha2562(bytes),
28566
+ bundleHash: sha2563(bytes),
28082
28567
  bundlePath,
28083
28568
  contract: metadata.contract,
28084
28569
  framework: metadata.framework,
28085
28570
  pageId: metadata.pageId,
28086
28571
  propsSchemaHash: metadata.propsSchemaHash,
28087
28572
  ...styleBytes && styleBundlePath ? {
28088
- styleBundleHash: sha2562(styleBytes),
28573
+ styleBundleHash: sha2563(styleBytes),
28089
28574
  styleBundlePath
28090
28575
  } : {}
28091
28576
  };
@@ -28093,7 +28578,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
28093
28578
  var buildAbsoluteMobileCompatibilityRelease = async (options) => {
28094
28579
  const [captured, producerBytes] = await Promise.all([
28095
28580
  captureAbsoluteMobileRouteGraph(options.app),
28096
- readFile12(options.producerPath)
28581
+ readFile13(options.producerPath)
28097
28582
  ]);
28098
28583
  if (captured.length === 0) {
28099
28584
  throw new TypeError("No instrumented AbsoluteJS mobile page routes were found in the finalized Elysia route graph.");
@@ -28107,8 +28592,8 @@ var buildAbsoluteMobileCompatibilityRelease = async (options) => {
28107
28592
  metadataByPage.set(metadata.pageId, metadata);
28108
28593
  }
28109
28594
  const pages = await Promise.all([...metadataByPage.values()].map((metadata) => pageFor(metadata, options.manifest, options.buildDirectory)));
28110
- const producerHash = sha2562(producerBytes);
28111
- const appBuild = `ambuild_${sha2562(new TextEncoder().encode(JSON.stringify({
28595
+ const producerHash = sha2563(producerBytes);
28596
+ const appBuild = `ambuild_${sha2563(new TextEncoder().encode(JSON.stringify({
28112
28597
  pages: pages.map(({
28113
28598
  bundleHash,
28114
28599
  bundlePath,
@@ -28184,15 +28669,15 @@ init_routeMatcher();
28184
28669
  import {
28185
28670
  cp,
28186
28671
  copyFile as copyFile5,
28187
- mkdir as mkdir10,
28188
- mkdtemp as mkdtemp6,
28189
- readFile as readFile13,
28672
+ mkdir as mkdir11,
28673
+ mkdtemp as mkdtemp7,
28674
+ readFile as readFile14,
28190
28675
  rename as rename10,
28191
- rm as rm9,
28676
+ rm as rm10,
28192
28677
  writeFile as writeFile11
28193
28678
  } from "fs/promises";
28194
28679
  import { existsSync as existsSync2 } from "fs";
28195
- import { basename as basename4, dirname as dirname8, extname as extname2, join as join11, relative as relative9, resolve as resolve10 } from "path";
28680
+ import { basename as basename5, dirname as dirname9, extname as extname2, join as join12, relative as relative10, resolve as resolve11 } from "path";
28196
28681
 
28197
28682
  // src/mobile/client.ts
28198
28683
  init_pageProtocol();
@@ -28403,55 +28888,55 @@ var CAPACITOR_CLIENT_FRAMEWORKS = new Set([
28403
28888
  var CLIENT_ASSET_DIRECTORIES = ["assets", "html", "htmx", "indexes"];
28404
28889
  var errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code;
28405
28890
  var shellBootstrapModule = () => {
28406
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync2);
28891
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync2);
28407
28892
  if (candidate)
28408
28893
  return candidate;
28409
28894
  throw new TypeError("AbsoluteJS mobile shell bootstrap module is missing.");
28410
28895
  };
28411
28896
  var shellAuthModule = () => {
28412
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellAuth.${extension}`)).find(existsSync2);
28897
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellAuth.${extension}`)).find(existsSync2);
28413
28898
  if (candidate)
28414
28899
  return candidate;
28415
28900
  throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
28416
28901
  };
28417
28902
  var shellExpoAuthModule = () => {
28418
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync2);
28903
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync2);
28419
28904
  if (candidate)
28420
28905
  return candidate;
28421
28906
  throw new TypeError("AbsoluteJS Expo auth bridge module is missing.");
28422
28907
  };
28423
28908
  var shellSyncModule = () => {
28424
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellSync.${extension}`)).find(existsSync2);
28909
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellSync.${extension}`)).find(existsSync2);
28425
28910
  if (candidate)
28426
28911
  return candidate;
28427
28912
  throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
28428
28913
  };
28429
28914
  var shellExpoSyncModule = () => {
28430
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellExpoSync.${extension}`)).find(existsSync2);
28915
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellExpoSync.${extension}`)).find(existsSync2);
28431
28916
  if (candidate)
28432
28917
  return candidate;
28433
28918
  throw new TypeError("AbsoluteJS Expo Sync bridge module is missing.");
28434
28919
  };
28435
28920
  var shellPushModule = () => {
28436
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellPush.${extension}`)).find(existsSync2);
28921
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellPush.${extension}`)).find(existsSync2);
28437
28922
  if (candidate)
28438
28923
  return candidate;
28439
28924
  throw new TypeError("AbsoluteJS mobile push shell module is missing.");
28440
28925
  };
28441
28926
  var shellExpoDevicesModule = () => {
28442
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellExpoDevices.${extension}`)).find(existsSync2);
28927
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellExpoDevices.${extension}`)).find(existsSync2);
28443
28928
  if (candidate)
28444
28929
  return candidate;
28445
28930
  throw new TypeError("AbsoluteJS Expo device bridge module is missing.");
28446
28931
  };
28447
28932
  var shellUpdateModule = () => {
28448
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellUpdate.${extension}`)).find(existsSync2);
28933
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellUpdate.${extension}`)).find(existsSync2);
28449
28934
  if (candidate)
28450
28935
  return candidate;
28451
28936
  throw new TypeError("AbsoluteJS mobile update shell module is missing.");
28452
28937
  };
28453
28938
  var shellReleaseReadinessModule = () => {
28454
- const candidate = ["js", "ts"].map((extension) => join11(import.meta.dir, `shellReleaseReadiness.${extension}`)).find(existsSync2);
28939
+ const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellReleaseReadiness.${extension}`)).find(existsSync2);
28455
28940
  if (candidate)
28456
28941
  return candidate;
28457
28942
  throw new TypeError("AbsoluteJS mobile release-readiness module is missing.");
@@ -28486,8 +28971,8 @@ var indexHtml = (appName, productionOrigin) => `<!doctype html>
28486
28971
  </html>
28487
28972
  `;
28488
28973
  var sourceAssetPath = (buildDirectory, bundlePath) => {
28489
- const root = resolve10(buildDirectory);
28490
- const asset = resolve10(root, bundlePath.replace(/^\/+/, ""));
28974
+ const root = resolve11(buildDirectory);
28975
+ const asset = resolve11(root, bundlePath.replace(/^\/+/, ""));
28491
28976
  if (!asset.startsWith(`${root}/`)) {
28492
28977
  throw new TypeError("Mobile page bundle escaped the build directory.");
28493
28978
  }
@@ -28504,15 +28989,15 @@ var resolveProjectImport = async (projectRoot, specifier) => {
28504
28989
  const segments = specifier.split("/");
28505
28990
  const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
28506
28991
  const subpath = specifier.slice(packageName.length);
28507
- const packageDirectory = join11(resolve10(projectRoot), "node_modules", packageName);
28508
- const manifest = JSON.parse(await readFile13(join11(packageDirectory, "package.json"), "utf8"));
28992
+ const packageDirectory = join12(resolve11(projectRoot), "node_modules", packageName);
28993
+ const manifest = JSON.parse(await readFile14(join12(packageDirectory, "package.json"), "utf8"));
28509
28994
  const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
28510
28995
  const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
28511
28996
  const target = importEntryTarget(entry);
28512
28997
  if (typeof target !== "string" || !target.startsWith("./"))
28513
28998
  throw new TypeError(`${specifier} does not publish an import entry.`);
28514
- const resolved = resolve10(packageDirectory, target);
28515
- if (!resolved.startsWith(`${resolve10(packageDirectory)}/`))
28999
+ const resolved = resolve11(packageDirectory, target);
29000
+ if (!resolved.startsWith(`${resolve11(packageDirectory)}/`))
28516
29001
  throw new TypeError(`${specifier} has an unsafe import entry.`);
28517
29002
  return resolved;
28518
29003
  };
@@ -28543,7 +29028,7 @@ var buildShellBootstrap = async (staging, auth, sync, storagePrefix, engine, upd
28543
29028
  const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absoluteMobilePush.capabilityOptions);
28544
29029
  ` : "";
28545
29030
  const capabilityOptions = shellCapabilities.map((name, index) => `${JSON.stringify(name)}: ${name === "pushNotifications" ? "absoluteMobilePushCapability" : `absoluteDeviceCapability${index}()`}`).join(", ");
28546
- const entryPath = join11(staging, ".absolute-mobile-entry.ts");
29031
+ const entryPath = join12(staging, ".absolute-mobile-entry.ts");
28547
29032
  const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
28548
29033
  const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
28549
29034
  const readinessImport = capacitor ? `import { markAbsoluteMobileShellReady } from ${JSON.stringify(shellReleaseReadinessModule())};` : "";
@@ -28579,13 +29064,13 @@ void startAbsoluteMobileShell(${shellOptions})${capacitor ? ".then(markAbsoluteM
28579
29064
  if (!build.success || build.outputs.length !== 1) {
28580
29065
  throw new AggregateError(build.logs, "Failed to build the AbsoluteJS Capacitor shell.");
28581
29066
  }
28582
- await rename10(build.outputs[0]?.path ?? "", join11(staging, BOOTSTRAP_FILE));
28583
- await rm9(entryPath, { force: true });
29067
+ await rename10(build.outputs[0]?.path ?? "", join12(staging, BOOTSTRAP_FILE));
29068
+ await rm10(entryPath, { force: true });
28584
29069
  };
28585
29070
  var removePreviousBundle = async (backup, moved) => {
28586
29071
  if (!moved)
28587
29072
  return;
28588
- await rm9(backup, { force: true, recursive: true });
29073
+ await rm10(backup, { force: true, recursive: true });
28589
29074
  };
28590
29075
  var restorePreviousBundle = async (backup, destination, moved) => {
28591
29076
  if (!moved)
@@ -28617,17 +29102,17 @@ var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) =
28617
29102
  const extension = extname2(page.bundlePath) || ".js";
28618
29103
  const localBundlePath = `./pages/${page.bundleHash}${extension}`;
28619
29104
  const source = sourceAssetPath(buildDirectory, page.bundlePath);
28620
- await copyFile5(source, join11(staging, localBundlePath));
29105
+ await copyFile5(source, join12(staging, localBundlePath));
28621
29106
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copiedDependencies);
28622
29107
  let localStylePath;
28623
29108
  if (page.styleBundlePath && page.styleBundleHash) {
28624
29109
  const styleExtension = extname2(page.styleBundlePath) || ".css";
28625
29110
  localStylePath = `./styles/${page.styleBundleHash}${styleExtension}`;
28626
29111
  const styleSource = sourceAssetPath(buildDirectory, page.styleBundlePath);
28627
- await mkdir10(dirname8(join11(staging, localStylePath)), {
29112
+ await mkdir11(dirname9(join12(staging, localStylePath)), {
28628
29113
  recursive: true
28629
29114
  });
28630
- await copyFile5(styleSource, join11(staging, localStylePath));
29115
+ await copyFile5(styleSource, join12(staging, localStylePath));
28631
29116
  await copyAbsoluteClientDependencies(styleSource, buildDirectory, staging, copiedDependencies);
28632
29117
  }
28633
29118
  return {
@@ -28643,26 +29128,26 @@ var materializeAbsoluteMobileSourcemaps = async (pages, appBuild, projectRoot) =
28643
29128
  return value;
28644
29129
  };
28645
29130
  const release = safeLeaf(appBuild, "Mobile app build");
28646
- const privateRoot = join11(projectRoot, "sourcemaps");
28647
- const releaseRoot = join11(privateRoot, "mobile", release);
29131
+ const privateRoot = join12(projectRoot, "sourcemaps");
29132
+ const releaseRoot = join12(privateRoot, "mobile", release);
28648
29133
  const copied = [];
28649
29134
  const available = pages.flatMap((page) => {
28650
- const source = join11(privateRoot, `${basename4(page.bundlePath)}.map`);
29135
+ const source = join12(privateRoot, `${basename5(page.bundlePath)}.map`);
28651
29136
  return existsSync2(source) ? [{ page, source }] : [];
28652
29137
  });
28653
29138
  if (available.length > 0)
28654
- await mkdir10(releaseRoot, { recursive: true });
29139
+ await mkdir11(releaseRoot, { recursive: true });
28655
29140
  await Promise.all(available.map(async ({ page, source }) => {
28656
29141
  const extension = extname2(page.bundlePath) || ".js";
28657
29142
  if (!/^\.[a-z0-9]+$/iu.test(extension))
28658
29143
  throw new TypeError("Mobile page extension is not a safe source-map key.");
28659
29144
  const bundleHash = safeLeaf(page.bundleHash, "Mobile page bundle hash");
28660
29145
  const file = `${bundleHash}${extension}.map`;
28661
- await copyFile5(source, join11(releaseRoot, file));
29146
+ await copyFile5(source, join12(releaseRoot, file));
28662
29147
  copied.push({ bundleHash, file, pageId: page.pageId });
28663
29148
  }));
28664
29149
  if (copied.length > 0) {
28665
- await writeFile11(join11(releaseRoot, "manifest.json"), `${JSON.stringify({
29150
+ await writeFile11(join12(releaseRoot, "manifest.json"), `${JSON.stringify({
28666
29151
  appBuild,
28667
29152
  format: 1,
28668
29153
  pages: copied.sort((left, right) => left.pageId.localeCompare(right.pageId))
@@ -28672,7 +29157,7 @@ var materializeAbsoluteMobileSourcemaps = async (pages, appBuild, projectRoot) =
28672
29157
  return copied.length;
28673
29158
  };
28674
29159
  var absoluteClientImports = async (sourcePath, buildDirectory) => {
28675
- const source = await readFile13(sourcePath, "utf8");
29160
+ const source = await readFile14(sourcePath, "utf8");
28676
29161
  const extension = extname2(sourcePath).toLowerCase();
28677
29162
  let scriptLoader;
28678
29163
  if (extension === ".tsx")
@@ -28695,9 +29180,9 @@ var absoluteClientImports = async (sourcePath, buildDirectory) => {
28695
29180
  const clean = specifier.split(/[?#]/u, 1)[0] ?? specifier;
28696
29181
  if (clean.startsWith("/"))
28697
29182
  return [clean];
28698
- const resolved = resolve10(dirname8(sourcePath), clean);
28699
- const root = resolve10(buildDirectory);
28700
- const relativePath = relative9(root, resolved).replaceAll("\\", "/");
29183
+ const resolved = resolve11(dirname9(sourcePath), clean);
29184
+ const root = resolve11(buildDirectory);
29185
+ const relativePath = relative10(root, resolved).replaceAll("\\", "/");
28701
29186
  if (relativePath === ".." || relativePath.startsWith("../")) {
28702
29187
  throw new TypeError(`Mobile client dependency escaped the build directory: ${specifier}`);
28703
29188
  }
@@ -28709,8 +29194,8 @@ var copyAbsoluteClientDependency = async (specifier, buildDirectory, staging, co
28709
29194
  return;
28710
29195
  copied.add(specifier);
28711
29196
  const source = sourceAssetPath(buildDirectory, specifier);
28712
- const destination = join11(staging, specifier.replace(/^\/+/, ""));
28713
- await mkdir10(dirname8(destination), { recursive: true });
29197
+ const destination = join12(staging, specifier.replace(/^\/+/, ""));
29198
+ await mkdir11(dirname9(destination), { recursive: true });
28714
29199
  await copyFile5(source, destination);
28715
29200
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
28716
29201
  };
@@ -28723,14 +29208,14 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
28723
29208
  throw new TypeError(`mobile.entry ${options.config.entry} is not a captured mobile page route.`);
28724
29209
  }
28725
29210
  const destination = options.config.bundleDirectory;
28726
- await mkdir10(dirname8(destination), { recursive: true });
28727
- const staging = await mkdtemp6(join11(dirname8(destination), `.${basename4(destination)}.stage-`));
29211
+ await mkdir11(dirname9(destination), { recursive: true });
29212
+ const staging = await mkdtemp7(join12(dirname9(destination), `.${basename5(destination)}.stage-`));
28728
29213
  try {
28729
- const pageDirectory = join11(staging, "pages");
28730
- await mkdir10(pageDirectory, { recursive: true });
29214
+ const pageDirectory = join12(staging, "pages");
29215
+ await mkdir11(pageDirectory, { recursive: true });
28731
29216
  await Promise.all(CLIENT_ASSET_DIRECTORIES.map((directory) => ({
28732
- destination: join11(staging, directory),
28733
- source: join11(options.buildDirectory, directory)
29217
+ destination: join12(staging, directory),
29218
+ source: join12(options.buildDirectory, directory)
28734
29219
  })).filter(({ source }) => existsSync2(source)).map(({ destination: assetDestination, source }) => cp(source, assetDestination, { recursive: true })));
28735
29220
  const copiedDependencies = new Set;
28736
29221
  const pages = await Promise.all(options.artifact.pages.map((page) => copyClientPage(page, options.buildDirectory, staging, copiedDependencies)));
@@ -28767,16 +29252,16 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
28767
29252
  } : {}
28768
29253
  };
28769
29254
  await Promise.all([
28770
- writeFile11(join11(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
29255
+ writeFile11(join12(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
28771
29256
  `),
28772
- writeFile11(join11(staging, INDEX_FILE), indexHtml(options.config.appName, options.config.productionOrigin)),
29257
+ writeFile11(join12(staging, INDEX_FILE), indexHtml(options.config.appName, options.config.productionOrigin)),
28773
29258
  buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true, `absolutejs.${options.auth?.clientId ?? options.config.appId}.`, options.config.engine, options.config.engine === "capacitor" && options.config.updates !== undefined, options.deviceCapabilities, options.projectRoot)
28774
29259
  ]);
28775
29260
  await installBundle(staging, destination);
28776
29261
  await materializeAbsoluteMobileSourcemaps(options.artifact.pages, options.artifact.appBuild, options.projectRoot);
28777
29262
  return manifest;
28778
29263
  } catch (error) {
28779
- await rm9(staging, { force: true, recursive: true });
29264
+ await rm10(staging, { force: true, recursive: true });
28780
29265
  throw error;
28781
29266
  }
28782
29267
  };
@@ -28793,22 +29278,22 @@ init_nativeAuth();
28793
29278
  init_syncSchema();
28794
29279
  init_deviceCapabilities();
28795
29280
  import {
28796
- access as access11,
28797
- mkdir as mkdir12,
28798
- mkdtemp as mkdtemp8,
28799
- readdir as readdir4,
28800
- readFile as readFile15,
29281
+ access as access12,
29282
+ mkdir as mkdir13,
29283
+ mkdtemp as mkdtemp9,
29284
+ readdir as readdir5,
29285
+ readFile as readFile16,
28801
29286
  rename as rename12,
28802
- rm as rm11,
29287
+ rm as rm12,
28803
29288
  writeFile as writeFile13
28804
29289
  } from "fs/promises";
28805
- import { createHash as createHash13 } from "crypto";
28806
- import { basename as basename5, dirname as dirname11, join as join18, relative as relative11, resolve as resolve13, sep as sep7 } from "path";
29290
+ import { createHash as createHash14 } from "crypto";
29291
+ import { basename as basename6, dirname as dirname12, join as join19, relative as relative12, resolve as resolve14, sep as sep8 } from "path";
28807
29292
 
28808
29293
  // src/mobile/updateRuntime.ts
28809
29294
  init_deviceCapabilities();
28810
29295
  init_nativeAuth();
28811
- import { createHash as createHash12 } from "crypto";
29296
+ import { createHash as createHash13 } from "crypto";
28812
29297
 
28813
29298
  // src/mobile/updateProtocol.ts
28814
29299
  var ABSOLUTE_MOBILE_UPDATE_FORMAT = 1;
@@ -28949,7 +29434,7 @@ var createAbsoluteMobileUpdateRuntimeDescriptor = (options) => ({
28949
29434
  syncSchema: options.syncSchema ?? null,
28950
29435
  updates: options.config.updates ?? null
28951
29436
  });
28952
- var fingerprintAbsoluteMobileUpdateRuntime = (descriptor) => createHash12("sha256").update(canonicalizeAbsoluteMobileUpdate(descriptor)).digest("hex");
29437
+ var fingerprintAbsoluteMobileUpdateRuntime = (descriptor) => createHash13("sha256").update(canonicalizeAbsoluteMobileUpdate(descriptor)).digest("hex");
28953
29438
  var resolveAbsoluteMobileUpdateRuntime = (config, projectRoot) => {
28954
29439
  const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
28955
29440
  const sync = auth !== undefined && projectUsesAbsoluteSync(projectRoot);
@@ -28972,7 +29457,7 @@ var resolveAbsoluteMobileUpdateRuntime = (config, projectRoot) => {
28972
29457
  };
28973
29458
 
28974
29459
  // src/mobile/expoNativeObservability.ts
28975
- import { join as join16 } from "path";
29460
+ import { join as join17 } from "path";
28976
29461
  var HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
28977
29462
  `;
28978
29463
  var XML_HEADER = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
@@ -29414,31 +29899,31 @@ export const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: s
29414
29899
  `;
29415
29900
  var absoluteExpoNativeObservabilityFiles = (project) => new Map([
29416
29901
  [
29417
- join16(project, "modules/absolute-mobile-observability/expo-module.config.json"),
29902
+ join17(project, "modules/absolute-mobile-observability/expo-module.config.json"),
29418
29903
  moduleConfig
29419
29904
  ],
29420
29905
  [
29421
- join16(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservability.podspec"),
29906
+ join17(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservability.podspec"),
29422
29907
  podspec
29423
29908
  ],
29424
29909
  [
29425
- join16(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservabilityModule.swift"),
29910
+ join17(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservabilityModule.swift"),
29426
29911
  iosModule
29427
29912
  ],
29428
29913
  [
29429
- join16(project, "modules/absolute-mobile-observability/android/build.gradle"),
29914
+ join17(project, "modules/absolute-mobile-observability/android/build.gradle"),
29430
29915
  androidBuild
29431
29916
  ],
29432
29917
  [
29433
- join16(project, "modules/absolute-mobile-observability/android/src/main/AndroidManifest.xml"),
29918
+ join17(project, "modules/absolute-mobile-observability/android/src/main/AndroidManifest.xml"),
29434
29919
  androidManifest
29435
29920
  ],
29436
29921
  [
29437
- join16(project, "modules/absolute-mobile-observability/android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"),
29922
+ join17(project, "modules/absolute-mobile-observability/android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"),
29438
29923
  androidModule
29439
29924
  ],
29440
29925
  [
29441
- join16(project, "src/generated/AbsoluteNativeObservability.ts"),
29926
+ join17(project, "src/generated/AbsoluteNativeObservability.ts"),
29442
29927
  expoNativeObservabilityRuntimeSource
29443
29928
  ]
29444
29929
  ]);
@@ -29447,7 +29932,7 @@ var absoluteExpoNativeObservabilityPaths = (project) => [
29447
29932
  ];
29448
29933
 
29449
29934
  // src/mobile/expoActivityResultRecovery.ts
29450
- import { join as join17 } from "path";
29935
+ import { join as join18 } from "path";
29451
29936
  var HEADER2 = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
29452
29937
  `;
29453
29938
  var XML_HEADER2 = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
@@ -29458,9 +29943,59 @@ var moduleConfig2 = `${JSON.stringify({
29458
29943
  "expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryModule"
29459
29944
  ]
29460
29945
  },
29461
- platforms: ["android"]
29946
+ apple: { modules: ["AbsoluteActivityResultRecoveryModule"] },
29947
+ platforms: ["apple", "android"]
29462
29948
  }, null, 2)}
29463
29949
  `;
29950
+ var podspec2 = `${HEADER2}Pod::Spec.new do |s|
29951
+ s.name = 'AbsoluteActivityResultRecovery'
29952
+ s.version = '0.0.1'
29953
+ s.summary = 'AbsoluteJS native runtime readiness bridge'
29954
+ s.description = 'Generated lifecycle and embedded-content readiness bridge for an AbsoluteJS Expo application.'
29955
+ s.author = 'AbsoluteJS'
29956
+ s.homepage = 'https://absolutejs.com'
29957
+ s.platforms = { :ios => '16.4' }
29958
+ s.source = { git: '' }
29959
+ s.static_framework = true
29960
+ s.dependency 'ExpoModulesCore'
29961
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
29962
+ s.source_files = '**/*.{h,m,mm,swift,hpp,cpp}'
29963
+ end
29964
+ `;
29965
+ var iosModule2 = `${HEADER2}import ExpoModulesCore
29966
+
29967
+ public final class AbsoluteActivityResultRecoveryModule: Module {
29968
+ public func definition() -> ModuleDefinition {
29969
+ Name("AbsoluteActivityResultRecovery")
29970
+
29971
+ Function("markApplicationRuntimeReady") { }
29972
+
29973
+ Function("markEmbeddedWebReady") {
29974
+ let info = Bundle.main.infoDictionary ?? [:]
29975
+ let version = info["CFBundleShortVersionString"] as? String ?? "unknown"
29976
+ let build = info["CFBundleVersion"] as? String ?? "unknown"
29977
+ NSLog("AbsoluteJS: Expo embedded web content ready; version=%@; build=%@", version, build)
29978
+ }
29979
+
29980
+ Function("markEmbeddedWebPhase") { (phase: String) in
29981
+ let allowed = [
29982
+ "assets-start", "assets-ready", "assets-root-failed",
29983
+ "assets-directory-failed", "assets-destination-failed",
29984
+ "assets-module-failed", "assets-source-failed",
29985
+ "assets-download-failed", "assets-copy-failed",
29986
+ "assets-read-failed", "assets-write-failed",
29987
+ "assets-finalize-failed", "assets-unexpected-failed",
29988
+ "devices-start", "devices-ready", "devices-failed"
29989
+ ]
29990
+ if allowed.contains(phase) {
29991
+ NSLog("AbsoluteJS: Expo embedded web phase: %@", phase)
29992
+ }
29993
+ }
29994
+
29995
+ Function("takePendingCancellation") { false }
29996
+ }
29997
+ }
29998
+ `;
29464
29999
  var androidBuild2 = `${HEADER2}plugins {
29465
30000
  id 'com.android.library'
29466
30001
  id 'expo-module-gradle-plugin'
@@ -29634,23 +30169,31 @@ export const takeAbsoluteActivityResultCancellation = () =>
29634
30169
  `;
29635
30170
  var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
29636
30171
  [
29637
- join17(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
30172
+ join18(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
29638
30173
  moduleConfig2
29639
30174
  ],
29640
30175
  [
29641
- join17(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
30176
+ join18(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecovery.podspec"),
30177
+ podspec2
30178
+ ],
30179
+ [
30180
+ join18(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecoveryModule.swift"),
30181
+ iosModule2
30182
+ ],
30183
+ [
30184
+ join18(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
29642
30185
  androidBuild2
29643
30186
  ],
29644
30187
  [
29645
- join17(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
30188
+ join18(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
29646
30189
  androidManifest2
29647
30190
  ],
29648
30191
  [
29649
- join17(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
30192
+ join18(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
29650
30193
  androidModule2
29651
30194
  ],
29652
30195
  [
29653
- join17(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
30196
+ join18(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
29654
30197
  runtime
29655
30198
  ]
29656
30199
  ]);
@@ -29660,9 +30203,9 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
29660
30203
  `;
29661
30204
  var EXPO_ASSET_EXTENSION = ".absasset";
29662
30205
  var EXPO_PROJECT_MARKER = ".absolutejs-expo-project";
29663
- var exists4 = async (path) => {
30206
+ var exists5 = async (path) => {
29664
30207
  try {
29665
- await access11(path);
30208
+ await access12(path);
29666
30209
  return true;
29667
30210
  } catch {
29668
30211
  return false;
@@ -29719,7 +30262,7 @@ var expoNativeDataManifest = (value) => {
29719
30262
  };
29720
30263
  };
29721
30264
  var portableRelative2 = (from, destination) => {
29722
- const value = relative11(from, destination).replaceAll("\\", "/");
30265
+ const value = relative12(from, destination).replaceAll("\\", "/");
29723
30266
  return value.startsWith(".") ? value : `./${value}`;
29724
30267
  };
29725
30268
  var routeSegments = (route) => {
@@ -29735,7 +30278,7 @@ var routeSegments = (route) => {
29735
30278
  return segment;
29736
30279
  });
29737
30280
  };
29738
- var routeFile = (project, route) => join18(project, "app", ...routeSegments(route), "index.tsx");
30281
+ var routeFile = (project, route) => join19(project, "app", ...routeSegments(route), "index.tsx");
29739
30282
  var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
29740
30283
  const separator = spec.lastIndexOf("@");
29741
30284
  return [spec.slice(0, separator), spec.slice(separator + 1)];
@@ -30289,7 +30832,7 @@ ${push ? `absoluteExpoAuth.onPrincipalChange(principal => {
30289
30832
  `;
30290
30833
  };
30291
30834
  var authRuntimeSource = (auth, appId) => {
30292
- const storageIdentity = createHash13("sha256").update(appId).digest("hex").slice(0, 24);
30835
+ const storageIdentity = createHash14("sha256").update(appId).digest("hex").slice(0, 24);
30293
30836
  return `${EXPO_GENERATED_HEADER}import { createAbsoluteExpoAuthClient } from '@absolutejs/auth-expo';
30294
30837
  import { createMobileAuthTransport, installAuthClientRuntimeTransport } from '@absolutejs/auth/client/mobile';
30295
30838
 
@@ -30321,7 +30864,7 @@ export const startAbsoluteExpoAuth = () => {
30321
30864
  `;
30322
30865
  };
30323
30866
  var syncRuntimeSource = (config, schema) => {
30324
- const storageIdentity = createHash13("sha256").update(config.appId).digest("hex").slice(0, 24);
30867
+ const storageIdentity = createHash14("sha256").update(config.appId).digest("hex").slice(0, 24);
30325
30868
  const backgroundEndpoint = new URL("/__absolute/sync/background", config.productionOrigin).href;
30326
30869
  const backgroundTask = `${config.appId}.absolutejs.sync`;
30327
30870
  return `${EXPO_GENERATED_HEADER}import { runHeadlessSync } from '@absolutejs/sync/client/headless';
@@ -30980,8 +31523,8 @@ const styles = StyleSheet.create({
30980
31523
  error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
30981
31524
  });
30982
31525
  `;
30983
- var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname11(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
30984
- import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname11(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
31526
+ var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname12(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
31527
+ import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname12(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
30985
31528
 
30986
31529
  export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
30987
31530
  export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
@@ -31023,9 +31566,9 @@ var expoTsConfig = (projectRoot, project, auth, sync) => ({
31023
31566
  extends: "expo/tsconfig.base"
31024
31567
  });
31025
31568
  var writeManagedFile = async (path, source, force) => {
31026
- await mkdir12(dirname11(path), { recursive: true });
31027
- if (await exists4(path)) {
31028
- const current = await readFile15(path, "utf8");
31569
+ await mkdir13(dirname12(path), { recursive: true });
31570
+ if (await exists5(path)) {
31571
+ const current = await readFile16(path, "utf8");
31029
31572
  if (current === source)
31030
31573
  return false;
31031
31574
  if (!force && !current.startsWith(EXPO_GENERATED_HEADER)) {
@@ -31039,26 +31582,26 @@ var writeManagedFile = async (path, source, force) => {
31039
31582
  };
31040
31583
  var pruneManagedFiles = async (paths) => {
31041
31584
  const removed = await Promise.all(paths.map(async (path) => {
31042
- if (!await exists4(path))
31585
+ if (!await exists5(path))
31043
31586
  return false;
31044
- const source = await readFile15(path, "utf8");
31587
+ const source = await readFile16(path, "utf8");
31045
31588
  if (!source.startsWith(EXPO_GENERATED_HEADER) && !path.endsWith("expo-module.config.json"))
31046
31589
  return false;
31047
- await rm11(path, { force: true });
31590
+ await rm12(path, { force: true });
31048
31591
  return true;
31049
31592
  }));
31050
31593
  return removed.filter(Boolean).length;
31051
31594
  };
31052
31595
  var pruneStaleManagedExpoRoutes = async (project, expected) => {
31053
- const appDirectory = join18(project, "app");
31054
- if (!await exists4(appDirectory))
31596
+ const appDirectory = join19(project, "app");
31597
+ if (!await exists5(appDirectory))
31055
31598
  return 0;
31056
31599
  const files = await walkFiles(appDirectory);
31057
31600
  const stale = (await Promise.all(files.map(async (path) => ({
31058
- managed: path.endsWith(".tsx") && (await readFile15(path, "utf8")).startsWith(EXPO_GENERATED_HEADER),
31601
+ managed: path.endsWith(".tsx") && (await readFile16(path, "utf8")).startsWith(EXPO_GENERATED_HEADER),
31059
31602
  path
31060
31603
  })))).filter(({ managed, path }) => managed && !expected.has(path));
31061
- await Promise.all(stale.map(({ path }) => rm11(path, { force: true })));
31604
+ await Promise.all(stale.map(({ path }) => rm12(path, { force: true })));
31062
31605
  return stale.length;
31063
31606
  };
31064
31607
  var jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
@@ -31081,7 +31624,7 @@ export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest | undefined = unde
31081
31624
  var writeAbsoluteExpoProject = async (config, options) => {
31082
31625
  if (config.engine !== "expo")
31083
31626
  throw new TypeError("Expo project generation requires mobile.engine: expo.");
31084
- const projectRoot = resolve13(options.projectRoot);
31627
+ const projectRoot = resolve14(options.projectRoot);
31085
31628
  const project = config.nativeProjectDirectory;
31086
31629
  const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
31087
31630
  const devices = resolveAbsoluteDeviceCapabilityPlan(projectRoot, "expo");
@@ -31090,7 +31633,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
31090
31633
  const runtimeFingerprint = resolveAbsoluteMobileUpdateRuntime(config, projectRoot).fingerprint;
31091
31634
  const routeModules = Object.entries(config.expoNativeRoutes);
31092
31635
  const moduleChecks = await Promise.all(routeModules.map(async ([route, module]) => ({
31093
- exists: await exists4(module),
31636
+ exists: await exists5(module),
31094
31637
  module,
31095
31638
  route
31096
31639
  })));
@@ -31098,20 +31641,20 @@ var writeAbsoluteExpoProject = async (config, options) => {
31098
31641
  if (missing) {
31099
31642
  throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
31100
31643
  }
31101
- const marker = join18(project, EXPO_PROJECT_MARKER);
31102
- if (await exists4(project) && !await exists4(marker)) {
31103
- const entries = await readdir4(project);
31644
+ const marker = join19(project, EXPO_PROJECT_MARKER);
31645
+ if (await exists5(project) && !await exists5(marker)) {
31646
+ const entries = await readdir5(project);
31104
31647
  if (entries.length > 0 && !options.force) {
31105
31648
  throw new TypeError(`Expo project directory ${project} is not AbsoluteJS-managed; rerun with --force only after reviewing it.`);
31106
31649
  }
31107
31650
  }
31108
- await mkdir12(project, { recursive: true });
31651
+ await mkdir13(project, { recursive: true });
31109
31652
  await writeFile13(marker, `format=1
31110
31653
  `);
31111
31654
  const authEnabled = Boolean(auth);
31112
31655
  const files = new Map([
31113
31656
  [
31114
- join18(project, ".gitignore"),
31657
+ join19(project, ".gitignore"),
31115
31658
  `.expo/
31116
31659
  android/
31117
31660
  ios/
@@ -31119,45 +31662,45 @@ node_modules/
31119
31662
  `
31120
31663
  ],
31121
31664
  [
31122
- join18(project, "app.json"),
31665
+ join19(project, "app.json"),
31123
31666
  jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
31124
31667
  ],
31125
- [join18(project, "app.config.js"), expoDynamicAppConfig],
31668
+ [join19(project, "app.config.js"), expoDynamicAppConfig],
31126
31669
  [
31127
- join18(project, "package.json"),
31670
+ join19(project, "package.json"),
31128
31671
  jsonSource(expoPackage(authEnabled, syncEnabled, devices, config.updates !== undefined))
31129
31672
  ],
31130
- [join18(project, "metro.config.js"), metroConfig(projectRoot)],
31673
+ [join19(project, "metro.config.js"), metroConfig(projectRoot)],
31131
31674
  [
31132
- join18(project, "plugins", "withAbsoluteDevelopmentCa.js"),
31675
+ join19(project, "plugins", "withAbsoluteDevelopmentCa.js"),
31133
31676
  expoDevelopmentCaPlugin
31134
31677
  ],
31135
31678
  [
31136
- join18(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
31679
+ join19(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
31137
31680
  expoActivityResultRecoveryPlugin
31138
31681
  ],
31139
31682
  [
31140
- join18(project, "tsconfig.json"),
31683
+ join19(project, "tsconfig.json"),
31141
31684
  jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
31142
31685
  ],
31143
31686
  [
31144
- join18(project, "app", "_layout.tsx"),
31687
+ join19(project, "app", "_layout.tsx"),
31145
31688
  layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
31146
31689
  ],
31147
31690
  [
31148
- join18(project, "app", "__absolute", "native", "index.tsx"),
31691
+ join19(project, "app", "__absolute", "native", "index.tsx"),
31149
31692
  nativeDiagnosticSource
31150
31693
  ],
31151
31694
  [
31152
- join18(project, "src", "generated", "AbsoluteDevices.ts"),
31695
+ join19(project, "src", "generated", "AbsoluteDevices.ts"),
31153
31696
  devicesRuntimeSource(config, devices, authEnabled)
31154
31697
  ],
31155
31698
  [
31156
- join18(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
31699
+ join19(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
31157
31700
  nativeRouteRuntimeSource(authEnabled)
31158
31701
  ],
31159
31702
  [
31160
- join18(project, "src", "generated", "AbsoluteWebHost.tsx"),
31703
+ join19(project, "src", "generated", "AbsoluteWebHost.tsx"),
31161
31704
  webHostSource(config, auth, syncEnabled)
31162
31705
  ]
31163
31706
  ]);
@@ -31168,40 +31711,40 @@ node_modules/
31168
31711
  files.set(path, source);
31169
31712
  }
31170
31713
  if (config.updates) {
31171
- files.set(join18(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
31714
+ files.set(join19(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
31172
31715
  }
31173
31716
  const expoCodeSigning = config.updates?.expoCodeSigning;
31174
31717
  if (expoCodeSigning)
31175
- files.set(join18(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
31718
+ files.set(join19(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
31176
31719
  if (auth) {
31177
- files.set(join18(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
31720
+ files.set(join19(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
31178
31721
  }
31179
31722
  if (syncSchema) {
31180
- files.set(join18(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
31723
+ files.set(join19(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
31181
31724
  }
31182
- const webAssetsPath = join18(project, "src", "generated", "webAssets.ts");
31183
- if (!await exists4(webAssetsPath)) {
31725
+ const webAssetsPath = join19(project, "src", "generated", "webAssets.ts");
31726
+ if (!await exists5(webAssetsPath)) {
31184
31727
  files.set(webAssetsPath, emptyWebAssetsSource);
31185
31728
  }
31186
31729
  if (!config.expoNativeRoutes["/"]) {
31187
- files.set(join18(project, "app", "index.tsx"), webRouteSource);
31730
+ files.set(join19(project, "app", "index.tsx"), webRouteSource);
31188
31731
  }
31189
- files.set(join18(project, "app", "[...absolute].tsx"), catchAllRouteSource);
31190
- const nativeRouteRuntime = join18(project, "src", "generated", "AbsoluteNativeRoute.tsx");
31732
+ files.set(join19(project, "app", "[...absolute].tsx"), catchAllRouteSource);
31733
+ const nativeRouteRuntime = join19(project, "src", "generated", "AbsoluteNativeRoute.tsx");
31191
31734
  for (const [route, module] of routeModules) {
31192
- const wrapper = route === "/" ? join18(project, "app", "index.tsx") : routeFile(project, route);
31735
+ const wrapper = route === "/" ? join19(project, "app", "index.tsx") : routeFile(project, route);
31193
31736
  files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
31194
31737
  }
31195
- const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join18(project, "app")}${sep7}`))));
31738
+ const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join19(project, "app")}${sep8}`))));
31196
31739
  const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
31197
31740
  const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
31198
31741
  const changed = removedRoutes + removedObservability + changes.filter(Boolean).length;
31199
31742
  return { changed, path: project, written: [...files.keys()] };
31200
31743
  };
31201
31744
  var walkFiles = async (root, directory = root) => {
31202
- const entries = await readdir4(directory, { withFileTypes: true });
31745
+ const entries = await readdir5(directory, { withFileTypes: true });
31203
31746
  const nested = await Promise.all(entries.map((entry) => {
31204
- const path = join18(directory, entry.name);
31747
+ const path = join19(directory, entry.name);
31205
31748
  if (entry.isDirectory())
31206
31749
  return walkFiles(root, path);
31207
31750
  if (entry.isFile())
@@ -31227,7 +31770,7 @@ var installStagedDirectory = async (staging, destination) => {
31227
31770
  try {
31228
31771
  await rename12(staging, destination);
31229
31772
  if (moved)
31230
- await rm11(backup, { force: true, recursive: true });
31773
+ await rm12(backup, { force: true, recursive: true });
31231
31774
  } catch (error) {
31232
31775
  if (moved)
31233
31776
  await rename12(backup, destination);
@@ -31305,27 +31848,27 @@ export const materializeAbsoluteWebBundle = async () => {
31305
31848
  var syncAbsoluteExpoWebAssets = async (config) => {
31306
31849
  if (config.engine !== "expo")
31307
31850
  throw new TypeError("Expo asset sync requires mobile.engine: expo.");
31308
- const marker = join18(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
31309
- if (!await exists4(marker)) {
31851
+ const marker = join19(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
31852
+ if (!await exists5(marker)) {
31310
31853
  throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
31311
31854
  }
31312
- const manifestPath = join18(config.bundleDirectory, "absolute-mobile-manifest.json");
31313
- const manifest = JSON.parse(await readFile15(manifestPath, "utf8"));
31855
+ const manifestPath = join19(config.bundleDirectory, "absolute-mobile-manifest.json");
31856
+ const manifest = JSON.parse(await readFile16(manifestPath, "utf8"));
31314
31857
  const nativeDataManifest = expoNativeDataManifest(manifest);
31315
31858
  const { appBuild } = nativeDataManifest;
31316
31859
  const files = await walkFiles(config.bundleDirectory);
31317
- const bundleHash = createHash13("sha256");
31318
- const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile15(file), file })));
31860
+ const bundleHash = createHash14("sha256");
31861
+ const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile16(file), file })));
31319
31862
  filesWithContents.forEach(({ contents, file }) => {
31320
- bundleHash.update(relative11(config.bundleDirectory, file).replaceAll("\\", "/"));
31863
+ bundleHash.update(relative12(config.bundleDirectory, file).replaceAll("\\", "/"));
31321
31864
  bundleHash.update("\x00");
31322
31865
  bundleHash.update(contents);
31323
31866
  bundleHash.update("\x00");
31324
31867
  });
31325
31868
  const bundleId = `amexpo_${bundleHash.digest("hex")}`;
31326
- const destination = join18(config.nativeProjectDirectory, "assets", "absolute");
31327
- await mkdir12(dirname11(destination), { recursive: true });
31328
- const staging = await mkdtemp8(join18(dirname11(destination), `.${basename5(destination)}.stage-`));
31869
+ const destination = join19(config.nativeProjectDirectory, "assets", "absolute");
31870
+ await mkdir13(dirname12(destination), { recursive: true });
31871
+ const staging = await mkdtemp9(join19(dirname12(destination), `.${basename6(destination)}.stage-`));
31329
31872
  let assets;
31330
31873
  let archiveAsset;
31331
31874
  try {
@@ -31334,20 +31877,20 @@ var syncAbsoluteExpoWebAssets = async (config) => {
31334
31877
  const entry = {
31335
31878
  length: contents.byteLength,
31336
31879
  offset,
31337
- path: relative11(config.bundleDirectory, file).replaceAll("\\", "/")
31880
+ path: relative12(config.bundleDirectory, file).replaceAll("\\", "/")
31338
31881
  };
31339
31882
  offset += contents.byteLength;
31340
31883
  return entry;
31341
31884
  });
31342
31885
  const name = `bundle${EXPO_ASSET_EXTENSION}`;
31343
- await writeFile13(join18(staging, name), Buffer.concat(filesWithContents.map(({ contents }) => contents)));
31344
- archiveAsset = portableRelative2(join18(config.nativeProjectDirectory, "src", "generated"), join18(destination, name));
31886
+ await writeFile13(join19(staging, name), Buffer.concat(filesWithContents.map(({ contents }) => contents)));
31887
+ archiveAsset = portableRelative2(join19(config.nativeProjectDirectory, "src", "generated"), join19(destination, name));
31345
31888
  await installStagedDirectory(staging, destination);
31346
31889
  } catch (error) {
31347
- await rm11(staging, { force: true, recursive: true });
31890
+ await rm12(staging, { force: true, recursive: true });
31348
31891
  throw error;
31349
31892
  }
31350
- const generated = join18(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
31893
+ const generated = join19(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
31351
31894
  await writeManagedFile(generated, assetModuleSource(assets, archiveAsset, bundleId, nativeDataManifest), true);
31352
31895
  return { appBuild, assets: assets.length, bundleId, path: destination };
31353
31896
  };
@@ -31386,11 +31929,11 @@ var loadServerApp = async (producerPath) => {
31386
31929
  return { app, exportName };
31387
31930
  };
31388
31931
  var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
31389
- const buildDirectory = resolve14(options.buildDirectory);
31932
+ const buildDirectory = resolve15(options.buildDirectory);
31390
31933
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
31391
- const root = join19(buildDirectory, ".absolutejs", "mobile-compatibility");
31934
+ const root = join20(buildDirectory, ".absolutejs", "mobile-compatibility");
31392
31935
  const [manifestSource, previous] = await Promise.all([
31393
- readFile16(join19(buildDirectory, "manifest.json"), "utf8"),
31936
+ readFile17(join20(buildDirectory, "manifest.json"), "utf8"),
31394
31937
  readAbsoluteMobileMaterializedReleases(root)
31395
31938
  ]);
31396
31939
  const manifest = JSON.parse(manifestSource);
@@ -31403,11 +31946,11 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
31403
31946
  process.env.ABSOLUTE_BUILD_DIR = buildDirectory;
31404
31947
  process.env.ABSOLUTE_COMPILED_RUNTIME = "1";
31405
31948
  if (options.configPath) {
31406
- process.env.ABSOLUTE_CONFIG = resolve14(options.projectRoot, options.configPath);
31949
+ process.env.ABSOLUTE_CONFIG = resolve15(options.projectRoot, options.configPath);
31407
31950
  }
31408
31951
  let loaded;
31409
31952
  try {
31410
- loaded = await loadServerApp(resolve14(options.producerPath));
31953
+ loaded = await loadServerApp(resolve15(options.producerPath));
31411
31954
  } finally {
31412
31955
  restoreEnvironmentVariable("ABSOLUTE_BUILD_DIR", previousBuildDirectory);
31413
31956
  restoreEnvironmentVariable("ABSOLUTE_COMPILED_RUNTIME", previousCompiledRuntime);
@@ -31420,7 +31963,7 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
31420
31963
  manifest,
31421
31964
  previousArtifacts: previous.map(({ artifact }) => artifact),
31422
31965
  producerExport: loaded.exportName,
31423
- producerPath: resolve14(options.producerPath),
31966
+ producerPath: resolve15(options.producerPath),
31424
31967
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
31425
31968
  });
31426
31969
  const {
@@ -31819,21 +32362,21 @@ var parseAbsoluteExpoBridgeMessage = (source) => {
31819
32362
  };
31820
32363
  // src/mobile/expoCodeSigning.ts
31821
32364
  var import_code_signing_certificates = __toESM(require_main(), 1);
31822
- import { access as access12, mkdir as mkdir13, writeFile as writeFile14 } from "fs/promises";
31823
- import { dirname as dirname12, isAbsolute as isAbsolute7, relative as relative12, resolve as resolve15, sep as sep8 } from "path";
31824
- var exists5 = async (path) => access12(path).then(() => true).catch(() => false);
31825
- var inside2 = (root, path) => {
31826
- const location2 = relative12(root, path);
31827
- return location2 === "" || location2 !== ".." && !location2.startsWith(`..${sep8}`) && !isAbsolute7(location2);
32365
+ import { access as access13, mkdir as mkdir14, writeFile as writeFile14 } from "fs/promises";
32366
+ import { dirname as dirname13, isAbsolute as isAbsolute8, relative as relative13, resolve as resolve16, sep as sep9 } from "path";
32367
+ var exists6 = async (path) => access13(path).then(() => true).catch(() => false);
32368
+ var inside3 = (root, path) => {
32369
+ const location2 = relative13(root, path);
32370
+ return location2 === "" || location2 !== ".." && !location2.startsWith(`..${sep9}`) && !isAbsolute8(location2);
31828
32371
  };
31829
32372
  var generateAbsoluteExpoCodeSigning = async (options) => {
31830
- const root = resolve15(options.projectRoot);
31831
- const certificatePath = resolve15(root, options.certificatePath);
31832
- const privateKeyPath = resolve15(root, options.privateKeyPath);
31833
- const publicKeyPath = resolve15(root, options.publicKeyPath ?? resolve15(dirname12(privateKeyPath), "public-key.pem"));
31834
- if (!inside2(root, certificatePath))
32373
+ const root = resolve16(options.projectRoot);
32374
+ const certificatePath = resolve16(root, options.certificatePath);
32375
+ const privateKeyPath = resolve16(root, options.privateKeyPath);
32376
+ const publicKeyPath = resolve16(root, options.publicKeyPath ?? resolve16(dirname13(privateKeyPath), "public-key.pem"));
32377
+ if (!inside3(root, certificatePath))
31835
32378
  throw new TypeError("Expo code-signing certificate must be written inside the project so store builds can embed it.");
31836
- if (inside2(root, privateKeyPath) || inside2(root, publicKeyPath))
32379
+ if (inside3(root, privateKeyPath) || inside3(root, publicKeyPath))
31837
32380
  throw new TypeError("Expo code-signing private/public key output must remain outside the project and source control.");
31838
32381
  const commonName = options.commonName.trim();
31839
32382
  if (!commonName || commonName.length > 64)
@@ -31842,7 +32385,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
31842
32385
  if (!Number.isSafeInteger(validityYears) || validityYears < 1 || validityYears > 20)
31843
32386
  throw new TypeError("Expo code-signing validity must be an integer from 1 through 20 years.");
31844
32387
  const collisions = (await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map(async (path) => ({
31845
- exists: await exists5(path),
32388
+ exists: await exists6(path),
31846
32389
  path
31847
32390
  })))).filter((entry) => entry.exists);
31848
32391
  if (collisions.length > 0)
@@ -31860,7 +32403,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
31860
32403
  import_code_signing_certificates.validateSelfSignedCertificate(certificate, keyPair);
31861
32404
  const { privateKeyPEM, publicKeyPEM } = import_code_signing_certificates.convertKeyPairToPEM(keyPair);
31862
32405
  const certificatePem = import_code_signing_certificates.convertCertificateToCertificatePEM(certificate);
31863
- await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map((path) => mkdir13(dirname12(path), { recursive: true })));
32406
+ await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map((path) => mkdir14(dirname13(path), { recursive: true })));
31864
32407
  await Promise.all([
31865
32408
  writeFile14(certificatePath, certificatePem, { flag: "wx", mode: 420 }),
31866
32409
  writeFile14(privateKeyPath, privateKeyPEM, { flag: "wx", mode: 384 }),
@@ -31966,9 +32509,9 @@ var parseAbsoluteAndroidAccessibilityHierarchy = (source) => [...source.matchAll
31966
32509
  });
31967
32510
  // src/mobile/expoNativeWatcher.ts
31968
32511
  import { watch as watch2 } from "fs";
31969
- import { access as access13, readdir as readdir5, readFile as readFile17 } from "fs/promises";
31970
- import { basename as basename6, join as join20, relative as relative13 } from "path";
31971
- import { createHash as createHash14 } from "crypto";
32512
+ import { access as access14, readdir as readdir6, readFile as readFile18 } from "fs/promises";
32513
+ import { basename as basename7, join as join21, relative as relative14 } from "path";
32514
+ import { createHash as createHash15 } from "crypto";
31972
32515
  var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
31973
32516
  var ROOT_NATIVE_INPUTS2 = new Set([
31974
32517
  "absolute.config.js",
@@ -31982,13 +32525,13 @@ var ROOT_NATIVE_INPUTS2 = new Set([
31982
32525
  "package.json"
31983
32526
  ]);
31984
32527
  var EXPO_NATIVE_DIRECTORIES = ["modules", "plugins"];
31985
- var exists6 = async (path) => access13(path).then(() => true, () => false);
32528
+ var exists7 = async (path) => access14(path).then(() => true, () => false);
31986
32529
  var filesIn = async (directory, prefix) => {
31987
- if (!await exists6(directory))
32530
+ if (!await exists7(directory))
31988
32531
  return [];
31989
- const entries = await readdir5(directory, { withFileTypes: true });
32532
+ const entries = await readdir6(directory, { withFileTypes: true });
31990
32533
  const nested = await Promise.all(entries.map((entry) => {
31991
- const path = join20(directory, entry.name);
32534
+ const path = join21(directory, entry.name);
31992
32535
  const name = `${prefix}/${entry.name}`;
31993
32536
  if (entry.isDirectory())
31994
32537
  return filesIn(path, name);
@@ -31997,21 +32540,21 @@ var filesIn = async (directory, prefix) => {
31997
32540
  return nested.flat().sort((left, right) => left.name.localeCompare(right.name));
31998
32541
  };
31999
32542
  var fingerprintAbsoluteExpoNativeInputs = async (options) => {
32000
- const hash = createHash14("sha256");
32543
+ const hash = createHash15("sha256");
32001
32544
  const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
32002
- const path = join20(options.projectRoot, name);
32003
- return await exists6(path) ? [{ name: `root/${name}`, path }] : [];
32545
+ const path = join21(options.projectRoot, name);
32546
+ return await exists7(path) ? [{ name: `root/${name}`, path }] : [];
32004
32547
  }));
32005
- const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join20(options.expoProjectDirectory, name), name)));
32548
+ const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join21(options.expoProjectDirectory, name), name)));
32006
32549
  const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
32007
- const contents = await Promise.all(files.map(({ path }) => readFile17(path)));
32550
+ const contents = await Promise.all(files.map(({ path }) => readFile18(path)));
32008
32551
  files.forEach(({ name }, index) => {
32009
32552
  hash.update(name);
32010
32553
  hash.update(contents[index] ?? Buffer.alloc(0));
32011
32554
  });
32012
32555
  return hash.digest("hex");
32013
32556
  };
32014
- var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename6(path));
32557
+ var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename7(path));
32015
32558
  var createAbsoluteExpoNativeWatcher = async (options) => {
32016
32559
  let fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
32017
32560
  let closed = false;
@@ -32073,14 +32616,14 @@ var createAbsoluteExpoNativeWatcher = async (options) => {
32073
32616
  }
32074
32617
  };
32075
32618
  const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
32076
- const directory = join20(options.expoProjectDirectory, name);
32077
- return await exists6(directory) ? [directory] : [];
32619
+ const directory = join21(options.expoProjectDirectory, name);
32620
+ return await exists7(directory) ? [directory] : [];
32078
32621
  }))).flat();
32079
32622
  nativeDirectories.forEach((directory) => {
32080
32623
  watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
32081
32624
  if (!filename)
32082
32625
  return;
32083
- record(relative13(options.expoProjectDirectory, join20(directory, String(filename))), false);
32626
+ record(relative14(options.expoProjectDirectory, join21(directory, String(filename))), false);
32084
32627
  }));
32085
32628
  });
32086
32629
  watchers.push(watch2(options.projectRoot, (_event, filename) => {
@@ -32095,8 +32638,8 @@ var createAbsoluteExpoNativeWatcher = async (options) => {
32095
32638
  return { close };
32096
32639
  };
32097
32640
  // src/mobile/expoUpdate.ts
32098
- import { access as access14, mkdir as mkdir14, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
32099
- import { dirname as dirname13, extname as extname4, join as join21 } from "path";
32641
+ import { access as access15, mkdir as mkdir15, readFile as readFile19, writeFile as writeFile15 } from "fs/promises";
32642
+ import { dirname as dirname14, extname as extname4, join as join22 } from "path";
32100
32643
  var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
32101
32644
  var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
32102
32645
  var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -32162,7 +32705,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
32162
32705
  };
32163
32706
  };
32164
32707
  var finalizeAbsoluteExpoUpdateExport = async (options) => {
32165
- const metadata = JSON.parse(await readFile18(join21(options.exportDirectory, "metadata.json"), "utf8"));
32708
+ const metadata = JSON.parse(await readFile19(join22(options.exportDirectory, "metadata.json"), "utf8"));
32166
32709
  if (!object4(metadata) || !object4(metadata.fileMetadata))
32167
32710
  throw new TypeError("Expo export metadata.json is invalid.");
32168
32711
  const descriptor = parseAbsoluteExpoUpdateDescriptor({
@@ -32173,11 +32716,11 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
32173
32716
  runtimeVersion: options.runtimeVersion
32174
32717
  });
32175
32718
  const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
32176
- await Promise.all(referenced.map(({ path }) => access14(join21(options.exportDirectory, path)).catch(() => {
32719
+ await Promise.all(referenced.map(({ path }) => access15(join22(options.exportDirectory, path)).catch(() => {
32177
32720
  throw new TypeError(`Expo export metadata references missing asset ${path}.`);
32178
32721
  })));
32179
- const destination = join21(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
32180
- await mkdir14(dirname13(destination), { recursive: true });
32722
+ const destination = join22(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
32723
+ await mkdir15(dirname14(destination), { recursive: true });
32181
32724
  await writeFile15(destination, `${JSON.stringify(descriptor, null, "\t")}
32182
32725
  `);
32183
32726
  return { descriptor, path: destination };
@@ -32188,8 +32731,8 @@ init_config();
32188
32731
 
32189
32732
  // src/mobile/ciWorkflow.ts
32190
32733
  import { existsSync as existsSync4 } from "fs";
32191
- import { access as access15, mkdir as mkdir15, readFile as readFile19, writeFile as writeFile16 } from "fs/promises";
32192
- import { dirname as dirname14, extname as extname5, relative as relative14, resolve as resolve16, sep as sep9 } from "path";
32734
+ import { access as access16, mkdir as mkdir16, readFile as readFile20, writeFile as writeFile16 } from "fs/promises";
32735
+ import { dirname as dirname15, extname as extname5, relative as relative15, resolve as resolve17, sep as sep10 } from "path";
32193
32736
  var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
32194
32737
  var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
32195
32738
  var CI_ENV_INDENTATION = 6;
@@ -32208,9 +32751,9 @@ var RESERVED_SECRET_NAMES = new Set([
32208
32751
  "APP_STORE_CONNECT_KEY_ID",
32209
32752
  "APP_STORE_CONNECT_PRIVATE_KEY_BASE64"
32210
32753
  ]);
32211
- var exists7 = async (path) => {
32754
+ var exists8 = async (path) => {
32212
32755
  try {
32213
- await access15(path);
32756
+ await access16(path);
32214
32757
  return true;
32215
32758
  } catch {
32216
32759
  return false;
@@ -32218,10 +32761,10 @@ var exists7 = async (path) => {
32218
32761
  };
32219
32762
  var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
32220
32763
  var projectPath = (projectRoot, value, field2, options = {}) => {
32221
- const root = resolve16(projectRoot);
32222
- const path = resolve16(root, value);
32223
- const portable = relative14(root, path).replaceAll("\\", "/");
32224
- if (portable === ".." || portable.startsWith(`..${sep9}`) || portable.startsWith("../") || portable === "") {
32764
+ const root = resolve17(projectRoot);
32765
+ const path = resolve17(root, value);
32766
+ const portable = relative15(root, path).replaceAll("\\", "/");
32767
+ if (portable === ".." || portable.startsWith(`..${sep10}`) || portable.startsWith("../") || portable === "") {
32225
32768
  throw new TypeError(`${field2} must remain inside the project root.`);
32226
32769
  }
32227
32770
  if (/\r|\n/u.test(portable) || portable.startsWith("-"))
@@ -32231,11 +32774,11 @@ var projectPath = (projectRoot, value, field2, options = {}) => {
32231
32774
  return portable;
32232
32775
  };
32233
32776
  var workflowOutputPath = (projectRoot, value) => {
32234
- const root = resolve16(projectRoot);
32235
- const workflows = resolve16(root, ".github/workflows");
32236
- const path = resolve16(root, value ?? ".github/workflows/absolute-mobile.yml");
32237
- const portable = relative14(workflows, path);
32238
- if (portable === ".." || portable.startsWith(`..${sep9}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
32777
+ const root = resolve17(projectRoot);
32778
+ const workflows = resolve17(root, ".github/workflows");
32779
+ const path = resolve17(root, value ?? ".github/workflows/absolute-mobile.yml");
32780
+ const portable = relative15(workflows, path);
32781
+ if (portable === ".." || portable.startsWith(`..${sep10}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
32239
32782
  throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
32240
32783
  }
32241
32784
  return path;
@@ -32664,11 +33207,11 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
32664
33207
  var writeAbsoluteMobileGithubWorkflow = async (options) => {
32665
33208
  const path = workflowOutputPath(options.projectRoot, options.outputPath);
32666
33209
  const generated = createAbsoluteMobileGithubWorkflow(options);
32667
- const previous = await exists7(path) ? await readFile19(path, "utf8") : undefined;
33210
+ const previous = await exists8(path) ? await readFile20(path, "utf8") : undefined;
32668
33211
  if (previous !== undefined && previous !== generated.workflow && !options.force)
32669
- throw new TypeError(`${relative14(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
33212
+ throw new TypeError(`${relative15(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
32670
33213
  if (previous !== generated.workflow) {
32671
- await mkdir15(dirname14(path), { recursive: true });
33214
+ await mkdir16(dirname15(path), { recursive: true });
32672
33215
  await writeFile16(path, generated.workflow);
32673
33216
  }
32674
33217
  return {
@@ -32687,15 +33230,15 @@ init_materializedBundle();
32687
33230
  init_mobilePreview();
32688
33231
 
32689
33232
  // src/mobile/nativeDeepLinks.ts
32690
- import { readFile as readFile20, rename as rename13, writeFile as writeFile17 } from "fs/promises";
32691
- import { join as join24 } from "path";
33233
+ import { readFile as readFile21, rename as rename13, writeFile as writeFile17 } from "fs/promises";
33234
+ import { join as join25 } from "path";
32692
33235
  var START_MARKER = "<!-- absolutejs:deep-links:start -->";
32693
33236
  var END_MARKER = "<!-- absolutejs:deep-links:end -->";
32694
33237
  var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
32695
33238
  var NOT_FOUND = -1;
32696
33239
  var escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
32697
33240
  var writeChangedFile = async (path, source) => {
32698
- const current = await readFile20(path, "utf8");
33241
+ const current = await readFile21(path, "utf8");
32699
33242
  if (current === source)
32700
33243
  return false;
32701
33244
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
@@ -32745,8 +33288,8 @@ ${hosts}
32745
33288
  `;
32746
33289
  };
32747
33290
  var configureAndroid = async (config) => {
32748
- const path = join24(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
32749
- const source = await readFile20(path, "utf8");
33291
+ const path = join25(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
33292
+ const source = await readFile21(path, "utf8");
32750
33293
  const mainActivity = source.indexOf('android:name=".MainActivity"');
32751
33294
  if (mainActivity === NOT_FOUND) {
32752
33295
  throw new TypeError("Android MainActivity was not found.");
@@ -32771,8 +33314,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
32771
33314
  ${END_MARKER}
32772
33315
  `;
32773
33316
  var configureIosInfo = async (config) => {
32774
- const path = join24(config.nativeProjectDirectory, "ios/App/App/Info.plist");
32775
- const source = await readFile20(path, "utf8");
33317
+ const path = join25(config.nativeProjectDirectory, "ios/App/App/Info.plist");
33318
+ const source = await readFile21(path, "utf8");
32776
33319
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
32777
33320
  ${END_MARKER}
32778
33321
  `;
@@ -32795,10 +33338,10 @@ ${domains}
32795
33338
  `;
32796
33339
  };
32797
33340
  var configureIosEntitlements = async (config) => {
32798
- const path = join24(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
33341
+ const path = join25(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
32799
33342
  let current = "";
32800
33343
  try {
32801
- current = await readFile20(path, "utf8");
33344
+ current = await readFile21(path, "utf8");
32802
33345
  } catch (error) {
32803
33346
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
32804
33347
  throw error;
@@ -32813,8 +33356,8 @@ var configureIosEntitlements = async (config) => {
32813
33356
  return true;
32814
33357
  };
32815
33358
  var configureIosProject = async (config) => {
32816
- const path = join24(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
32817
- const source = await readFile20(path, "utf8");
33359
+ const path = join25(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
33360
+ const source = await readFile21(path, "utf8");
32818
33361
  const declarations = [
32819
33362
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
32820
33363
  ].map((match) => match[1]);
@@ -32853,8 +33396,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
32853
33396
  };
32854
33397
  // src/mobile/nativeDeviceCapabilities.ts
32855
33398
  init_deviceCapabilities();
32856
- import { readFile as readFile21, rename as rename14, writeFile as writeFile18 } from "fs/promises";
32857
- import { join as join25 } from "path";
33399
+ import { readFile as readFile22, rename as rename14, writeFile as writeFile18 } from "fs/promises";
33400
+ import { join as join26 } from "path";
32858
33401
  var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
32859
33402
  var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
32860
33403
  var NOT_FOUND2 = -1;
@@ -32864,7 +33407,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
32864
33407
  var PUSH_END_MARKER = "absolutejs:push-notifications:end";
32865
33408
  var escapeXml2 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
32866
33409
  var writeChangedFile2 = async (path, source) => {
32867
- const current = await readFile21(path, "utf8");
33410
+ const current = await readFile22(path, "utf8");
32868
33411
  if (current === source)
32869
33412
  return false;
32870
33413
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
@@ -32884,7 +33427,7 @@ var writeOptionalChangedFile = async (path, source) => {
32884
33427
  };
32885
33428
  var optionalSource = async (path) => {
32886
33429
  try {
32887
- return await readFile21(path, "utf8");
33430
+ return await readFile22(path, "utf8");
32888
33431
  } catch (error) {
32889
33432
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32890
33433
  return null;
@@ -33004,8 +33547,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
33004
33547
  var configureIosPrivacyProject = async (config, requirements) => {
33005
33548
  if (requirements.iosPrivacyAccessedApis.length === 0)
33006
33549
  return false;
33007
- const projectPath2 = join25(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
33008
- const project = await readFile21(projectPath2, "utf8");
33550
+ const projectPath2 = join26(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
33551
+ const project = await readFile22(projectPath2, "utf8");
33009
33552
  return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
33010
33553
  };
33011
33554
  var addIosPrivacyProjectReference = (source) => {
@@ -33057,8 +33600,8 @@ ${next.slice(index)}`;
33057
33600
  return next;
33058
33601
  };
33059
33602
  var configureIos2 = async (config, plan) => {
33060
- const path = join25(config.nativeProjectDirectory, "ios/App/App/Info.plist");
33061
- const source = await readFile21(path, "utf8");
33603
+ const path = join26(config.nativeProjectDirectory, "ios/App/App/Info.plist");
33604
+ const source = await readFile22(path, "utf8");
33062
33605
  const requirements = absoluteDeviceNativeRequirements(plan);
33063
33606
  const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
33064
33607
  const ownedStart = source.indexOf(START_MARKER2);
@@ -33078,7 +33621,7 @@ ${content}
33078
33621
  ${END_MARKER2}
33079
33622
  ` : "";
33080
33623
  const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
33081
- const privacyPath = join25(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
33624
+ const privacyPath = join26(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
33082
33625
  const privacyCurrent = await optionalSource(privacyPath);
33083
33626
  const privacySource = privacyManifestSource(privacyCurrent, requirements);
33084
33627
  const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
@@ -33089,7 +33632,7 @@ ${content}
33089
33632
  return infoChanged || privacyChanged || projectChanged || pushChanged;
33090
33633
  };
33091
33634
  var configureIosPushNotifications = async (config, enabled) => {
33092
- const entitlementsPath = join25(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
33635
+ const entitlementsPath = join26(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
33093
33636
  const entitlements = await optionalSource(entitlementsPath);
33094
33637
  if (entitlements === null && !enabled)
33095
33638
  return false;
@@ -33101,7 +33644,7 @@ var configureIosPushNotifications = async (config, enabled) => {
33101
33644
  <!-- ${PUSH_END_MARKER} -->
33102
33645
  ` : "";
33103
33646
  const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
33104
- const delegatePath = join25(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
33647
+ const delegatePath = join26(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
33105
33648
  const delegate = await optionalSource(delegatePath);
33106
33649
  if (delegate === null && !enabled)
33107
33650
  return false;
@@ -33150,8 +33693,8 @@ var replacePushRegion = (source, region, insertion) => {
33150
33693
  return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
33151
33694
  };
33152
33695
  var configureAndroid2 = async (config, plan) => {
33153
- const path = join25(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
33154
- const source = await readFile21(path, "utf8");
33696
+ const path = join26(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
33697
+ const source = await readFile22(path, "utf8");
33155
33698
  const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
33156
33699
  const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
33157
33700
  `);
@@ -33186,7 +33729,7 @@ ${content}
33186
33729
  throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
33187
33730
  const [manifestChanged, firebaseChanged] = await Promise.all([
33188
33731
  writeChangedFile2(path, nextManifest),
33189
- writeOptionalChangedFile(join25(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
33732
+ writeOptionalChangedFile(join26(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
33190
33733
  ]);
33191
33734
  return manifestChanged || firebaseChanged;
33192
33735
  };
@@ -33205,14 +33748,14 @@ init_nativeAuth();
33205
33748
 
33206
33749
  // src/mobile/nativeUpdates.ts
33207
33750
  import {
33208
- mkdir as mkdir16,
33209
- readFile as readFile22,
33210
- readdir as readdir6,
33751
+ mkdir as mkdir17,
33752
+ readFile as readFile23,
33753
+ readdir as readdir7,
33211
33754
  rename as rename15,
33212
- rm as rm12,
33755
+ rm as rm13,
33213
33756
  writeFile as writeFile19
33214
33757
  } from "fs/promises";
33215
- import { dirname as dirname16, join as join26 } from "path";
33758
+ import { dirname as dirname17, join as join27 } from "path";
33216
33759
  var START = "// absolutejs:mobile-updates:start";
33217
33760
  var END = "// absolutejs:mobile-updates:end";
33218
33761
  var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
@@ -33220,7 +33763,7 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
33220
33763
  var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
33221
33764
  var optionalSource2 = async (path) => {
33222
33765
  try {
33223
- return await readFile22(path, "utf8");
33766
+ return await readFile23(path, "utf8");
33224
33767
  } catch (error) {
33225
33768
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
33226
33769
  return null;
@@ -33232,7 +33775,7 @@ var writeChanged = async (path, source) => {
33232
33775
  const current = await optionalSource2(path);
33233
33776
  if (current === source)
33234
33777
  return false;
33235
- await mkdir16(dirname16(path), { recursive: true });
33778
+ await mkdir17(dirname17(path), { recursive: true });
33236
33779
  if (current === null) {
33237
33780
  await writeFile19(path, source, { flag: "wx" });
33238
33781
  return true;
@@ -33245,7 +33788,7 @@ var writeChanged = async (path, source) => {
33245
33788
  var removeOwnedFile = async (path) => {
33246
33789
  if (await optionalSource2(path) === null)
33247
33790
  return false;
33248
- await rm12(path);
33791
+ await rm13(path);
33249
33792
  return true;
33250
33793
  };
33251
33794
  var replaceMarkedRegion = (source, start, end, region, insertion, error) => {
@@ -33382,9 +33925,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
33382
33925
  ${PLUGIN_END}
33383
33926
  `;
33384
33927
  var configureIos3 = async (config, enabled) => {
33385
- const path = join26(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
33386
- const capacitorConfigPath = join26(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
33387
- let source = await readFile22(path, "utf8");
33928
+ const path = join27(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
33929
+ const capacitorConfigPath = join27(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
33930
+ let source = await readFile23(path, "utf8");
33388
33931
  const launch2 = source.indexOf("didFinishLaunchingWithOptions");
33389
33932
  const brace = launch2 < 0 ? -1 : source.indexOf("{", launch2);
33390
33933
  const launchRegion = enabled ? ` ${START}
@@ -33395,7 +33938,7 @@ var configureIos3 = async (config, enabled) => {
33395
33938
  `, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
33396
33939
  const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
33397
33940
  source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
33398
- const capacitorConfigSource2 = await readFile22(capacitorConfigPath, "utf8");
33941
+ const capacitorConfigSource2 = await readFile23(capacitorConfigPath, "utf8");
33399
33942
  let capacitorConfig;
33400
33943
  try {
33401
33944
  const value = JSON.parse(capacitorConfigSource2);
@@ -33568,19 +34111,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
33568
34111
  var androidActivityInRoot = async (root) => {
33569
34112
  let entries;
33570
34113
  try {
33571
- entries = await readdir6(root, { recursive: true });
34114
+ entries = await readdir7(root, { recursive: true });
33572
34115
  } catch (error) {
33573
34116
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
33574
34117
  return;
33575
34118
  throw error;
33576
34119
  }
33577
34120
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
33578
- return candidate ? join26(root, candidate) : undefined;
34121
+ return candidate ? join27(root, candidate) : undefined;
33579
34122
  };
33580
34123
  var androidActivity = async (config) => {
33581
34124
  const roots = [
33582
- join26(config.nativeProjectDirectory, "android/app/src/main/java"),
33583
- join26(config.nativeProjectDirectory, "android/app/src/main/kotlin")
34125
+ join27(config.nativeProjectDirectory, "android/app/src/main/java"),
34126
+ join27(config.nativeProjectDirectory, "android/app/src/main/kotlin")
33584
34127
  ];
33585
34128
  const candidates = await Promise.all(roots.map(androidActivityInRoot));
33586
34129
  const candidate = candidates.find((value) => value !== undefined);
@@ -33679,12 +34222,12 @@ var injectAndroidActivity = (source, enabled) => {
33679
34222
  };
33680
34223
  var configureAndroid3 = async (config, enabled) => {
33681
34224
  const activityPath = await androidActivity(config);
33682
- const activity = await readFile22(activityPath, "utf8");
34225
+ const activity = await readFile23(activityPath, "utf8");
33683
34226
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
33684
34227
  if (!packageName)
33685
34228
  throw new TypeError("Android MainActivity package declaration was not found.");
33686
34229
  const packagePath = packageName.replaceAll(".", "/");
33687
- const pluginPath = join26(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
34230
+ const pluginPath = join27(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
33688
34231
  const changed = await Promise.all([
33689
34232
  writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
33690
34233
  enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
@@ -33704,14 +34247,14 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
33704
34247
  };
33705
34248
  // src/mobile/nativeObservability.ts
33706
34249
  import {
33707
- mkdir as mkdir17,
33708
- readFile as readFile23,
33709
- readdir as readdir7,
34250
+ mkdir as mkdir18,
34251
+ readFile as readFile24,
34252
+ readdir as readdir8,
33710
34253
  rename as rename16,
33711
- rm as rm13,
34254
+ rm as rm14,
33712
34255
  writeFile as writeFile20
33713
34256
  } from "fs/promises";
33714
- import { dirname as dirname17, join as join27 } from "path";
34257
+ import { dirname as dirname18, join as join28 } from "path";
33715
34258
  var START2 = "// absolutejs:native-observability:start";
33716
34259
  var END2 = "// absolutejs:native-observability:end";
33717
34260
  var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
@@ -33719,7 +34262,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
33719
34262
  var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
33720
34263
  var optionalSource3 = async (path) => {
33721
34264
  try {
33722
- return await readFile23(path, "utf8");
34265
+ return await readFile24(path, "utf8");
33723
34266
  } catch (error) {
33724
34267
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
33725
34268
  return null;
@@ -33730,7 +34273,7 @@ var writeChanged2 = async (path, source) => {
33730
34273
  const current = await optionalSource3(path);
33731
34274
  if (current === source)
33732
34275
  return false;
33733
- await mkdir17(dirname17(path), { recursive: true });
34276
+ await mkdir18(dirname18(path), { recursive: true });
33734
34277
  if (current === null) {
33735
34278
  await writeFile20(path, source, { flag: "wx" });
33736
34279
  return true;
@@ -33743,7 +34286,7 @@ var writeChanged2 = async (path, source) => {
33743
34286
  var removeOwnedFile2 = async (path) => {
33744
34287
  if (await optionalSource3(path) === null)
33745
34288
  return false;
33746
- await rm13(path);
34289
+ await rm14(path);
33747
34290
  return true;
33748
34291
  };
33749
34292
  var isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -33879,9 +34422,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
33879
34422
  ${PLUGIN_END2}
33880
34423
  `;
33881
34424
  var configureIos4 = async (config, enabled) => {
33882
- const path = join27(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
33883
- const capacitorConfigPath = join27(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
33884
- let source = await readFile23(path, "utf8");
34425
+ const path = join28(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
34426
+ const capacitorConfigPath = join28(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
34427
+ let source = await readFile24(path, "utf8");
33885
34428
  if (enabled && !source.includes("import MetricKit")) {
33886
34429
  const capacitorImport = source.lastIndexOf("import Capacitor");
33887
34430
  if (capacitorImport < 0)
@@ -33895,7 +34438,7 @@ ${source.slice(newline + 1)}`;
33895
34438
  source = source.replace(`import MetricKit
33896
34439
  `, "");
33897
34440
  source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
33898
- const capacitorConfigSource2 = await readFile23(capacitorConfigPath, "utf8");
34441
+ const capacitorConfigSource2 = await readFile24(capacitorConfigPath, "utf8");
33899
34442
  let capacitorConfig;
33900
34443
  try {
33901
34444
  const value = JSON.parse(capacitorConfigSource2);
@@ -34133,19 +34676,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
34133
34676
  var androidActivityInRoot2 = async (root) => {
34134
34677
  let entries;
34135
34678
  try {
34136
- entries = await readdir7(root, { recursive: true });
34679
+ entries = await readdir8(root, { recursive: true });
34137
34680
  } catch (error) {
34138
34681
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
34139
34682
  return;
34140
34683
  throw error;
34141
34684
  }
34142
34685
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
34143
- return candidate ? join27(root, candidate) : undefined;
34686
+ return candidate ? join28(root, candidate) : undefined;
34144
34687
  };
34145
34688
  var androidActivity2 = async (config) => {
34146
34689
  const roots = [
34147
- join27(config.nativeProjectDirectory, "android/app/src/main/java"),
34148
- join27(config.nativeProjectDirectory, "android/app/src/main/kotlin")
34690
+ join28(config.nativeProjectDirectory, "android/app/src/main/java"),
34691
+ join28(config.nativeProjectDirectory, "android/app/src/main/kotlin")
34149
34692
  ];
34150
34693
  const candidates = await Promise.all(roots.map(androidActivityInRoot2));
34151
34694
  const candidate = candidates.find((value) => value !== undefined);
@@ -34213,11 +34756,11 @@ var injectAndroidActivity2 = (source, enabled) => {
34213
34756
  };
34214
34757
  var configureAndroid4 = async (config, enabled) => {
34215
34758
  const activityPath = await androidActivity2(config);
34216
- const activity = await readFile23(activityPath, "utf8");
34759
+ const activity = await readFile24(activityPath, "utf8");
34217
34760
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
34218
34761
  if (!packageName)
34219
34762
  throw new TypeError("Android MainActivity package declaration was not found.");
34220
- const pluginPath = join27(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
34763
+ const pluginPath = join28(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
34221
34764
  const changed = await Promise.all([
34222
34765
  writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
34223
34766
  enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
@@ -34236,14 +34779,16 @@ var applyAbsoluteNativeObservability = async (config, platforms = config.platfor
34236
34779
  return { changed: changed.some(Boolean) };
34237
34780
  };
34238
34781
  // src/mobile/nativeReleaseReadiness.ts
34239
- import { mkdir as mkdir18, readFile as readFile24, readdir as readdir8, rename as rename17, writeFile as writeFile21 } from "fs/promises";
34240
- import { dirname as dirname18, join as join28 } from "path";
34782
+ import { mkdir as mkdir19, readFile as readFile25, readdir as readdir9, rename as rename17, writeFile as writeFile21 } from "fs/promises";
34783
+ import { dirname as dirname19, join as join29 } from "path";
34241
34784
  var START3 = "// absolutejs:release-readiness:start";
34242
34785
  var END3 = "// absolutejs:release-readiness:end";
34786
+ var IOS_PLUGIN_START = "// absolutejs:release-readiness-plugin:start";
34787
+ var IOS_PLUGIN_END = "// absolutejs:release-readiness-plugin:end";
34243
34788
  var ANDROID_PLUGIN3 = "AbsoluteReleaseReadinessPlugin.java";
34244
34789
  var optionalSource4 = async (path) => {
34245
34790
  try {
34246
- return await readFile24(path, "utf8");
34791
+ return await readFile25(path, "utf8");
34247
34792
  } catch (error) {
34248
34793
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
34249
34794
  return null;
@@ -34254,7 +34799,7 @@ var writeChanged3 = async (path, source) => {
34254
34799
  const current = await optionalSource4(path);
34255
34800
  if (current === source)
34256
34801
  return false;
34257
- await mkdir18(dirname18(path), { recursive: true });
34802
+ await mkdir19(dirname19(path), { recursive: true });
34258
34803
  if (current === null) {
34259
34804
  await writeFile21(path, source, { flag: "wx" });
34260
34805
  return true;
@@ -34267,19 +34812,19 @@ var writeChanged3 = async (path, source) => {
34267
34812
  var activityInRoot = async (root) => {
34268
34813
  let entries;
34269
34814
  try {
34270
- entries = await readdir8(root, { recursive: true });
34815
+ entries = await readdir9(root, { recursive: true });
34271
34816
  } catch (error) {
34272
34817
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
34273
34818
  return;
34274
34819
  throw error;
34275
34820
  }
34276
34821
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
34277
- return candidate ? join28(root, candidate) : undefined;
34822
+ return candidate ? join29(root, candidate) : undefined;
34278
34823
  };
34279
34824
  var activityPath = async (config) => {
34280
34825
  const roots = [
34281
- join28(config.nativeProjectDirectory, "android/app/src/main/java"),
34282
- join28(config.nativeProjectDirectory, "android/app/src/main/kotlin")
34826
+ join29(config.nativeProjectDirectory, "android/app/src/main/java"),
34827
+ join29(config.nativeProjectDirectory, "android/app/src/main/kotlin")
34283
34828
  ];
34284
34829
  const candidates = await Promise.all(roots.map(activityInRoot));
34285
34830
  const candidate = candidates.find((value) => value !== undefined);
@@ -34361,19 +34906,89 @@ public final class AbsoluteReleaseReadinessPlugin extends Plugin {
34361
34906
  }
34362
34907
  }
34363
34908
  `;
34364
- var applyAbsoluteNativeReleaseReadiness = async (config, platforms = config.platforms) => {
34365
- if (config.engine !== "capacitor" || !platforms.includes("android"))
34366
- return { changed: false };
34909
+ var iosPluginRegion3 = `${IOS_PLUGIN_START}
34910
+ @objc(AbsoluteReleaseReadinessPlugin)
34911
+ public final class AbsoluteReleaseReadinessPlugin: CAPPlugin, CAPBridgedPlugin {
34912
+ public let identifier = "AbsoluteReleaseReadinessPlugin"
34913
+ public let jsName = "AbsoluteReleaseReadiness"
34914
+ public let pluginMethods: [CAPPluginMethod] = [
34915
+ CAPPluginMethod(name: "ready", returnType: CAPPluginReturnPromise)
34916
+ ]
34917
+
34918
+ @objc public func ready(_ call: CAPPluginCall) {
34919
+ let info = Bundle.main.infoDictionary ?? [:]
34920
+ let version = info["CFBundleShortVersionString"] as? String ?? "unknown"
34921
+ let build = info["CFBundleVersion"] as? String ?? "unknown"
34922
+ NSLog("AbsoluteJS: Capacitor embedded web content ready; version=%@; build=%@", version, build)
34923
+ call.resolve(["ready": true])
34924
+ }
34925
+ }
34926
+ ${IOS_PLUGIN_END}
34927
+ `;
34928
+ var replaceIosPluginRegion = (appDelegate, existingStart, existingEnd) => {
34929
+ const from = appDelegate.lastIndexOf(`
34930
+ `, existingStart) + 1;
34931
+ const newline = appDelegate.indexOf(`
34932
+ `, existingEnd + IOS_PLUGIN_END.length);
34933
+ const through = newline < 0 ? appDelegate.length : newline + 1;
34934
+ return `${appDelegate.slice(0, from)}${iosPluginRegion3}${appDelegate.slice(through)}`;
34935
+ };
34936
+ var configureIos5 = async (config) => {
34937
+ const appDelegatePath = join29(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
34938
+ const capacitorConfigPath = join29(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
34939
+ const appDelegate = await readFile25(appDelegatePath, "utf8");
34940
+ const existingStart = appDelegate.indexOf(IOS_PLUGIN_START);
34941
+ const existingEnd = appDelegate.indexOf(IOS_PLUGIN_END);
34942
+ if (existingStart < 0 !== existingEnd < 0 || existingStart >= 0 && existingEnd < existingStart)
34943
+ throw new TypeError("AbsoluteJS iOS release-readiness markers are malformed.");
34944
+ const source = existingStart < 0 ? `${appDelegate.trimEnd()}
34945
+
34946
+ ${iosPluginRegion3}` : replaceIosPluginRegion(appDelegate, existingStart, existingEnd);
34947
+ let capacitorConfig;
34948
+ try {
34949
+ capacitorConfig = JSON.parse(await readFile25(capacitorConfigPath, "utf8"));
34950
+ } catch {
34951
+ throw new TypeError("iOS capacitor.config.json is invalid; run Capacitor sync before projecting release readiness.");
34952
+ }
34953
+ if (typeof capacitorConfig !== "object" || capacitorConfig === null)
34954
+ throw new TypeError("iOS capacitor.config.json must contain an object.");
34955
+ const packageClassList = Reflect.get(capacitorConfig, "packageClassList");
34956
+ if (!Array.isArray(packageClassList))
34957
+ throw new TypeError("iOS capacitor.config.json has no packageClassList; run Capacitor sync before projecting release readiness.");
34958
+ const classes = packageClassList.filter((value) => typeof value === "string");
34959
+ const nextConfig = `${JSON.stringify({
34960
+ ...capacitorConfig,
34961
+ packageClassList: [
34962
+ ...new Set([...classes, "AbsoluteReleaseReadinessPlugin"])
34963
+ ]
34964
+ }, null, "\t")}
34965
+ `;
34966
+ const changed = await Promise.all([
34967
+ writeChanged3(appDelegatePath, source),
34968
+ writeChanged3(capacitorConfigPath, nextConfig)
34969
+ ]);
34970
+ return changed.some(Boolean);
34971
+ };
34972
+ var configureAndroid5 = async (config) => {
34367
34973
  const mainActivityPath = await activityPath(config);
34368
- const activity = await readFile24(mainActivityPath, "utf8");
34974
+ const activity = await readFile25(mainActivityPath, "utf8");
34369
34975
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
34370
34976
  if (!packageName)
34371
34977
  throw new TypeError("Android MainActivity package declaration was not found.");
34372
- const pluginPath = join28(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN3);
34978
+ const pluginPath = join29(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN3);
34373
34979
  const changed = await Promise.all([
34374
34980
  writeChanged3(mainActivityPath, injectRegistration(activity)),
34375
34981
  writeChanged3(pluginPath, pluginSource(packageName))
34376
34982
  ]);
34983
+ return changed.some(Boolean);
34984
+ };
34985
+ var applyAbsoluteNativeReleaseReadiness = async (config, platforms = config.platforms) => {
34986
+ if (config.engine !== "capacitor")
34987
+ return { changed: false };
34988
+ const changed = await Promise.all([
34989
+ platforms.includes("android") ? configureAndroid5(config) : false,
34990
+ platforms.includes("ios") ? configureIos5(config) : false
34991
+ ]);
34377
34992
  return { changed: changed.some(Boolean) };
34378
34993
  };
34379
34994
 
@@ -34383,8 +34998,8 @@ init_producerContext();
34383
34998
  init_releaseArtifact();
34384
34999
 
34385
35000
  // src/mobile/releasePublisher.ts
34386
- import { access as access16 } from "fs/promises";
34387
- import { isAbsolute as isAbsolute8, relative as relative15, resolve as resolve17, sep as sep10 } from "path";
35001
+ import { access as access17 } from "fs/promises";
35002
+ import { isAbsolute as isAbsolute9, relative as relative16, resolve as resolve18, sep as sep11 } from "path";
34388
35003
  import { pathToFileURL as pathToFileURL3 } from "url";
34389
35004
  var prepareAbsoluteIosRelease = async (publisher, options) => {
34390
35005
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -34410,17 +35025,17 @@ var prepareAbsoluteAndroidRelease = async (publisher, options) => {
34410
35025
  var isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
34411
35026
  var isPublisher = (value) => isRecord14(value) && typeof value.publish === "function";
34412
35027
  var publisherModulePath = (projectRoot, requested) => {
34413
- const root = resolve17(projectRoot);
34414
- const path = resolve17(root, requested);
34415
- const projectRelative = relative15(root, path);
34416
- if (projectRelative === ".." || projectRelative.startsWith(`..${sep10}`) || isAbsolute8(projectRelative)) {
35028
+ const root = resolve18(projectRoot);
35029
+ const path = resolve18(root, requested);
35030
+ const projectRelative = relative16(root, path);
35031
+ if (projectRelative === ".." || projectRelative.startsWith(`..${sep11}`) || isAbsolute9(projectRelative)) {
34417
35032
  throw new TypeError("mobile publish --registry must remain inside the project.");
34418
35033
  }
34419
35034
  return path;
34420
35035
  };
34421
35036
  var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
34422
35037
  const modulePath = publisherModulePath(projectRoot, requestedModulePath);
34423
- await access16(modulePath).catch(() => {
35038
+ await access17(modulePath).catch(() => {
34424
35039
  throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
34425
35040
  });
34426
35041
  const loaded = await import(pathToFileURL3(modulePath).href);
@@ -34484,7 +35099,7 @@ var publishAbsoluteIosRelease = async (options) => {
34484
35099
  init_pageProtocol();
34485
35100
  init_releaseArtifact();
34486
35101
  import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
34487
- import { dirname as dirname19, extname as extname6, relative as relative16, resolve as resolve18 } from "path";
35102
+ import { dirname as dirname20, extname as extname6, relative as relative17, resolve as resolve19 } from "path";
34488
35103
  import ts2 from "typescript";
34489
35104
  var ROUTE_METHODS = new Set(["get", "head"]);
34490
35105
  var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
@@ -34535,7 +35150,7 @@ var PAGE_HANDLERS = new Map([
34535
35150
  ]
34536
35151
  ]);
34537
35152
  var posixPath = (value) => value.replace(/\\/g, "/");
34538
- var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(dirname19(entry), existsSync7, "tsconfig.json") ?? ts2.findConfigFile(projectRoot, existsSync7, "tsconfig.json");
35153
+ var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(dirname20(entry), existsSync7, "tsconfig.json") ?? ts2.findConfigFile(projectRoot, existsSync7, "tsconfig.json");
34539
35154
  var createProgram = (entry, projectRoot) => {
34540
35155
  const configPath2 = findTsconfig(entry, projectRoot);
34541
35156
  if (!configPath2) {
@@ -34547,7 +35162,7 @@ var createProgram = (entry, projectRoot) => {
34547
35162
  target: ts2.ScriptTarget.ESNext
34548
35163
  });
34549
35164
  }
34550
- const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath2, (path) => readFileSync8(path, "utf8")).config, ts2.sys, dirname19(configPath2));
35165
+ const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath2, (path) => readFileSync8(path, "utf8")).config, ts2.sys, dirname20(configPath2));
34551
35166
  if (!parsed.fileNames.includes(entry))
34552
35167
  parsed.fileNames.push(entry);
34553
35168
  return ts2.createProgram(parsed.fileNames, parsed.options);
@@ -34653,7 +35268,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
34653
35268
  const declaration = symbol?.declarations?.[0];
34654
35269
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
34655
35270
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
34656
- const source = posixPath(relative16(projectRoot, file));
35271
+ const source = posixPath(relative17(projectRoot, file));
34657
35272
  return `${source}#${exportedName}`;
34658
35273
  };
34659
35274
  var resolveAlias = (symbol, checker) => {
@@ -34892,7 +35507,7 @@ var analyzeProgram = (program, projectRoot) => {
34892
35507
  const checker = program.getTypeChecker();
34893
35508
  const analyzed = new Map;
34894
35509
  for (const sourceFile of program.getSourceFiles()) {
34895
- const resolvedFile = resolve18(sourceFile.fileName);
35510
+ const resolvedFile = resolve19(sourceFile.fileName);
34896
35511
  if (!isProjectSource(sourceFile, resolvedFile, projectRoot))
34897
35512
  continue;
34898
35513
  const analysis = analyzeSourceFile(sourceFile, checker, projectRoot);
@@ -34985,14 +35600,14 @@ var transformFile = (source, fileName, analysis) => {
34985
35600
  };
34986
35601
  var ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL = ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION;
34987
35602
  var createAbsoluteMobileRouteMetadataPlugin = (options) => {
34988
- const projectRoot = resolve18(options.projectRoot ?? process.cwd());
34989
- const entry = resolve18(options.entry);
35603
+ const projectRoot = resolve19(options.projectRoot ?? process.cwd());
35604
+ const entry = resolve19(options.entry);
34990
35605
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
34991
35606
  return {
34992
35607
  name: "absolute-mobile-route-metadata",
34993
35608
  setup(build) {
34994
35609
  build.onLoad({ filter: SOURCE_FILTER }, async ({ path }) => {
34995
- const analysis = analyzed.get(resolve18(path));
35610
+ const analysis = analyzed.get(resolve19(path));
34996
35611
  if (!analysis)
34997
35612
  return;
34998
35613
  const source = await Bun.file(path).text();
@@ -35005,11 +35620,11 @@ var createAbsoluteMobileRouteMetadataPlugin = (options) => {
35005
35620
  };
35006
35621
  };
35007
35622
  var inspectAbsoluteMobileRouteMetadata = (options) => {
35008
- const projectRoot = resolve18(options.projectRoot ?? process.cwd());
35009
- const entry = resolve18(options.entry);
35623
+ const projectRoot = resolve19(options.projectRoot ?? process.cwd());
35624
+ const entry = resolve19(options.entry);
35010
35625
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
35011
35626
  return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
35012
- file: posixPath(relative16(projectRoot, file)),
35627
+ file: posixPath(relative17(projectRoot, file)),
35013
35628
  metadata
35014
35629
  })));
35015
35630
  };
@@ -35343,7 +35958,7 @@ var createCapacitor = (win) => {
35343
35958
  callbackId
35344
35959
  }, callback);
35345
35960
  };
35346
- const p = new Promise((resolve19) => call.then(() => resolve19({ remove })));
35961
+ const p = new Promise((resolve20) => call.then(() => resolve20({ remove })));
35347
35962
  p.remove = async () => {
35348
35963
  console.warn(`Using addListener() without 'await' is deprecated.`);
35349
35964
  await remove();
@@ -35548,11 +36163,11 @@ class CapacitorCookiesPluginWeb extends WebPlugin {
35548
36163
  var CapacitorCookies = registerPlugin("CapacitorCookies", {
35549
36164
  web: () => new CapacitorCookiesPluginWeb
35550
36165
  });
35551
- var readBlobAsBase64 = async (blob) => new Promise((resolve19, reject) => {
36166
+ var readBlobAsBase64 = async (blob) => new Promise((resolve20, reject) => {
35552
36167
  const reader = new FileReader;
35553
36168
  reader.onload = () => {
35554
36169
  const base64String = reader.result;
35555
- resolve19(base64String.indexOf(",") >= 0 ? base64String.split(",")[1] : base64String);
36170
+ resolve20(base64String.indexOf(",") >= 0 ? base64String.split(",")[1] : base64String);
35556
36171
  };
35557
36172
  reader.onerror = (error) => reject(error);
35558
36173
  reader.readAsDataURL(blob);
@@ -40212,8 +40827,8 @@ var createBeacon = (options) => {
40212
40827
  if (await fontAvailable(element))
40213
40828
  return;
40214
40829
  if (confirmationMs > 0) {
40215
- await new Promise((resolve19) => {
40216
- const timer2 = window.setTimeout(resolve19, confirmationMs);
40830
+ await new Promise((resolve20) => {
40831
+ const timer2 = window.setTimeout(resolve20, confirmationMs);
40217
40832
  cleanups.push(() => window.clearTimeout(timer2));
40218
40833
  });
40219
40834
  if (document.visibilityState === "hidden")
@@ -41201,51 +41816,51 @@ var createAbsoluteMobileUpdateClient = (options) => {
41201
41816
  };
41202
41817
  };
41203
41818
  // src/mobile/updatePublisher.ts
41204
- import { access as access17 } from "fs/promises";
41205
- import { isAbsolute as isAbsolute9, relative as relative18, resolve as resolve20, sep as sep11 } from "path";
41819
+ import { access as access18 } from "fs/promises";
41820
+ import { isAbsolute as isAbsolute10, relative as relative19, resolve as resolve21, sep as sep12 } from "path";
41206
41821
  import { pathToFileURL as pathToFileURL4 } from "url";
41207
41822
 
41208
41823
  // src/mobile/updateSigning.ts
41209
- import { createHash as createHash15, sign, verify } from "crypto";
41824
+ import { createHash as createHash16, sign, verify } from "crypto";
41210
41825
  import {
41211
41826
  cp as cp2,
41212
- mkdir as mkdir19,
41213
- mkdtemp as mkdtemp9,
41214
- readdir as readdir9,
41215
- readFile as readFile25,
41827
+ mkdir as mkdir20,
41828
+ mkdtemp as mkdtemp10,
41829
+ readdir as readdir10,
41830
+ readFile as readFile26,
41216
41831
  rename as rename18,
41217
- rm as rm14,
41218
- stat as stat5,
41832
+ rm as rm15,
41833
+ stat as stat6,
41219
41834
  writeFile as writeFile22
41220
41835
  } from "fs/promises";
41221
- import { dirname as dirname20, join as join29, relative as relative17, resolve as resolve19 } from "path";
41836
+ import { dirname as dirname21, join as join30, relative as relative18, resolve as resolve20 } from "path";
41222
41837
  var UPDATE_MANIFEST_FILE = "update.json";
41223
41838
  var UPDATE_FILES_DIRECTORY = "files";
41224
- var sha2563 = (value) => createHash15("sha256").update(value).digest("hex");
41839
+ var sha2564 = (value) => createHash16("sha256").update(value).digest("hex");
41225
41840
  var listFiles = async (root, directory = root) => {
41226
- const entries = await readdir9(directory, { withFileTypes: true });
41841
+ const entries = await readdir10(directory, { withFileTypes: true });
41227
41842
  const paths = await Promise.all(entries.map(async (entry) => {
41228
- const path = join29(directory, entry.name);
41843
+ const path = join30(directory, entry.name);
41229
41844
  if (entry.isDirectory())
41230
41845
  return listFiles(root, path);
41231
41846
  if (!entry.isFile())
41232
41847
  throw new TypeError("Mobile updates cannot contain links or special files.");
41233
- return [relative17(root, path).replaceAll("\\", "/")];
41848
+ return [relative18(root, path).replaceAll("\\", "/")];
41234
41849
  }));
41235
41850
  return paths.flat().sort((left, right) => left.localeCompare(right));
41236
41851
  };
41237
41852
  var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
41238
- const source = join29(root, path);
41853
+ const source = join30(root, path);
41239
41854
  const [metadata, contents] = await Promise.all([
41240
- stat5(source),
41241
- readFile25(source)
41855
+ stat6(source),
41856
+ readFile26(source)
41242
41857
  ]);
41243
- return { bytes: metadata.size, path, sha256: sha2563(contents) };
41858
+ return { bytes: metadata.size, path, sha256: sha2564(contents) };
41244
41859
  }));
41245
- var releaseIdFor = (value) => `amu_${sha2563(canonicalizeAbsoluteMobileUpdate(value))}`;
41860
+ var releaseIdFor = (value) => `amu_${sha2564(canonicalizeAbsoluteMobileUpdate(value))}`;
41246
41861
  var buildAbsoluteMobileUpdate = async (options) => {
41247
- const bundleDirectory = resolve19(options.bundleDirectory);
41248
- const outputRoot = resolve19(options.outputDirectory);
41862
+ const bundleDirectory = resolve20(options.bundleDirectory);
41863
+ const outputRoot = resolve20(options.outputDirectory);
41249
41864
  if (outputRoot === bundleDirectory || outputRoot.startsWith(`${bundleDirectory}/`))
41250
41865
  throw new TypeError("Mobile update output must be outside the embedded bundle.");
41251
41866
  const paths = await listFiles(bundleDirectory);
@@ -41273,38 +41888,38 @@ var buildAbsoluteMobileUpdate = async (options) => {
41273
41888
  value: signature.toString("base64")
41274
41889
  }
41275
41890
  });
41276
- await mkdir19(outputRoot, { recursive: true });
41277
- const outputDirectory = join29(outputRoot, manifest.releaseId);
41278
- const staging = await mkdtemp9(join29(outputRoot, ".stage-"));
41891
+ await mkdir20(outputRoot, { recursive: true });
41892
+ const outputDirectory = join30(outputRoot, manifest.releaseId);
41893
+ const staging = await mkdtemp10(join30(outputRoot, ".stage-"));
41279
41894
  try {
41280
- await cp2(bundleDirectory, join29(staging, UPDATE_FILES_DIRECTORY), {
41895
+ await cp2(bundleDirectory, join30(staging, UPDATE_FILES_DIRECTORY), {
41281
41896
  force: true,
41282
41897
  recursive: true
41283
41898
  });
41284
- await writeFile22(join29(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
41899
+ await writeFile22(join30(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
41285
41900
  `);
41286
41901
  await rename18(staging, outputDirectory);
41287
41902
  } catch (error) {
41288
- await rm14(staging, { force: true, recursive: true });
41903
+ await rm15(staging, { force: true, recursive: true });
41289
41904
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "EEXIST")
41290
41905
  throw new TypeError(`Mobile update ${manifest.releaseId} already exists.`, { cause: error });
41291
41906
  throw error;
41292
41907
  }
41293
41908
  return {
41294
41909
  manifest,
41295
- manifestPath: join29(outputDirectory, UPDATE_MANIFEST_FILE),
41910
+ manifestPath: join30(outputDirectory, UPDATE_MANIFEST_FILE),
41296
41911
  outputDirectory
41297
41912
  };
41298
41913
  };
41299
41914
  var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) => {
41300
- const source = resolve19(updateDirectory, UPDATE_FILES_DIRECTORY, path);
41301
- const root = resolve19(updateDirectory, UPDATE_FILES_DIRECTORY);
41915
+ const source = resolve20(updateDirectory, UPDATE_FILES_DIRECTORY, path);
41916
+ const root = resolve20(updateDirectory, UPDATE_FILES_DIRECTORY);
41302
41917
  if (!source.startsWith(`${root}/`))
41303
41918
  throw new TypeError("Update file escaped its release.");
41304
- await mkdir19(dirname20(destination), { recursive: true });
41919
+ await mkdir20(dirname21(destination), { recursive: true });
41305
41920
  await cp2(source, destination, { force: true });
41306
41921
  };
41307
- var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile25(join29(resolve19(directory), UPDATE_MANIFEST_FILE), "utf8")));
41922
+ var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile26(join30(resolve20(directory), UPDATE_MANIFEST_FILE), "utf8")));
41308
41923
  var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
41309
41924
  const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
41310
41925
  const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
@@ -41421,16 +42036,16 @@ var pruneAbsoluteMobileUpdates = async (options) => {
41421
42036
  var object5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
41422
42037
  var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "function" && typeof value.promoteUpdate === "function" && typeof value.rollbackUpdate === "function";
41423
42038
  var projectPath2 = (projectRoot, requested, label) => {
41424
- const root = resolve20(projectRoot);
41425
- const path = resolve20(root, requested);
41426
- const projectRelative = relative18(root, path);
41427
- if (projectRelative === ".." || projectRelative.startsWith(`..${sep11}`) || isAbsolute9(projectRelative))
42039
+ const root = resolve21(projectRoot);
42040
+ const path = resolve21(root, requested);
42041
+ const projectRelative = relative19(root, path);
42042
+ if (projectRelative === ".." || projectRelative.startsWith(`..${sep12}`) || isAbsolute10(projectRelative))
41428
42043
  throw new TypeError(`${label} must remain inside the project.`);
41429
42044
  return path;
41430
42045
  };
41431
42046
  var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
41432
42047
  const modulePath = projectPath2(projectRoot, requestedModulePath, "mobile update registry");
41433
- await access17(modulePath).catch(() => {
42048
+ await access18(modulePath).catch(() => {
41434
42049
  throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
41435
42050
  });
41436
42051
  const loaded = await import(pathToFileURL4(modulePath).href);
@@ -41481,7 +42096,7 @@ var rollbackAbsoluteMobileUpdate = async (options) => {
41481
42096
  return result;
41482
42097
  };
41483
42098
  // src/mobile/updateRollout.ts
41484
- import { createHash as createHash16 } from "crypto";
42099
+ import { createHash as createHash17 } from "crypto";
41485
42100
  var UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[1-8][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u;
41486
42101
  var requireHeader = (headers, name) => {
41487
42102
  const value = headers.get(name);
@@ -41496,7 +42111,7 @@ var isAbsoluteMobileUpdateRolloutMember = (options) => {
41496
42111
  return false;
41497
42112
  if (options.rollout === 1)
41498
42113
  return true;
41499
- const digest = createHash16("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
42114
+ const digest = createHash17("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
41500
42115
  const bucket = digest.readUInt32BE(0) / 4294967296;
41501
42116
  return bucket < options.rollout;
41502
42117
  };
@@ -41734,6 +42349,7 @@ export {
41734
42349
  publishAbsoluteIosRelease,
41735
42350
  publishAbsoluteMobileUpdate,
41736
42351
  readAbsoluteAndroidRelease,
42352
+ readAbsoluteIosRelease,
41737
42353
  readAbsoluteMobileLinkIntent,
41738
42354
  readAbsoluteMobileMaterializedReleases,
41739
42355
  readAbsoluteMobileUpdate,
@@ -41758,6 +42374,8 @@ export {
41758
42374
  rollbackAbsoluteMobileUpdate,
41759
42375
  runAbsoluteAndroidReleaseAcceptance,
41760
42376
  runAbsoluteAndroidUpgradeConformance,
42377
+ runAbsoluteIosDeviceReleaseAcceptance,
42378
+ runAbsoluteIosSimulatorReleaseAcceptance,
41761
42379
  runWithAbsoluteMobileProducer,
41762
42380
  serializeAbsoluteMobileAuthEnvironment,
41763
42381
  startAbsoluteExpoDevSession,
@@ -41783,5 +42401,5 @@ export {
41783
42401
  writeAbsoluteMobileUpdateRegistry
41784
42402
  };
41785
42403
 
41786
- //# debugId=6C1E943E101A0E8A64756E2164756E21
42404
+ //# debugId=E34FAEF09492010764756E2164756E21
41787
42405
  //# sourceMappingURL=index.js.map