@absolutejs/absolute 0.20.0-beta.115 → 0.20.0-beta.117

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 (35) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/changelog.json +38 -1
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  4. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  5. package/dist/build.js +9 -4
  6. package/dist/build.js.map +5 -4
  7. package/dist/cli/{androidEmulatorController-nybhzc6c.js → androidEmulatorController-v6chbhem.js} +2 -2
  8. package/dist/cli/{androidNativeWatcher-2930tb8c.js → androidNativeWatcher-mgqws6ag.js} +2 -2
  9. package/dist/cli/{compile-ya4kd2sg.js → compile-5m830csy.js} +2 -2
  10. package/dist/cli/{dev-5cqmf7za.js → dev-ww30tdrv.js} +10 -7
  11. package/dist/cli/{expoProject-f5j20xms.js → expoProject-w2pzjwnx.js} +1 -1
  12. package/dist/cli/{index-28pbrd3q.js → index-18q9qc7f.js} +15 -2
  13. package/dist/cli/{index-5fmgn0nx.js → index-5268nwjx.js} +1 -1
  14. package/dist/cli/{index-5skbydh0.js → index-hneb973j.js} +1 -1
  15. package/dist/cli/{index-6mbm4n3g.js → index-k8r00xh9.js} +1 -1
  16. package/dist/cli/{index-dr21p6ae.js → index-nxcwg9ma.js} +590 -152
  17. package/dist/cli/{index-qr0pc777.js → index-wtyg9cy0.js} +1 -1
  18. package/dist/cli/index.js +5 -5
  19. package/dist/cli/{iosNativeWatcher-t6gv0p1w.js → iosNativeWatcher-8w1gawg4.js} +2 -2
  20. package/dist/cli/{iosSimulatorController-5n2a9fxv.js → iosSimulatorController-5vhqvhg6.js} +2 -2
  21. package/dist/cli/{mobile-fg2226vv.js → mobile-21vsmrjd.js} +47 -56
  22. package/dist/cli/{start-jt61f40d.js → start-3bhf56tj.js} +3 -3
  23. package/dist/index.js +12 -6
  24. package/dist/index.js.map +6 -5
  25. package/dist/mobile/index.js +692 -274
  26. package/dist/mobile/index.js.map +8 -6
  27. package/dist/mobile/remoteMacAgentEntry.js +564 -231
  28. package/dist/mobile/shellBootstrap.js +6 -1
  29. package/dist/react/hooks/index.js.map +2 -2
  30. package/dist/src/dev/serverEntryCopies.d.ts +2 -0
  31. package/dist/src/mobile/capacitorProject.d.ts +4 -0
  32. package/dist/src/mobile/expoEmbeddedAssets.d.ts +1 -0
  33. package/dist/src/mobile/nativePackages.d.ts +10 -0
  34. package/dist/src/mobile/updateRuntime.d.ts +1 -0
  35. package/package.json +6 -2
@@ -1120,7 +1120,7 @@ __export(exports_associationFiles, {
1120
1120
  });
1121
1121
  import {
1122
1122
  access as access11,
1123
- mkdir as mkdir10,
1123
+ mkdir as mkdir11,
1124
1124
  readFile as readFile13,
1125
1125
  rename as rename10,
1126
1126
  rm as rm10,
@@ -1241,7 +1241,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1241
1241
  await rm10(backup, { force: true, recursive: true });
1242
1242
  }, materializeHost = async (root, host, files) => {
1243
1243
  const directory = resolve10(root, host, ".well-known");
1244
- await mkdir10(directory, { recursive: true });
1244
+ await mkdir11(directory, { recursive: true });
1245
1245
  return Promise.all(files.map(async ([name, document2]) => {
1246
1246
  const path = resolve10(directory, name);
1247
1247
  await writeAtomic(path, `${JSON.stringify(document2, null, 2)}
@@ -1277,7 +1277,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
1277
1277
  if (documents.apple) {
1278
1278
  files.push(["apple-app-site-association", documents.apple]);
1279
1279
  }
1280
- await mkdir10(temporary, { recursive: true });
1280
+ await mkdir11(temporary, { recursive: true });
1281
1281
  try {
1282
1282
  const temporaryPaths = (await Promise.all(config.deepLinkHosts.map((host) => materializeHost(temporary, host, files)))).flat();
1283
1283
  await writeAtomic(resolve10(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
@@ -1712,7 +1712,7 @@ __export(exports_materializedBundle, {
1712
1712
  import { createHash as createHash13 } from "crypto";
1713
1713
  import {
1714
1714
  access as access12,
1715
- mkdir as mkdir13,
1715
+ mkdir as mkdir14,
1716
1716
  mkdtemp as mkdtemp8,
1717
1717
  readFile as readFile16,
1718
1718
  rename as rename12,
@@ -1752,7 +1752,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1752
1752
  }, writeRelease = async (root, release) => {
1753
1753
  const directory = join14(root, release.artifact.releaseId);
1754
1754
  const producerPath = join14(directory, release.artifact.producer.module);
1755
- await mkdir13(dirname11(producerPath), { recursive: true });
1755
+ await mkdir14(dirname11(producerPath), { recursive: true });
1756
1756
  await Promise.all([
1757
1757
  writeFile13(join14(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
1758
1758
  `),
@@ -1833,7 +1833,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
1833
1833
  });
1834
1834
  const root = resolvePath4(input.root);
1835
1835
  const bundlesRoot = join14(root, BUNDLES_DIRECTORY);
1836
- await mkdir13(bundlesRoot, { recursive: true });
1836
+ await mkdir14(bundlesRoot, { recursive: true });
1837
1837
  const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
1838
1838
  await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
1839
1839
  const index = {
@@ -6439,24 +6439,24 @@ var require_pem = __commonJS(function(exports, module) {
6439
6439
  options = options || {};
6440
6440
  var rval = "-----BEGIN " + msg.type + `-----\r
6441
6441
  `;
6442
- var header;
6442
+ var header2;
6443
6443
  if (msg.procType) {
6444
- header = {
6444
+ header2 = {
6445
6445
  name: "Proc-Type",
6446
6446
  values: [String(msg.procType.version), msg.procType.type]
6447
6447
  };
6448
- rval += foldHeader(header);
6448
+ rval += foldHeader(header2);
6449
6449
  }
6450
6450
  if (msg.contentDomain) {
6451
- header = { name: "Content-Domain", values: [msg.contentDomain] };
6452
- rval += foldHeader(header);
6451
+ header2 = { name: "Content-Domain", values: [msg.contentDomain] };
6452
+ rval += foldHeader(header2);
6453
6453
  }
6454
6454
  if (msg.dekInfo) {
6455
- header = { name: "DEK-Info", values: [msg.dekInfo.algorithm] };
6455
+ header2 = { name: "DEK-Info", values: [msg.dekInfo.algorithm] };
6456
6456
  if (msg.dekInfo.parameters) {
6457
- header.values.push(msg.dekInfo.parameters);
6457
+ header2.values.push(msg.dekInfo.parameters);
6458
6458
  }
6459
- rval += foldHeader(header);
6459
+ rval += foldHeader(header2);
6460
6460
  }
6461
6461
  if (msg.headers) {
6462
6462
  for (var i = 0;i < msg.headers.length; ++i) {
@@ -6514,27 +6514,27 @@ var require_pem = __commonJS(function(exports, module) {
6514
6514
  }
6515
6515
  match = line.match(rHeader);
6516
6516
  if (match) {
6517
- var header = { name: match[1], values: [] };
6517
+ var header2 = { name: match[1], values: [] };
6518
6518
  var values = match[2].split(",");
6519
6519
  for (var vi = 0;vi < values.length; ++vi) {
6520
- header.values.push(ltrim(values[vi]));
6520
+ header2.values.push(ltrim(values[vi]));
6521
6521
  }
6522
6522
  if (!msg.procType) {
6523
- if (header.name !== "Proc-Type") {
6523
+ if (header2.name !== "Proc-Type") {
6524
6524
  throw new Error("Invalid PEM formatted message. The first " + 'encapsulated header must be "Proc-Type".');
6525
- } else if (header.values.length !== 2) {
6525
+ } else if (header2.values.length !== 2) {
6526
6526
  throw new Error('Invalid PEM formatted message. The "Proc-Type" ' + "header must have two subfields.");
6527
6527
  }
6528
6528
  msg.procType = { version: values[0], type: values[1] };
6529
- } else if (!msg.contentDomain && header.name === "Content-Domain") {
6529
+ } else if (!msg.contentDomain && header2.name === "Content-Domain") {
6530
6530
  msg.contentDomain = values[0] || "";
6531
- } else if (!msg.dekInfo && header.name === "DEK-Info") {
6532
- if (header.values.length === 0) {
6531
+ } else if (!msg.dekInfo && header2.name === "DEK-Info") {
6532
+ if (header2.values.length === 0) {
6533
6533
  throw new Error('Invalid PEM formatted message. The "DEK-Info" ' + "header must have at least one subfield.");
6534
6534
  }
6535
6535
  msg.dekInfo = { algorithm: values[0], parameters: values[1] || null };
6536
6536
  } else {
6537
- msg.headers.push(header);
6537
+ msg.headers.push(header2);
6538
6538
  }
6539
6539
  }
6540
6540
  ++li;
@@ -6548,14 +6548,14 @@ var require_pem = __commonJS(function(exports, module) {
6548
6548
  }
6549
6549
  return rval;
6550
6550
  };
6551
- function foldHeader(header) {
6552
- var rval = header.name + ": ";
6551
+ function foldHeader(header2) {
6552
+ var rval = header2.name + ": ";
6553
6553
  var values = [];
6554
6554
  var insertSpace = function(match, $1) {
6555
6555
  return " " + $1;
6556
6556
  };
6557
- for (var i = 0;i < header.values.length; ++i) {
6558
- values.push(header.values[i].replace(/^(\S+\r\n)/, insertSpace));
6557
+ for (var i = 0;i < header2.values.length; ++i) {
6558
+ values.push(header2.values[i].replace(/^(\S+\r\n)/, insertSpace));
6559
6559
  }
6560
6560
  rval += values.join(",") + `\r
6561
6561
  `;
@@ -7172,9 +7172,9 @@ var require_prng = __commonJS(function(exports, module) {
7172
7172
  _crypto = __require("crypto");
7173
7173
  }
7174
7174
  var prng = module.exports = forge.prng = forge.prng || {};
7175
- prng.create = function(plugin) {
7175
+ prng.create = function(plugin2) {
7176
7176
  var ctx = {
7177
- plugin,
7177
+ plugin: plugin2,
7178
7178
  key: null,
7179
7179
  seed: null,
7180
7180
  time: null,
@@ -7182,7 +7182,7 @@ var require_prng = __commonJS(function(exports, module) {
7182
7182
  generated: 0,
7183
7183
  keyBytes: ""
7184
7184
  };
7185
- var md = plugin.md;
7185
+ var md = plugin2.md;
7186
7186
  var pools2 = new Array(32);
7187
7187
  for (var i = 0;i < 32; ++i) {
7188
7188
  pools2[i] = md.create();
@@ -19453,7 +19453,7 @@ var init_compatibilityDispatcher = __esm(() => {
19453
19453
  // src/cli/scripts/telemetry.ts
19454
19454
  import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
19455
19455
  import { homedir as homedir4 } from "os";
19456
- import { join as join27 } from "path";
19456
+ import { join as join28 } from "path";
19457
19457
  var configDir, configPath, getTelemetryConfig = () => {
19458
19458
  try {
19459
19459
  if (!existsSync5(configPath))
@@ -19466,14 +19466,14 @@ var configDir, configPath, getTelemetryConfig = () => {
19466
19466
  }
19467
19467
  };
19468
19468
  var init_telemetry = __esm(() => {
19469
- configDir = join27(homedir4(), ".absolutejs");
19470
- configPath = join27(configDir, "telemetry.json");
19469
+ configDir = join28(homedir4(), ".absolutejs");
19470
+ configPath = join28(configDir, "telemetry.json");
19471
19471
  });
19472
19472
 
19473
19473
  // src/cli/telemetryEvent.ts
19474
19474
  import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
19475
19475
  import { arch, platform as platform3 } from "os";
19476
- import { dirname as dirname20, join as join28, parse } from "path";
19476
+ import { dirname as dirname20, join as join29, parse } from "path";
19477
19477
  var checkCandidate = (candidate) => {
19478
19478
  if (!existsSync6(candidate)) {
19479
19479
  return null;
@@ -19493,7 +19493,7 @@ var checkCandidate = (candidate) => {
19493
19493
  }, findPackageVersion = () => {
19494
19494
  let { dir } = import.meta;
19495
19495
  while (dir !== parse(dir).root) {
19496
- const candidate = join28(dir, "package.json");
19496
+ const candidate = join29(dir, "package.json");
19497
19497
  const version = checkCandidate(candidate);
19498
19498
  if (version) {
19499
19499
  return version;
@@ -21718,7 +21718,7 @@ import {
21718
21718
  createPublicKey as createPublicKey3,
21719
21719
  X509Certificate as X509Certificate4
21720
21720
  } from "crypto";
21721
- import { access as access24, mkdir as mkdir26 } from "fs/promises";
21721
+ import { access as access24, mkdir as mkdir27 } from "fs/promises";
21722
21722
  import { dirname as dirname26, isAbsolute as isAbsolute15, relative as relative25, resolve as resolve27, sep as sep17 } from "path";
21723
21723
  import { pathToFileURL as pathToFileURL5 } from "url";
21724
21724
  import { Elysia as Elysia4 } from "elysia";
@@ -21944,7 +21944,7 @@ ${generated}`);
21944
21944
  return;
21945
21945
  });
21946
21946
  }
21947
- await mkdir26(dirname26(path2), { recursive: true });
21947
+ await mkdir27(dirname26(path2), { recursive: true });
21948
21948
  await Bun.write(path2, renderAbsoluteMobileUpdateRegistry({
21949
21949
  ...options.health ? { health: options.health } : {},
21950
21950
  ...options.rollout ? { rollout: options.rollout } : {},
@@ -23686,7 +23686,7 @@ import { createHash as createHash5 } from "crypto";
23686
23686
  import {
23687
23687
  access as access6,
23688
23688
  copyFile as copyFile3,
23689
- mkdir as mkdir4,
23689
+ mkdir as mkdir5,
23690
23690
  mkdtemp as mkdtemp2,
23691
23691
  readFile as readFile6,
23692
23692
  realpath as realpath2,
@@ -23939,7 +23939,7 @@ import {
23939
23939
  access as access4,
23940
23940
  copyFile as copyFile2,
23941
23941
  lstat,
23942
- mkdir as mkdir3,
23942
+ mkdir as mkdir4,
23943
23943
  readFile as readFile4,
23944
23944
  readdir as readdir2,
23945
23945
  readlink,
@@ -23960,7 +23960,7 @@ import {
23960
23960
  } from "path";
23961
23961
 
23962
23962
  // src/mobile/capacitorProject.ts
23963
- import { access as access3, readFile as readFile3, rename as rename3, writeFile as writeFile3 } from "fs/promises";
23963
+ import { access as access3, mkdir as mkdir3, readFile as readFile3, rename as rename3, writeFile as writeFile3 } from "fs/promises";
23964
23964
  import { relative as relative2, resolve as resolve2 } from "path";
23965
23965
  var CONFIG_FILE = "capacitor.config.ts";
23966
23966
  var portableRelative2 = (root, path) => relative2(root, path).replaceAll("\\", "/");
@@ -23988,6 +23988,19 @@ var exists2 = async (path) => {
23988
23988
  return false;
23989
23989
  }
23990
23990
  };
23991
+ var prepareAbsoluteCapacitorInitialization = async (config) => {
23992
+ await mkdir3(config.bundleDirectory, { recursive: true });
23993
+ try {
23994
+ await writeFile3(resolve2(config.bundleDirectory, "index.html"), '<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>App preparation</title><body><main><h1>Your native project is ready</h1><p>Build your AbsoluteJS mobile bundle before running this app.</p></main></body></html>', { flag: "wx" });
23995
+ } catch (error) {
23996
+ if (!(error instanceof Error && ("code" in error) && error.code === "EEXIST"))
23997
+ throw error;
23998
+ }
23999
+ return Promise.all(config.platforms.map(async (platform2) => ({
24000
+ command: await exists2(resolve2(config.nativeProjectDirectory, platform2)) ? "sync" : "add",
24001
+ platform: platform2
24002
+ })));
24003
+ };
23991
24004
  var writeAbsoluteCapacitorConfig = async (config, options) => {
23992
24005
  const projectRoot = resolve2(options.projectRoot);
23993
24006
  const destination = resolve2(projectRoot, CONFIG_FILE);
@@ -25343,7 +25356,7 @@ var installRelease = async (artifactPath, metadata, outputRoot) => {
25343
25356
  }
25344
25357
  return { artifactPath: destination, metadata: existing, releaseRoot };
25345
25358
  }
25346
- await mkdir4(dirname3(releaseRoot), { recursive: true });
25359
+ await mkdir5(dirname3(releaseRoot), { recursive: true });
25347
25360
  const staging = await mkdtemp2(join6(dirname3(releaseRoot), ".android-stage-"));
25348
25361
  try {
25349
25362
  await copyFile3(artifactPath, join6(staging, artifactName));
@@ -25504,7 +25517,7 @@ var waitForAbsoluteAndroidNetworkServices = async (options) => {
25504
25517
  // src/mobile/androidReleaseAcceptance.ts
25505
25518
  import {
25506
25519
  access as access7,
25507
- mkdir as mkdir5,
25520
+ mkdir as mkdir6,
25508
25521
  mkdtemp as mkdtemp3,
25509
25522
  readFile as readFile7,
25510
25523
  rename as rename6,
@@ -25723,7 +25736,7 @@ var ensureAbsoluteBundletool = async (options) => {
25723
25736
  const digest = createHash6("sha256").update(bytes).digest("hex");
25724
25737
  if (digest !== ABSOLUTE_BUNDLETOOL_SHA256)
25725
25738
  throw new TypeError("Downloaded Bundletool failed checksum verification.");
25726
- await mkdir5(dirname4(inspected.path), { recursive: true });
25739
+ await mkdir6(dirname4(inspected.path), { recursive: true });
25727
25740
  const staging = await mkdtemp3(join7(dirname4(inspected.path), ".install-"));
25728
25741
  const candidate = join7(staging, "bundletool.jar");
25729
25742
  try {
@@ -25800,7 +25813,7 @@ var runAbsoluteAndroidReleaseAcceptance = async (options) => {
25800
25813
  throw new TypeError("Installed release acceptance changes network state and therefore requires an Android emulator.");
25801
25814
  const run = options.run ?? defaultRun;
25802
25815
  const startedAt = performance.now();
25803
- await mkdir5(options.artifactDirectory, { recursive: true });
25816
+ await mkdir6(options.artifactDirectory, { recursive: true });
25804
25817
  const apksPath = join7(options.artifactDirectory, "release.apks");
25805
25818
  const windowsJava = (options.host ?? detectAbsoluteMobileHost()) === "wsl" && options.java.toLowerCase().endsWith(".exe");
25806
25819
  const toolPath = async (path) => {
@@ -25897,7 +25910,7 @@ import { createHash as createHash7 } from "crypto";
25897
25910
  import {
25898
25911
  access as access8,
25899
25912
  copyFile as copyFile4,
25900
- mkdir as mkdir6,
25913
+ mkdir as mkdir7,
25901
25914
  mkdtemp as mkdtemp4,
25902
25915
  readdir as readdir3,
25903
25916
  readFile as readFile8,
@@ -26159,7 +26172,7 @@ var installRelease2 = async (artifactPath, metadata, outputRoot, registeredArtif
26159
26172
  releaseRoot
26160
26173
  };
26161
26174
  }
26162
- await mkdir6(dirname5(releaseRoot), { recursive: true });
26175
+ await mkdir7(dirname5(releaseRoot), { recursive: true });
26163
26176
  const staging = await mkdtemp4(join8(dirname5(releaseRoot), ".ios-stage-"));
26164
26177
  try {
26165
26178
  await copyFile4(artifactPath, join8(staging, "App.ipa"));
@@ -26188,7 +26201,7 @@ var installRelease2 = async (artifactPath, metadata, outputRoot, registeredArtif
26188
26201
  var exportRegisteredDeviceArtifact = async (options) => {
26189
26202
  const exportPath = join8(options.staging, "registered-export");
26190
26203
  const exportPlist = join8(options.staging, "RegisteredExportOptions.plist");
26191
- await mkdir6(exportPath, { recursive: true });
26204
+ await mkdir7(exportPath, { recursive: true });
26192
26205
  await writeFile7(exportPlist, exportOptions("debugging"));
26193
26206
  const exitCode = await options.run([
26194
26207
  "xcodebuild",
@@ -26238,12 +26251,12 @@ var buildAbsoluteIosRelease = async (options) => {
26238
26251
  buildNumber = requireBuildNumber(await options.prepareBuildNumber(buildIdentity));
26239
26252
  }
26240
26253
  const stagingParent = resolve6(options.projectRoot, ".absolutejs/mobile");
26241
- await mkdir6(stagingParent, { recursive: true });
26254
+ await mkdir7(stagingParent, { recursive: true });
26242
26255
  const staging = await mkdtemp4(join8(stagingParent, ".ios-build-"));
26243
26256
  const archivePath = join8(staging, "App.xcarchive");
26244
26257
  const exportPath = join8(staging, "export");
26245
26258
  const exportPlist = join8(staging, "ExportOptions.plist");
26246
- await mkdir6(exportPath, { recursive: true });
26259
+ await mkdir7(exportPath, { recursive: true });
26247
26260
  await writeFile7(exportPlist, exportOptions("app-store-connect"));
26248
26261
  const run = options.run ?? defaultRun2;
26249
26262
  try {
@@ -26355,7 +26368,7 @@ var installAbsoluteIosRelease = async (options) => {
26355
26368
  import { createHash as createHash8 } from "crypto";
26356
26369
  import {
26357
26370
  access as access9,
26358
- mkdir as mkdir7,
26371
+ mkdir as mkdir8,
26359
26372
  mkdtemp as mkdtemp5,
26360
26373
  readFile as readFile9,
26361
26374
  readdir as readdir4,
@@ -26593,7 +26606,7 @@ var runAbsoluteIosSimulatorReleaseAcceptance = async (options) => {
26593
26606
  const iosRoot = join9(options.config.nativeProjectDirectory, "ios");
26594
26607
  const xcode = await resolveAbsoluteIosXcodeProject(iosRoot);
26595
26608
  const derivedData = join9(options.artifactDirectory, "DerivedData");
26596
- await mkdir7(options.artifactDirectory, { recursive: true });
26609
+ await mkdir8(options.artifactDirectory, { recursive: true });
26597
26610
  await requireSuccess3(run, [
26598
26611
  xcodebuild,
26599
26612
  "-workspace",
@@ -26899,7 +26912,7 @@ import { createHash as createHash9, randomUUID as randomUUID3 } from "crypto";
26899
26912
  import {
26900
26913
  access as access10,
26901
26914
  copyFile as copyFile5,
26902
- mkdir as mkdir8,
26915
+ mkdir as mkdir9,
26903
26916
  readFile as readFile11,
26904
26917
  rename as rename8,
26905
26918
  rm as rm8,
@@ -27230,7 +27243,7 @@ var writeDevProjection = async (project, port, https, serverHost = "localhost")
27230
27243
  const parsed = JSON.parse(configSource);
27231
27244
  if (!isRecord4(parsed))
27232
27245
  throw new Error(`Invalid Capacitor native config at ${nativeConfigPath}.`);
27233
- await mkdir8(paths.root, { recursive: true });
27246
+ await mkdir9(paths.root, { recursive: true });
27234
27247
  await Promise.all([
27235
27248
  writeFile8(paths.configBackup, configSource, { flag: "wx" }),
27236
27249
  writeFile8(paths.infoBackup, infoSource, { flag: "wx" })
@@ -27281,7 +27294,7 @@ var readNativeCache = (projectRoot) => readFile11(nativeCachePath(projectRoot),
27281
27294
  var writeNativeCache = async (projectRoot, cache) => {
27282
27295
  const destination = nativeCachePath(projectRoot);
27283
27296
  const temporary = `${destination}.${process.pid}.${randomUUID3()}.tmp`;
27284
- await mkdir8(dirname7(destination), { recursive: true });
27297
+ await mkdir9(dirname7(destination), { recursive: true });
27285
27298
  try {
27286
27299
  await writeFile8(temporary, `${JSON.stringify(cache, null, "\t")}
27287
27300
  `, {
@@ -27396,7 +27409,7 @@ var physicalIosAppIsInstalled = (project, identifier, capture) => {
27396
27409
  };
27397
27410
  var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
27398
27411
  const derivedDataPath = join10(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash9("sha256").update(project.config.appId).digest("hex").slice(0, 16));
27399
- await mkdir8(derivedDataPath, { recursive: true });
27412
+ await mkdir9(derivedDataPath, { recursive: true });
27400
27413
  await requireSuccess4([
27401
27414
  project.xcodebuild,
27402
27415
  "-workspace",
@@ -27418,7 +27431,7 @@ var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
27418
27431
  };
27419
27432
  var buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
27420
27433
  const derivedDataPath = join10(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash9("sha256").update(project.config.appId).digest("hex").slice(0, 16));
27421
- await mkdir8(derivedDataPath, { recursive: true });
27434
+ await mkdir9(derivedDataPath, { recursive: true });
27422
27435
  await requireSuccess4([
27423
27436
  project.xcodebuild,
27424
27437
  "-workspace",
@@ -27582,7 +27595,7 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
27582
27595
  if (!await pathExists5(cap))
27583
27596
  throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
27584
27597
  await writeAbsoluteCapacitorConfig(config, { projectRoot });
27585
- await mkdir8(config.bundleDirectory, { recursive: true });
27598
+ await mkdir9(config.bundleDirectory, { recursive: true });
27586
27599
  const placeholder = join10(config.bundleDirectory, "index.html");
27587
27600
  if (!await pathExists5(placeholder))
27588
27601
  await writeFile8(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
@@ -27818,7 +27831,7 @@ var startAbsoluteIosDevSession = async (options) => {
27818
27831
  const resolved = resolve8(project.projectRoot, destination);
27819
27832
  if (!isInside(project.projectRoot, resolved))
27820
27833
  throw new Error("iOS screenshot destination must remain inside the project.");
27821
- await mkdir8(dirname7(resolved), { recursive: true });
27834
+ await mkdir9(dirname7(resolved), { recursive: true });
27822
27835
  await requireSuccess4([
27823
27836
  project.xcrun,
27824
27837
  "simctl",
@@ -27940,7 +27953,7 @@ var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename3(pa
27940
27953
  import { createHash as createHash10, randomUUID as randomUUID4 } from "crypto";
27941
27954
  import {
27942
27955
  chmod,
27943
- mkdir as mkdir9,
27956
+ mkdir as mkdir10,
27944
27957
  mkdtemp as mkdtemp6,
27945
27958
  readFile as readFile12,
27946
27959
  rename as rename9,
@@ -27995,7 +28008,7 @@ var loadStore = async (path = defaultProfilePath()) => {
27995
28008
  }
27996
28009
  };
27997
28010
  var saveStore = async (store, path = defaultProfilePath()) => {
27998
- await mkdir9(dirname8(path), { recursive: true });
28011
+ await mkdir10(dirname8(path), { recursive: true });
27999
28012
  const temporary = `${path}.${randomUUID4()}.tmp`;
28000
28013
  await writeFile9(temporary, `${JSON.stringify(store, null, 2)}
28001
28014
  `, {
@@ -28354,7 +28367,7 @@ var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
28354
28367
  if (!source)
28355
28368
  throw new Error("The AbsoluteJS installation does not contain its remote Mac agent artifact.");
28356
28369
  const outdir = join11(resolvePath3(projectRoot), ".absolutejs", "mobile", "remote-agent");
28357
- await mkdir9(outdir, { recursive: true });
28370
+ await mkdir10(outdir, { recursive: true });
28358
28371
  const result = await Bun.build({
28359
28372
  entrypoints: [source],
28360
28373
  minify: true,
@@ -28590,7 +28603,7 @@ var writeRemoteArtifact = async (path, stream) => {
28590
28603
  var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory) => {
28591
28604
  const releaseRoot = posix.join(project.remoteProjectRoot, ".absolutejs", "mobile", "releases", "ios", metadata.releaseId);
28592
28605
  const stagingParent = join11(project.projectRoot, ".absolutejs", "mobile");
28593
- await mkdir9(stagingParent, { recursive: true });
28606
+ await mkdir10(stagingParent, { recursive: true });
28594
28607
  const staging = await mkdtemp6(join11(stagingParent, ".remote-ios-"));
28595
28608
  try {
28596
28609
  const remoteMetadata = requireRemoteSuccess(await defaultTransport.capture([
@@ -29294,7 +29307,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
29294
29307
  const targetRelative = relative9(options.project.projectRoot, target);
29295
29308
  if (targetRelative.startsWith("..") || isAbsolute7(targetRelative))
29296
29309
  throw new Error("iOS screenshot must remain inside the project.");
29297
- await mkdir9(dirname8(target), { recursive: true });
29310
+ await mkdir10(dirname8(target), { recursive: true });
29298
29311
  await writeFile9(target, Buffer.from(result.data, "base64"));
29299
29312
  return target;
29300
29313
  },
@@ -29376,12 +29389,12 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
29376
29389
  };
29377
29390
  // src/mobile/buildPipeline.ts
29378
29391
  import { readFile as readFile18 } from "fs/promises";
29379
- import { join as join21, resolve as resolve16 } from "path";
29392
+ import { join as join22, resolve as resolve16 } from "path";
29380
29393
  import { pathToFileURL as pathToFileURL2 } from "url";
29381
29394
 
29382
29395
  // src/mobile/buildRelease.ts
29383
29396
  import { createHash as createHash12 } from "crypto";
29384
- import { mkdir as mkdir11, readFile as readFile14, writeFile as writeFile11 } from "fs/promises";
29397
+ import { mkdir as mkdir12, readFile as readFile14, writeFile as writeFile11 } from "fs/promises";
29385
29398
  import { basename as basename4, dirname as dirname9, extname, join as join12, relative as relative10, resolve as resolve11 } from "path";
29386
29399
  init_releaseArtifact();
29387
29400
  var sha2563 = (bytes) => createHash12("sha256").update(bytes).digest("hex");
@@ -29413,7 +29426,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
29413
29426
  const rewritten = rewriteStaticScriptPaths(source, manifest);
29414
29427
  const documentHash = sha2563(new TextEncoder().encode(rewritten));
29415
29428
  resolvedAssetPath = join12(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
29416
- await mkdir11(dirname9(resolvedAssetPath), { recursive: true });
29429
+ await mkdir12(dirname9(resolvedAssetPath), { recursive: true });
29417
29430
  await writeFile11(resolvedAssetPath, rewritten);
29418
29431
  }
29419
29432
  const pageAssetKey = metadata.bundleKey.replace(/Index$/u, "");
@@ -29535,7 +29548,7 @@ init_routeMatcher();
29535
29548
  import {
29536
29549
  cp,
29537
29550
  copyFile as copyFile6,
29538
- mkdir as mkdir12,
29551
+ mkdir as mkdir13,
29539
29552
  mkdtemp as mkdtemp7,
29540
29553
  readFile as readFile15,
29541
29554
  rename as rename11,
@@ -29975,7 +29988,7 @@ var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) =
29975
29988
  const styleExtension = extname2(page.styleBundlePath) || ".css";
29976
29989
  localStylePath = `./styles/${page.styleBundleHash}${styleExtension}`;
29977
29990
  const styleSource = sourceAssetPath(buildDirectory, page.styleBundlePath);
29978
- await mkdir12(dirname10(join13(staging, localStylePath)), {
29991
+ await mkdir13(dirname10(join13(staging, localStylePath)), {
29979
29992
  recursive: true
29980
29993
  });
29981
29994
  await copyFile6(styleSource, join13(staging, localStylePath));
@@ -30002,7 +30015,7 @@ var materializeAbsoluteMobileSourcemaps = async (pages, appBuild, projectRoot) =
30002
30015
  return existsSync2(source) ? [{ page, source }] : [];
30003
30016
  });
30004
30017
  if (available.length > 0)
30005
- await mkdir12(releaseRoot, { recursive: true });
30018
+ await mkdir13(releaseRoot, { recursive: true });
30006
30019
  await Promise.all(available.map(async ({ page, source }) => {
30007
30020
  const extension = extname2(page.bundlePath) || ".js";
30008
30021
  if (!/^\.[a-z0-9]+$/iu.test(extension))
@@ -30061,7 +30074,7 @@ var copyAbsoluteClientDependency = async (specifier, buildDirectory, staging, co
30061
30074
  copied.add(specifier);
30062
30075
  const source = sourceAssetPath(buildDirectory, specifier);
30063
30076
  const destination = join13(staging, specifier.replace(/^\/+/, ""));
30064
- await mkdir12(dirname10(destination), { recursive: true });
30077
+ await mkdir13(dirname10(destination), { recursive: true });
30065
30078
  await copyFile6(source, destination);
30066
30079
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
30067
30080
  };
@@ -30074,11 +30087,11 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
30074
30087
  throw new TypeError(`mobile.entry ${options.config.entry} is not a captured mobile page route.`);
30075
30088
  }
30076
30089
  const destination = options.config.bundleDirectory;
30077
- await mkdir12(dirname10(destination), { recursive: true });
30090
+ await mkdir13(dirname10(destination), { recursive: true });
30078
30091
  const staging = await mkdtemp7(join13(dirname10(destination), `.${basename5(destination)}.stage-`));
30079
30092
  try {
30080
30093
  const pageDirectory = join13(staging, "pages");
30081
- await mkdir12(pageDirectory, { recursive: true });
30094
+ await mkdir13(pageDirectory, { recursive: true });
30082
30095
  await Promise.all(CLIENT_ASSET_DIRECTORIES.map((directory) => ({
30083
30096
  destination: join13(staging, directory),
30084
30097
  source: join13(options.buildDirectory, directory)
@@ -30140,12 +30153,9 @@ init_releaseArtifact();
30140
30153
  init_deviceCapabilities();
30141
30154
 
30142
30155
  // src/mobile/expoProject.ts
30143
- init_nativeAuth();
30144
- init_syncSchema();
30145
- init_deviceCapabilities();
30146
30156
  import {
30147
30157
  access as access13,
30148
- mkdir as mkdir14,
30158
+ mkdir as mkdir15,
30149
30159
  mkdtemp as mkdtemp9,
30150
30160
  readdir as readdir5,
30151
30161
  readFile as readFile17,
@@ -30154,7 +30164,39 @@ import {
30154
30164
  writeFile as writeFile14
30155
30165
  } from "fs/promises";
30156
30166
  import { createHash as createHash15 } from "crypto";
30157
- import { basename as basename6, dirname as dirname13, join as join20, relative as relative13, resolve as resolve15, sep as sep8 } from "path";
30167
+ import { basename as basename6, dirname as dirname13, join as join21, relative as relative13, resolve as resolve15, sep as sep8 } from "path";
30168
+
30169
+ // src/mobile/nativePackages.ts
30170
+ var ABSOLUTE_CAPACITOR_DEVICES_VERSION = "0.8.0";
30171
+ var ABSOLUTE_CAPACITOR_SYNC_VERSION = "0.9.3";
30172
+ var ABSOLUTE_DEVICES_VERSION = "0.7.0";
30173
+ var ABSOLUTE_EXPO_DEVICES_VERSION = "0.0.11";
30174
+ var ABSOLUTE_NATIVE_EXACT_PACKAGES = new Set([
30175
+ "@absolutejs/devices",
30176
+ "@absolutejs/devices-capacitor",
30177
+ "@absolutejs/sync-capacitor"
30178
+ ]);
30179
+ var CAPACITOR_PACKAGE_SPECS = [
30180
+ "@capacitor/core@8.5.0",
30181
+ "@capacitor/app@8.1.1",
30182
+ "@capacitor/browser@8.0.4",
30183
+ "@capacitor/network@8.0.1",
30184
+ "@capacitor/preferences@8.0.1",
30185
+ "@capacitor/cli@8.5.0",
30186
+ "@capacitor/android@8.5.0",
30187
+ "@capacitor/ios@8.5.0",
30188
+ `@absolutejs/devices@${ABSOLUTE_DEVICES_VERSION}`,
30189
+ `@absolutejs/devices-capacitor@${ABSOLUTE_CAPACITOR_DEVICES_VERSION}`
30190
+ ];
30191
+ var CAPACITOR_SYNC_PACKAGE_SPECS = [
30192
+ `@absolutejs/sync-capacitor@${ABSOLUTE_CAPACITOR_SYNC_VERSION}`,
30193
+ "@capacitor-community/sqlite@8.1.1"
30194
+ ];
30195
+
30196
+ // src/mobile/expoProject.ts
30197
+ init_nativeAuth();
30198
+ init_syncSchema();
30199
+ init_deviceCapabilities();
30158
30200
 
30159
30201
  // src/mobile/updateRuntime.ts
30160
30202
  init_deviceCapabilities();
@@ -30295,6 +30337,7 @@ var createAbsoluteMobileUpdateRuntimeDescriptor = (options) => ({
30295
30337
  },
30296
30338
  deviceCapabilities: options.deviceCapabilities,
30297
30339
  engine: options.config.engine,
30340
+ ...options.config.engine === "expo" ? { expoEmbeddedAssetsAbi: 1 } : {},
30298
30341
  format: ABSOLUTE_MOBILE_UPDATE_RUNTIME_FORMAT,
30299
30342
  shellAbi: ABSOLUTE_MOBILE_SHELL_ABI,
30300
30343
  syncSchema: options.syncSchema ?? null,
@@ -31064,6 +31107,265 @@ var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
31064
31107
  ]
31065
31108
  ]);
31066
31109
 
31110
+ // src/mobile/expoEmbeddedAssets.ts
31111
+ import { join as join20 } from "path";
31112
+ var header = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
31113
+ `;
31114
+ var android = `${header}package expo.modules.absoluteembeddedassets
31115
+
31116
+ import android.content.Context
31117
+ import android.graphics.Bitmap
31118
+ import android.net.Uri
31119
+ import android.util.Log
31120
+ import android.webkit.WebResourceRequest
31121
+ import android.webkit.WebResourceResponse
31122
+ import android.webkit.WebView
31123
+ import androidx.webkit.WebViewAssetLoader
31124
+ import androidx.webkit.WebViewCompat
31125
+ import androidx.webkit.WebViewFeature
31126
+ import androidx.webkit.ScriptHandler
31127
+ import androidx.webkit.WebMessageCompat
31128
+ import com.facebook.react.ReactPackage
31129
+ import com.facebook.react.bridge.NativeModule
31130
+ import com.facebook.react.bridge.ReactApplicationContext
31131
+ import com.facebook.react.bridge.ReadableMap
31132
+ import com.facebook.react.uimanager.ThemedReactContext
31133
+ import com.facebook.react.uimanager.ViewManager
31134
+ import com.reactnativecommunity.webview.RNCWebViewClient
31135
+ import com.reactnativecommunity.webview.RNCWebViewManager
31136
+ import com.reactnativecommunity.webview.RNCWebViewWrapper
31137
+ import expo.modules.kotlin.modules.Module
31138
+ import expo.modules.kotlin.modules.ModuleDefinition
31139
+ import java.io.ByteArrayInputStream
31140
+ import java.io.File
31141
+ import java.util.concurrent.ConcurrentHashMap
31142
+ import java.util.WeakHashMap
31143
+
31144
+ private const val HOST = "appassets.androidplatform.net"
31145
+ private const val PREFIX = "/absolutejs/"
31146
+
31147
+ internal object AbsoluteEmbeddedAssets {
31148
+ private val bundles = ConcurrentHashMap<String, Map<String, File>>()
31149
+
31150
+ fun register(context: Context, rootUri: String, paths: List<String>): String {
31151
+ check(WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT) &&
31152
+ WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
31153
+ "Update Android System WebView to load this application."
31154
+ }
31155
+ val uri = Uri.parse(rootUri)
31156
+ require(uri.scheme == "file" && uri.authority.isNullOrEmpty() && uri.query == null && uri.fragment == null)
31157
+ val root = File(requireNotNull(uri.path)).canonicalFile
31158
+ val parent = File(context.filesDir, "absolutejs-web").canonicalFile
31159
+ require(root.parentFile == parent && root.name.matches(Regex("amexpo_[a-f0-9]{64}")))
31160
+ require(paths.isNotEmpty() && paths.size <= 100000 && paths.distinct().size == paths.size)
31161
+ val files = paths.associateWith { path ->
31162
+ require(path.isNotEmpty() && !path.contains('\\\\') && !path.contains('%') &&
31163
+ !path.contains('?') && !path.contains('#') && path.indexOf(0.toChar()) < 0 &&
31164
+ path.split('/').all { it.isNotEmpty() && it != "." && it != ".." })
31165
+ val file = File(root, path).canonicalFile
31166
+ require(file.path.startsWith(root.path + File.separator) && file.isFile)
31167
+ file
31168
+ }
31169
+ require(files.containsKey("index.html") && files.containsKey("absolute-mobile-manifest.json"))
31170
+ bundles[root.name] = files
31171
+ Log.i("AbsoluteJS", "Expo embedded web phase: asset-host-registered")
31172
+ return "https://" + HOST + PREFIX + root.name + "/index.html"
31173
+ }
31174
+
31175
+ private fun empty(status: Int, reason: String) = WebResourceResponse(
31176
+ "text/plain", "UTF-8", status, reason,
31177
+ mapOf("Cache-Control" to "no-store", "X-Content-Type-Options" to "nosniff"),
31178
+ ByteArrayInputStream(ByteArray(0))
31179
+ )
31180
+
31181
+ private fun resource(path: String): WebResourceResponse {
31182
+ val bundle = path.substringBefore('/')
31183
+ val name = path.substringAfter('/', "")
31184
+ val file = bundles[bundle]?.get(name) ?: return empty(404, "Not Found")
31185
+ // Recheck canonical location at read time. Never follow a replaced symlink.
31186
+ if (file.canonicalFile != file || !file.isFile) return empty(404, "Not Found")
31187
+ val mime = when (file.extension.lowercase()) {
31188
+ "html", "htm" -> "text/html"
31189
+ "js", "mjs" -> "text/javascript"
31190
+ "json", "map" -> "application/json"
31191
+ "css" -> "text/css"
31192
+ "svg" -> "image/svg+xml"
31193
+ "wasm" -> "application/wasm"
31194
+ else -> android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension.lowercase()) ?: "application/octet-stream"
31195
+ }
31196
+ return try {
31197
+ WebResourceResponse(mime, "UTF-8", 200, "OK",
31198
+ mapOf("Cache-Control" to "no-store", "X-Content-Type-Options" to "nosniff"), file.inputStream())
31199
+ } catch (_: Exception) { empty(404, "Not Found") }
31200
+ }
31201
+
31202
+ private val loader = WebViewAssetLoader.Builder()
31203
+ .setDomain(HOST).setHttpAllowed(false)
31204
+ .addPathHandler(PREFIX) { path -> resource(path) }.build()
31205
+
31206
+ fun intercept(request: WebResourceRequest, activeBundle: String?): WebResourceResponse? {
31207
+ val uri = request.url
31208
+ if (uri.host != HOST) return null
31209
+ if (uri.path.orEmpty().endsWith("/index.html")) Log.i("AbsoluteJS", "Expo embedded web phase: document-request")
31210
+ if (uri.path.orEmpty().endsWith("/absolute-mobile-bootstrap.js")) Log.i("AbsoluteJS", "Expo embedded web phase: bootstrap-request")
31211
+ // A reserved asset host must never fall through to DNS/network, even for
31212
+ // unknown bundles, wrong ports/schemes, methods, or malformed paths.
31213
+ if (uri.scheme != "https" || uri.port != -1 || uri.userInfo != null ||
31214
+ request.method != "GET") return empty(403, "Forbidden")
31215
+ // Root-relative image/font/CSS URLs retain their web meaning. Scope them
31216
+ // to this WebView's bundle, not the last bundle registered by another view.
31217
+ if (!uri.path.orEmpty().startsWith(PREFIX)) {
31218
+ if (request.isForMainFrame || activeBundle == null) return empty(404, "Not Found")
31219
+ return resource(activeBundle + "/" + uri.path.orEmpty().removePrefix("/"))
31220
+ }
31221
+ return loader.shouldInterceptRequest(uri) ?: empty(404, "Not Found")
31222
+ }
31223
+ }
31224
+
31225
+ class AbsoluteEmbeddedAssetsModule : Module() {
31226
+ override fun definition() = ModuleDefinition {
31227
+ Name("AbsoluteEmbeddedAssets")
31228
+ AsyncFunction("registerBundle") { root: String, paths: List<String> ->
31229
+ AbsoluteEmbeddedAssets.register(requireNotNull(appContext.reactContext), root, paths)
31230
+ }
31231
+ }
31232
+ }
31233
+
31234
+ class AbsoluteEmbeddedWebViewManager : RNCWebViewManager() {
31235
+ private val scripts = WeakHashMap<RNCWebViewWrapper, ScriptHandler>()
31236
+ override fun getName() = "AbsoluteEmbeddedWebView"
31237
+ override fun setNewSource(view: RNCWebViewWrapper, value: ReadableMap?) {
31238
+ Log.i("AbsoluteJS", "Expo embedded web phase: source-assigned")
31239
+ super.setNewSource(view, value)
31240
+ }
31241
+ override fun setMessagingEnabled(view: RNCWebViewWrapper, value: Boolean) {
31242
+ super.setMessagingEnabled(view, value)
31243
+ // Upstream reports sourceOrigin as event.url and accepts subframe messages.
31244
+ // Retain its event dispatch, but bind this bridge to our main-frame origin
31245
+ // and attach the native-observed document URL, never a JS-supplied URL.
31246
+ if (!WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) return
31247
+ WebViewCompat.removeWebMessageListener(view.webView, "ReactNativeWebView")
31248
+ if (!value) return
31249
+ WebViewCompat.addWebMessageListener(view.webView, "ReactNativeWebView", setOf("https://" + HOST)) {
31250
+ webView, message, sourceOrigin, isMainFrame, _ ->
31251
+ if (isMainFrame && sourceOrigin.scheme == "https" && sourceOrigin.host == HOST &&
31252
+ message.type == WebMessageCompat.TYPE_STRING) {
31253
+ val url = webView.url
31254
+ val data = message.data
31255
+ if (url != null && data != null) view.webView.onMessage(data, url)
31256
+ }
31257
+ }
31258
+ }
31259
+ override fun setInjectedJavaScriptBeforeContentLoaded(view: RNCWebViewWrapper, value: String?) {
31260
+ scripts.remove(view)?.remove()
31261
+ if (value == null) return
31262
+ // onPageStarted injection races module execution on Android. Register with
31263
+ // Chromium before navigation, scoped to our virtual asset origin only.
31264
+ check(WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
31265
+ "AbsoluteJS requires an Android System WebView with document-start script support."
31266
+ }
31267
+ scripts[view] = WebViewCompat.addDocumentStartJavaScript(view.webView, value, setOf("https://" + HOST))
31268
+ }
31269
+ override fun onDropViewInstance(view: RNCWebViewWrapper) {
31270
+ scripts.remove(view)?.remove()
31271
+ if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER))
31272
+ WebViewCompat.removeWebMessageListener(view.webView, "ReactNativeWebView")
31273
+ super.onDropViewInstance(view)
31274
+ }
31275
+ override fun addEventEmitters(context: ThemedReactContext, view: RNCWebViewWrapper) {
31276
+ Log.i("AbsoluteJS", "Expo embedded web phase: asset-host-view-created")
31277
+ view.webView.webViewClient = object : RNCWebViewClient() {
31278
+ @Volatile private var activeBundle: String? = null
31279
+ override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
31280
+ Log.i("AbsoluteJS", "Expo embedded web phase: document-started")
31281
+ val uri = Uri.parse(url)
31282
+ activeBundle = if (uri.scheme == "https" && uri.host == HOST && uri.path.orEmpty().startsWith(PREFIX))
31283
+ uri.path!!.removePrefix(PREFIX).substringBefore('/') else null
31284
+ super.onPageStarted(view, url, favicon)
31285
+ }
31286
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? =
31287
+ AbsoluteEmbeddedAssets.intercept(request, activeBundle) ?: super.shouldInterceptRequest(view, request)
31288
+ }
31289
+ }
31290
+ }
31291
+
31292
+ class AbsoluteEmbeddedWebViewPackage : ReactPackage {
31293
+ override fun createNativeModules(context: ReactApplicationContext): List<NativeModule> = emptyList()
31294
+ override fun createViewManagers(context: ReactApplicationContext): List<ViewManager<*, *>> = listOf(AbsoluteEmbeddedWebViewManager())
31295
+ }
31296
+ `;
31297
+ var plugin = `${header}const { withMainApplication } = require('expo/config-plugins');
31298
+ module.exports = config => withMainApplication(config, value => {
31299
+ if (value.modResults.language !== 'kt') throw new Error('AbsoluteJS embedded assets require the managed Kotlin application.');
31300
+ const name = 'expo.modules.absoluteembeddedassets.AbsoluteEmbeddedWebViewPackage';
31301
+ const registration = 'add(' + name + '())';
31302
+ const source = value.modResults.contents;
31303
+ if (!source.includes(registration)) {
31304
+ const anchor = 'PackageList(this).packages.apply {';
31305
+ if (source.split(anchor).length !== 2) throw new Error('Cannot safely register AbsoluteJS embedded WebView in MainApplication.');
31306
+ value.modResults.contents = source.replace(anchor, anchor + '\\n ' + registration);
31307
+ }
31308
+ return value;
31309
+ });
31310
+ `;
31311
+ var runtime2 = `${header}import { requireNativeModule } from 'expo-modules-core';
31312
+ import { Platform, requireNativeComponent } from 'react-native';
31313
+
31314
+ export const absoluteEmbeddedNativeConfig = Platform.OS === 'android'
31315
+ ? { component: requireNativeComponent('AbsoluteEmbeddedWebView') }
31316
+ : undefined;
31317
+
31318
+ export const registerAbsoluteEmbeddedBundle = async (rootUri: string, paths: string[], indexUri: string): Promise<string> => {
31319
+ if (Platform.OS !== 'android') return indexUri;
31320
+ const native = requireNativeModule<{ registerBundle(root: string, paths: string[]): Promise<string> }>('AbsoluteEmbeddedAssets');
31321
+ return native.registerBundle(rootUri, paths);
31322
+ };
31323
+ `;
31324
+ var absoluteExpoEmbeddedAssetsFiles = (project) => {
31325
+ const root = join20(project, "modules/absolute-embedded-assets");
31326
+ return new Map([
31327
+ [
31328
+ join20(root, "expo-module.config.json"),
31329
+ `${JSON.stringify({
31330
+ android: {
31331
+ modules: [
31332
+ "expo.modules.absoluteembeddedassets.AbsoluteEmbeddedAssetsModule"
31333
+ ]
31334
+ },
31335
+ platforms: ["android"]
31336
+ }, null, 2)}
31337
+ `
31338
+ ],
31339
+ [
31340
+ join20(root, "android/build.gradle"),
31341
+ `${header}plugins { id 'com.android.library'; id 'expo-module-gradle-plugin' }
31342
+ group = 'expo.modules.absoluteembeddedassets'
31343
+ version = '0.0.1'
31344
+ android {
31345
+ namespace 'expo.modules.absoluteembeddedassets'
31346
+ defaultConfig { versionCode 1; versionName '0.0.1' }
31347
+ }
31348
+ dependencies {
31349
+ implementation 'com.facebook.react:react-android'
31350
+ implementation project(':react-native-webview')
31351
+ implementation 'androidx.webkit:webkit:1.14.0'
31352
+ }
31353
+ `
31354
+ ],
31355
+ [
31356
+ join20(root, "android/src/main/AndroidManifest.xml"),
31357
+ `<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
31358
+ `
31359
+ ],
31360
+ [
31361
+ join20(root, "android/src/main/java/expo/modules/absoluteembeddedassets/AbsoluteEmbeddedAssetsModule.kt"),
31362
+ android
31363
+ ],
31364
+ [join20(project, "plugins/withAbsoluteEmbeddedAssets.js"), plugin],
31365
+ [join20(project, "src/generated/AbsoluteEmbeddedAssets.ts"), runtime2]
31366
+ ]);
31367
+ };
31368
+
31067
31369
  // src/mobile/expoProject.ts
31068
31370
  var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
31069
31371
  `;
@@ -31144,15 +31446,15 @@ var routeSegments = (route) => {
31144
31446
  return segment;
31145
31447
  });
31146
31448
  };
31147
- var routeFile = (project, route) => join20(project, "app", ...routeSegments(route), "index.tsx");
31449
+ var routeFile = (project, route) => join21(project, "app", ...routeSegments(route), "index.tsx");
31148
31450
  var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
31149
31451
  const separator = spec.lastIndexOf("@");
31150
31452
  return [spec.slice(0, separator), spec.slice(separator + 1)];
31151
31453
  }));
31152
31454
  var expoPackage = (auth, branding, sync, devices, updates) => ({
31153
31455
  dependencies: {
31154
- "@absolutejs/devices": "0.7.0",
31155
- "@absolutejs/devices-expo": "0.0.11",
31456
+ "@absolutejs/devices": ABSOLUTE_DEVICES_VERSION,
31457
+ "@absolutejs/devices-expo": ABSOLUTE_EXPO_DEVICES_VERSION,
31156
31458
  ...auth ? {
31157
31459
  "@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
31158
31460
  [ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
@@ -31233,24 +31535,24 @@ var expoAppConfig = (config, auth, sync, devices, runtimeFingerprint) => {
31233
31535
  const devicePlugins = [
31234
31536
  ...new Set(devices.capabilities.flatMap((name) => devices.providers[name]?.plugins ?? []))
31235
31537
  ];
31236
- const configuredPlugins = devicePlugins.map((plugin) => {
31237
- if (plugin === "expo-image-picker")
31538
+ const configuredPlugins = devicePlugins.map((plugin2) => {
31539
+ if (plugin2 === "expo-image-picker")
31238
31540
  return [
31239
- plugin,
31541
+ plugin2,
31240
31542
  {
31241
31543
  cameraPermission: descriptions.NSCameraUsageDescription,
31242
31544
  microphonePermission: false,
31243
31545
  photosPermission: descriptions.NSPhotoLibraryUsageDescription
31244
31546
  }
31245
31547
  ];
31246
- if (plugin === "expo-location")
31548
+ if (plugin2 === "expo-location")
31247
31549
  return [
31248
- plugin,
31550
+ plugin2,
31249
31551
  {
31250
31552
  locationWhenInUsePermission: descriptions.NSLocationWhenInUseUsageDescription
31251
31553
  }
31252
31554
  ];
31253
- return plugin;
31555
+ return plugin2;
31254
31556
  });
31255
31557
  return {
31256
31558
  expo: {
@@ -31272,7 +31574,7 @@ var expoAppConfig = (config, auth, sync, devices, runtimeFingerprint) => {
31272
31574
  package: config.appId,
31273
31575
  permissions: requirements.androidPermissions
31274
31576
  },
31275
- experiments: { typedRoutes: true },
31577
+ experiments: { tsconfigPaths: false, typedRoutes: true },
31276
31578
  ios: {
31277
31579
  ...branding?.ios ?? {},
31278
31580
  associatedDomains: config.deepLinkHosts.map((host2) => `applinks:${host2}`),
@@ -31295,6 +31597,7 @@ var expoAppConfig = (config, auth, sync, devices, runtimeFingerprint) => {
31295
31597
  ["expo-dev-client", { launchMode: "most-recent" }],
31296
31598
  ...branding ? [branding.splashPlugin] : [],
31297
31599
  "./plugins/withAbsoluteActivityResultRecovery",
31600
+ "./plugins/withAbsoluteEmbeddedAssets",
31298
31601
  ...auth || config.updates ? ["expo-secure-store"] : [],
31299
31602
  ...sync ? [
31300
31603
  "expo-sqlite",
@@ -31752,7 +32055,7 @@ import {
31752
32055
  installExpoSyncLifecycle,
31753
32056
  registerExpoSyncBackgroundTask
31754
32057
  } from '@absolutejs/sync-expo';
31755
- import * as Updates from 'expo-updates';
32058
+ import { reloadAppAsync } from 'expo';
31756
32059
  import { absoluteExpoAuth, startAbsoluteExpoAuth } from './AbsoluteAuth';
31757
32060
 
31758
32061
  const BACKGROUND_TASK = ${JSON.stringify(backgroundTask)};
@@ -31811,37 +32114,98 @@ absoluteExpoAuth.onPrincipalChange(principal => {
31811
32114
  if (!started || principal?.namespace === activeNamespace) return;
31812
32115
  const previousNamespace = activeNamespace;
31813
32116
  installRuntimeTransport(principal);
31814
- if (previousNamespace !== undefined) void Updates.reloadAsync();
32117
+ if (previousNamespace !== undefined) void reloadAppAsync('absolutejs-auth-principal-changed').catch(() => {
32118
+ console.warn('AbsoluteJS could not reset the account runtime. Restart the app before continuing.');
32119
+ });
31815
32120
  });
31816
32121
 
31817
32122
  export const createAbsoluteExpoSyncBridge = async (
31818
32123
  emit: (event: 'sync.socket' | 'sync.wake', payload: Record<string, unknown>) => void
31819
32124
  ) => {
31820
32125
  await startAbsoluteExpoSync();
31821
- const principal = await absoluteExpoAuth.principal();
31822
- if (!principal) return {
31823
- close: () => undefined,
31824
- request: async () => { throw new Error('Expo Sync requires an authenticated principal.'); }
32126
+ const bind = (namespace: string, generation: number) => {
32127
+ const emitCurrent = (event: 'sync.socket' | 'sync.wake', payload: Record<string, unknown>) => {
32128
+ if (!closed && generation === revision) emit(event, payload);
32129
+ };
32130
+ const transactions = createExpoSyncBridgeHost({ createId: expoSyncRandomId, namespace, store });
32131
+ const sockets = createExpoSyncSocketBridgeHost({
32132
+ allowedOrigin: PRODUCTION_ORIGIN,
32133
+ emit: payload => emitCurrent('sync.socket', payload),
32134
+ socketTicket: async audience => {
32135
+ if (closed || generation !== revision) throw new Error('Expo Sync principal changed.');
32136
+ const ticket = await absoluteExpoAuth.socketTicket(audience);
32137
+ if (closed || generation !== revision) throw new Error('Expo Sync principal changed.');
32138
+ return ticket;
32139
+ }
32140
+ });
32141
+ const removeLifecycle = installExpoSyncLifecycle({
32142
+ client: { reconnect: () => emitCurrent('sync.wake', {}) }
32143
+ });
32144
+ return {
32145
+ close: async () => {
32146
+ removeLifecycle();
32147
+ await Promise.all([transactions.close(), sockets.close()]);
32148
+ },
32149
+ request: (method: string, params: Record<string, unknown>) =>
32150
+ method.startsWith('sync.socket.') ? sockets.request(method, params) : transactions.request(method, params)
32151
+ };
31825
32152
  };
31826
- const transactions = createExpoSyncBridgeHost({ createId: expoSyncRandomId, namespace: principal.namespace, store });
31827
- const sockets = createExpoSyncSocketBridgeHost({
31828
- allowedOrigin: PRODUCTION_ORIGIN,
31829
- emit: payload => emit('sync.socket', payload),
31830
- socketTicket: audience => absoluteExpoAuth.socketTicket(audience)
31831
- });
31832
- const removeLifecycle = installExpoSyncLifecycle({
31833
- client: { reconnect: () => emit('sync.wake', {}) }
31834
- });
32153
+ let closed = false;
32154
+ let revoked = false;
32155
+ let boundNamespace: string | undefined;
32156
+ let revision = 0;
32157
+ let bridge: ReturnType<typeof bind> | undefined;
32158
+ let ready = Promise.resolve();
32159
+ const replace = (principal: Awaited<ReturnType<typeof absoluteExpoAuth.principal>>) => {
32160
+ if (closed) return;
32161
+ // A mounted page may bind its first login, but must never inherit another
32162
+ // account's authority. Account changes require the existing runtime reload.
32163
+ if (boundNamespace !== undefined && principal?.namespace !== boundNamespace) revoked = true;
32164
+ const generation = ++revision;
32165
+ const previous = bridge;
32166
+ bridge = undefined;
32167
+ ready = ready.then(async () => {
32168
+ await previous?.close();
32169
+ if (!closed && !revoked && generation === revision && principal) {
32170
+ boundNamespace = principal.namespace;
32171
+ bridge = bind(principal.namespace, generation);
32172
+ }
32173
+ });
32174
+ // Keep background transitions handled; requests still observe setup failures.
32175
+ void ready.catch(() => undefined);
32176
+ };
32177
+ const stop = absoluteExpoAuth.onPrincipalChange(replace);
32178
+ try {
32179
+ const initialRevision = revision;
32180
+ const principal = await absoluteExpoAuth.principal();
32181
+ if (revision === initialRevision) replace(principal);
32182
+ await ready;
32183
+ } catch (error) {
32184
+ stop();
32185
+ closed = true;
32186
+ await bridge?.close();
32187
+ throw error;
32188
+ }
31835
32189
 
31836
32190
  return {
31837
32191
  close: async () => {
31838
- removeLifecycle();
31839
- await Promise.all([transactions.close(), sockets.close()]);
32192
+ if (closed) return;
32193
+ closed = true;
32194
+ ++revision;
32195
+ stop();
32196
+ const previous = bridge;
32197
+ bridge = undefined;
32198
+ await Promise.all([ready, previous?.close()]);
31840
32199
  },
31841
- request: (method: string, params: Record<string, unknown>) =>
31842
- method.startsWith('sync.socket.')
31843
- ? sockets.request(method, params)
31844
- : transactions.request(method, params)
32200
+ request: async (method: string, params: Record<string, unknown>) => {
32201
+ const generation = revision;
32202
+ await ready;
32203
+ if (closed || revoked || generation !== revision) throw new Error('Expo Sync principal changed.');
32204
+ if (!bridge) throw new Error('Expo Sync requires an authenticated principal.');
32205
+ const result = await bridge.request(method, params);
32206
+ if (closed || revoked || generation !== revision) throw new Error('Expo Sync principal changed.');
32207
+ return result;
32208
+ }
31845
32209
  };
31846
32210
  };
31847
32211
  `;
@@ -31859,6 +32223,7 @@ import { ActivityIndicator, BackHandler, Platform, Pressable, StyleSheet, Text,
31859
32223
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
31860
32224
  import { WebView, type WebViewMessageEvent } from 'react-native-webview';
31861
32225
  import { materializeAbsoluteWebBundle } from './webAssets';
32226
+ import { absoluteEmbeddedNativeConfig } from './AbsoluteEmbeddedAssets';
31862
32227
  import { markAbsoluteEmbeddedWebPhase, markAbsoluteEmbeddedWebReady } from './AbsoluteActivityResultRecovery';
31863
32228
  import { createExpoDevicesBridgeHost } from '@absolutejs/devices-expo/bridge';
31864
32229
  import { absoluteExpoDevices, beforeAbsoluteExpoDeviceSignOut } from './AbsoluteDevices';
@@ -31978,7 +32343,16 @@ const bridgeBootstrap = (path: string, safeAreaInsets: { bottom: number; left: n
31978
32343
  event.preventDefault();
31979
32344
  send({ format: 3, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
31980
32345
  }, true);
31981
- send({ format: 3, kind: 'event', event: 'ready', path: currentPath });
32346
+ let shellRendered = false;
32347
+ addEventListener('absolute:shell-rendered', () => {
32348
+ shellRendered = true;
32349
+ send({ format: 3, kind: 'event', event: 'shell-rendered', path: currentPath });
32350
+ });
32351
+ const startupFailed = () => {
32352
+ if (!shellRendered) send({ format: 3, kind: 'event', event: 'startup-failed', path: currentPath });
32353
+ };
32354
+ addEventListener('error', startupFailed);
32355
+ addEventListener('unhandledrejection', startupFailed);
31982
32356
  })(); true;\`;
31983
32357
  };
31984
32358
 
@@ -32023,11 +32397,18 @@ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
32023
32397
  const canGoBack = useRef(false);
32024
32398
  const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
32025
32399
  const [devicesReady, setDevicesReady] = useState(false);
32026
- const [startupError, setStartupError] = useState<'assets' | 'devices'>();
32400
+ const [startupError, setStartupError] = useState<'assets' | 'devices' | 'content'>();
32027
32401
  const [startupRevision, setStartupRevision] = useState(0);
32028
32402
  const activeWebPath = useRef(pathname);
32029
32403
  const embeddedReadyReported = useRef(false);
32030
32404
  const webSource = useMemo(() => indexUri ? { uri: indexUri } : undefined, [indexUri]);
32405
+ useEffect(() => {
32406
+ if (!indexUri || DEV_ORIGIN) return;
32407
+ const timeout = setTimeout(() => {
32408
+ if (!embeddedReadyReported.current) setStartupError('content');
32409
+ }, 60000);
32410
+ return () => clearTimeout(timeout);
32411
+ }, [indexUri]);
32031
32412
 
32032
32413
  useEffect(() => {
32033
32414
  if (!AUTH_ENABLED && !SYNC_ENABLED) return;
@@ -32038,10 +32419,13 @@ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
32038
32419
  webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
32039
32420
  });
32040
32421
  void ${sync ? "startAbsoluteExpoSync" : "startAbsoluteExpoAuth"}().then(async () => {
32041
- ${sync ? `syncBridge.current = await createAbsoluteExpoSyncBridge((event, payload) => {
32422
+ ${sync ? `const bridge = await createAbsoluteExpoSyncBridge((event, payload) => {
32423
+ if (!active) return;
32042
32424
  const source = JSON.stringify({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
32043
32425
  webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
32044
- });` : ""}
32426
+ });
32427
+ if (!active) { await bridge.close(); return; }
32428
+ syncBridge.current = bridge;` : ""}
32045
32429
  if (active) setRuntimeReady(true);
32046
32430
  });
32047
32431
  return () => {
@@ -32063,6 +32447,7 @@ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
32063
32447
  markAbsoluteEmbeddedWebPhase('assets-start');
32064
32448
  void materializeAbsoluteWebBundle().then(uri => {
32065
32449
  markAbsoluteEmbeddedWebPhase('assets-ready');
32450
+ embeddedReadyReported.current = false;
32066
32451
  setIndexUri(uri + '?absolutePath=' + encodeURIComponent(pathname));
32067
32452
  }).catch(error => {
32068
32453
  const phase = error instanceof Error && (error.message === 'assets-root-failed' || error.message === 'assets-directory-failed' || error.message === 'assets-destination-failed' || error.message === 'assets-module-failed' || error.message === 'assets-source-failed' || error.message === 'assets-download-failed' || error.message === 'assets-copy-failed' || error.message === 'assets-read-failed' || error.message === 'assets-write-failed' || error.message === 'assets-finalize-failed')
@@ -32116,15 +32501,23 @@ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
32116
32501
  try { return new URL(source).origin === origin; } catch { return false; }
32117
32502
  };
32118
32503
  const onMessage = async (event: WebViewMessageEvent) => {
32504
+ // Bridge authority belongs only to the currently loaded embedded bundle
32505
+ // (or the explicitly configured development origin), never remote pages.
32506
+ const sourceUrl = event.nativeEvent.url;
32507
+ if (!indexUri || typeof sourceUrl !== 'string' || (DEV_ORIGIN ? !hasOrigin(sourceUrl, DEV_ORIGIN) : !sourceUrl.startsWith(indexUri.slice(0, indexUri.lastIndexOf('/') + 1)))) return;
32119
32508
  const source = event.nativeEvent.data;
32120
32509
  if (new TextEncoder().encode(source).byteLength > MAX_MESSAGE_BYTES) return;
32121
32510
  let message: Record<string, unknown>;
32122
32511
  try { message = JSON.parse(source); } catch { return; }
32123
32512
  if (message.format !== BRIDGE_FORMAT || typeof message.path !== 'string' || !message.path.startsWith('/') || message.path.startsWith('//')) return;
32124
- if (message.kind === 'event' && (message.event === 'navigation' || message.event === 'ready')) {
32513
+ if (message.kind === 'event' && message.event === 'startup-failed') {
32514
+ if (!embeddedReadyReported.current) setStartupError('content');
32515
+ return;
32516
+ }
32517
+ if (message.kind === 'event' && (message.event === 'navigation' || message.event === 'shell-rendered')) {
32125
32518
  const target = new URL(message.path, PRODUCTION_ORIGIN);
32126
32519
  if (target.origin !== PRODUCTION_ORIGIN) return;
32127
- if (message.event === 'ready' && !DEV_ORIGIN && !embeddedReadyReported.current) {
32520
+ if (message.event === 'shell-rendered' && !DEV_ORIGIN && !embeddedReadyReported.current) {
32128
32521
  embeddedReadyReported.current = true;
32129
32522
  markAbsoluteEmbeddedWebReady();
32130
32523
  }
@@ -32178,12 +32571,17 @@ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
32178
32571
  </View>;
32179
32572
  if (!webSource || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
32180
32573
  return <WebView
32181
- allowFileAccess
32182
- allowFileAccessFromFileURLs
32574
+ nativeConfig={!DEV_ORIGIN ? absoluteEmbeddedNativeConfig : undefined}
32575
+ allowFileAccess={Platform.OS !== 'android'}
32576
+ allowFileAccessFromFileURLs={Platform.OS !== 'android'}
32183
32577
  allowUniversalAccessFromFileURLs={false}
32578
+ originWhitelist={DEV_ORIGIN ? [DEV_ORIGIN] : [Platform.OS === 'android' ? 'https://appassets.androidplatform.net' : 'file://*']}
32184
32579
  allowingReadAccessToURL={webSource.uri.slice(0, webSource.uri.lastIndexOf('/') + 1)}
32185
32580
  injectedJavaScriptBeforeContentLoaded={bridgeBootstrap(pathname, safeAreaInsets)}
32186
32581
  onMessage={onMessage}
32582
+ onError={() => setStartupError('content')}
32583
+ onRenderProcessGone={() => setStartupError('content')}
32584
+ onContentProcessDidTerminate={() => setStartupError('content')}
32187
32585
  onNavigationStateChange={state => {
32188
32586
  canGoBack.current = state.canGoBack;
32189
32587
  if (!DEV_ORIGIN || !hasOrigin(state.url, DEV_ORIGIN)) return;
@@ -32191,8 +32589,8 @@ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
32191
32589
  activeWebPath.current = route.pathname + route.search + route.hash;
32192
32590
  }}
32193
32591
  onShouldStartLoadWithRequest={request => {
32194
- if (request.url.startsWith('file:') || hasOrigin(request.url, PRODUCTION_ORIGIN) || DEV_ORIGIN && hasOrigin(request.url, DEV_ORIGIN)) return true;
32195
- void Linking.openURL(request.url);
32592
+ if (DEV_ORIGIN ? hasOrigin(request.url, DEV_ORIGIN) : request.url.startsWith(webSource.uri.slice(0, webSource.uri.lastIndexOf('/') + 1))) return true;
32593
+ if (/^https?:/.test(request.url)) void Linking.openURL(request.url);
32196
32594
  return false;
32197
32595
  }}
32198
32596
  ref={webView}
@@ -32395,8 +32793,8 @@ const styles = StyleSheet.create({
32395
32793
  error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
32396
32794
  });
32397
32795
  `;
32398
- var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative3(dirname13(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
32399
- import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative3(dirname13(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
32796
+ var nativeWrapperSource = (wrapper, module, runtime3, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative3(dirname13(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
32797
+ import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative3(dirname13(wrapper), runtime3).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
32400
32798
 
32401
32799
  export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
32402
32800
  export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
@@ -32438,7 +32836,7 @@ var expoTsConfig = (projectRoot, project, auth, sync) => ({
32438
32836
  extends: "expo/tsconfig.base"
32439
32837
  });
32440
32838
  var writeManagedFile = async (path, source, force) => {
32441
- await mkdir14(dirname13(path), { recursive: true });
32839
+ await mkdir15(dirname13(path), { recursive: true });
32442
32840
  if (await exists6(path)) {
32443
32841
  const current = await readFile17(path, "utf8");
32444
32842
  if (current === source)
@@ -32465,7 +32863,7 @@ var pruneManagedFiles = async (paths) => {
32465
32863
  return removed.filter(Boolean).length;
32466
32864
  };
32467
32865
  var pruneStaleManagedExpoRoutes = async (project, expected) => {
32468
- const appDirectory = join20(project, "app");
32866
+ const appDirectory = join21(project, "app");
32469
32867
  if (!await exists6(appDirectory))
32470
32868
  return 0;
32471
32869
  const files = await walkFiles(appDirectory);
@@ -32513,20 +32911,20 @@ var writeAbsoluteExpoProject = async (config, options) => {
32513
32911
  if (missing) {
32514
32912
  throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
32515
32913
  }
32516
- const marker = join20(project, EXPO_PROJECT_MARKER);
32914
+ const marker = join21(project, EXPO_PROJECT_MARKER);
32517
32915
  if (await exists6(project) && !await exists6(marker)) {
32518
32916
  const entries = await readdir5(project);
32519
32917
  if (entries.length > 0 && !options.force) {
32520
32918
  throw new TypeError(`Expo project directory ${project} is not AbsoluteJS-managed; rerun with --force only after reviewing it.`);
32521
32919
  }
32522
32920
  }
32523
- await mkdir14(project, { recursive: true });
32921
+ await mkdir15(project, { recursive: true });
32524
32922
  await writeFile14(marker, `format=1
32525
32923
  `);
32526
32924
  const authEnabled = Boolean(auth);
32527
32925
  const files = new Map([
32528
32926
  [
32529
- join20(project, ".gitignore"),
32927
+ join21(project, ".gitignore"),
32530
32928
  `.expo/
32531
32929
  android/
32532
32930
  ios/
@@ -32534,80 +32932,82 @@ node_modules/
32534
32932
  `
32535
32933
  ],
32536
32934
  [
32537
- join20(project, "app.json"),
32935
+ join21(project, "app.json"),
32538
32936
  jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
32539
32937
  ],
32540
- [join20(project, "app.config.js"), expoDynamicAppConfig],
32938
+ [join21(project, "app.config.js"), expoDynamicAppConfig],
32541
32939
  [
32542
- join20(project, "package.json"),
32940
+ join21(project, "package.json"),
32543
32941
  jsonSource(expoPackage(authEnabled, config.branding !== undefined, syncEnabled, devices, config.updates !== undefined))
32544
32942
  ],
32545
- [join20(project, "metro.config.js"), metroConfig(projectRoot)],
32943
+ [join21(project, "metro.config.js"), metroConfig(projectRoot)],
32546
32944
  [
32547
- join20(project, "plugins", "withAbsoluteDevelopmentCa.js"),
32945
+ join21(project, "plugins", "withAbsoluteDevelopmentCa.js"),
32548
32946
  expoDevelopmentCaPlugin
32549
32947
  ],
32550
32948
  [
32551
- join20(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
32949
+ join21(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
32552
32950
  expoActivityResultRecoveryPlugin
32553
32951
  ],
32554
32952
  [
32555
- join20(project, "tsconfig.json"),
32953
+ join21(project, "tsconfig.json"),
32556
32954
  jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
32557
32955
  ],
32558
32956
  [
32559
- join20(project, "app", "_layout.tsx"),
32957
+ join21(project, "app", "_layout.tsx"),
32560
32958
  layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
32561
32959
  ],
32562
32960
  [
32563
- join20(project, "app", "__absolute", "native", "index.tsx"),
32961
+ join21(project, "app", "__absolute", "native", "index.tsx"),
32564
32962
  nativeDiagnosticSource
32565
32963
  ],
32566
32964
  [
32567
- join20(project, "src", "generated", "AbsoluteDevices.ts"),
32965
+ join21(project, "src", "generated", "AbsoluteDevices.ts"),
32568
32966
  devicesRuntimeSource(config, devices, authEnabled)
32569
32967
  ],
32570
32968
  [
32571
- join20(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
32969
+ join21(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
32572
32970
  nativeRouteRuntimeSource(authEnabled)
32573
32971
  ],
32574
32972
  [
32575
- join20(project, "src", "generated", "AbsoluteWebHost.tsx"),
32973
+ join21(project, "src", "generated", "AbsoluteWebHost.tsx"),
32576
32974
  webHostSource(config, auth, syncEnabled)
32577
32975
  ]
32578
32976
  ]);
32579
32977
  for (const [path, source] of absoluteExpoActivityResultRecoveryFiles(project))
32580
32978
  files.set(path, source);
32979
+ for (const [path, source] of absoluteExpoEmbeddedAssetsFiles(project))
32980
+ files.set(path, source);
32581
32981
  if (config.observability) {
32582
32982
  for (const [path, source] of absoluteExpoNativeObservabilityFiles(project))
32583
32983
  files.set(path, source);
32584
32984
  }
32585
32985
  if (config.updates) {
32586
- files.set(join20(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
32986
+ files.set(join21(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
32587
32987
  }
32588
32988
  const expoCodeSigning = config.updates?.expoCodeSigning;
32589
32989
  if (expoCodeSigning)
32590
- files.set(join20(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
32990
+ files.set(join21(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
32591
32991
  if (auth) {
32592
- files.set(join20(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
32992
+ files.set(join21(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
32593
32993
  }
32594
32994
  if (syncSchema) {
32595
- files.set(join20(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
32995
+ files.set(join21(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
32596
32996
  }
32597
- const webAssetsPath = join20(project, "src", "generated", "webAssets.ts");
32997
+ const webAssetsPath = join21(project, "src", "generated", "webAssets.ts");
32598
32998
  if (!await exists6(webAssetsPath)) {
32599
32999
  files.set(webAssetsPath, emptyWebAssetsSource);
32600
33000
  }
32601
33001
  if (!config.expoNativeRoutes["/"]) {
32602
- files.set(join20(project, "app", "index.tsx"), webRouteSource);
33002
+ files.set(join21(project, "app", "index.tsx"), webRouteSource);
32603
33003
  }
32604
- files.set(join20(project, "app", "[...absolute].tsx"), catchAllRouteSource);
32605
- const nativeRouteRuntime = join20(project, "src", "generated", "AbsoluteNativeRoute.tsx");
33004
+ files.set(join21(project, "app", "[...absolute].tsx"), catchAllRouteSource);
33005
+ const nativeRouteRuntime = join21(project, "src", "generated", "AbsoluteNativeRoute.tsx");
32606
33006
  for (const [route, module] of routeModules) {
32607
- const wrapper = route === "/" ? join20(project, "app", "index.tsx") : routeFile(project, route);
33007
+ const wrapper = route === "/" ? join21(project, "app", "index.tsx") : routeFile(project, route);
32608
33008
  files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
32609
33009
  }
32610
- const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join20(project, "app")}${sep8}`))));
33010
+ const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join21(project, "app")}${sep8}`))));
32611
33011
  const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
32612
33012
  const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
32613
33013
  await writeAbsoluteExpoBrandingInputs(config, projectRoot);
@@ -32617,7 +33017,7 @@ node_modules/
32617
33017
  var walkFiles = async (root, directory = root) => {
32618
33018
  const entries = await readdir5(directory, { withFileTypes: true });
32619
33019
  const nested = await Promise.all(entries.map((entry) => {
32620
- const path = join20(directory, entry.name);
33020
+ const path = join21(directory, entry.name);
32621
33021
  if (entry.isDirectory())
32622
33022
  return walkFiles(root, path);
32623
33023
  if (entry.isFile())
@@ -32650,13 +33050,16 @@ var installStagedDirectory = async (staging, destination) => {
32650
33050
  throw error;
32651
33051
  }
32652
33052
  };
32653
- var assetModuleSource = (assets, archiveAsset, bundleId, manifest) => `${EXPO_GENERATED_HEADER}import { Asset } from 'expo-asset';
33053
+ var assetModuleSource = (assets, archiveAsset, bundleId, archiveMd5, manifest) => `${EXPO_GENERATED_HEADER}import { Asset } from 'expo-asset';
32654
33054
  import { Directory, File, Paths } from 'expo-file-system';
32655
33055
  import { copyAsync as copyLegacyAsync } from 'expo-file-system/legacy';
33056
+ import { registerAbsoluteEmbeddedBundle } from './AbsoluteEmbeddedAssets';
32656
33057
 
32657
33058
  ${nativeDataManifestTypeSource}
32658
33059
  declare const require: (path: string) => number;
32659
33060
  const BUNDLE_ID = ${JSON.stringify(bundleId)};
33061
+ const ARCHIVE_MD5 = ${JSON.stringify(archiveMd5)};
33062
+ const ARCHIVE_LENGTH = ${assets.reduce((sum, entry) => sum + entry.length, 0)};
32660
33063
  export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest = ${JSON.stringify(manifest)};
32661
33064
  const ARCHIVE_MODULE = require(${JSON.stringify(archiveAsset)});
32662
33065
  const ASSETS = [
@@ -32673,10 +33076,12 @@ export const materializeAbsoluteWebBundle = async () => {
32673
33076
  let archive: File;
32674
33077
  try { archive = new File(root, '.absolutejs-bundle.absasset'); }
32675
33078
  catch { throw new Error('assets-destination-failed'); }
33079
+ if (archive.exists && (archive.size !== ARCHIVE_LENGTH || archive.md5 !== ARCHIVE_MD5)) archive.delete();
32676
33080
  if (!archive.exists) {
32677
33081
  let asset: Asset;
32678
33082
  try { asset = Asset.fromModule(ARCHIVE_MODULE); }
32679
33083
  catch { throw new Error('assets-module-failed'); }
33084
+ if (asset.type !== 'absasset' || asset.hash !== ARCHIVE_MD5) throw new Error('assets-identity-failed');
32680
33085
  try { if (!asset.localUri) asset = await asset.downloadAsync(); }
32681
33086
  catch { throw new Error('assets-download-failed'); }
32682
33087
  if (!asset.localUri) throw new Error('assets-download-failed');
@@ -32689,9 +33094,16 @@ export const materializeAbsoluteWebBundle = async () => {
32689
33094
  catch { throw new Error('assets-copy-failed'); }
32690
33095
  }
32691
33096
  }
33097
+ // Checksums detect accidental corruption/registry mismatches, not authenticity;
33098
+ // authenticity comes from the signed application/update containing this table.
33099
+ if (archive.size !== ARCHIVE_LENGTH || archive.md5 !== ARCHIVE_MD5) {
33100
+ archive.delete();
33101
+ throw new Error('assets-integrity-failed');
33102
+ }
32692
33103
  let contents: Uint8Array;
32693
33104
  try { contents = await archive.bytes(); }
32694
33105
  catch { throw new Error('assets-read-failed'); }
33106
+ if (contents.byteLength !== ARCHIVE_LENGTH) throw new Error('assets-integrity-failed');
32695
33107
  for (const entry of ASSETS) {
32696
33108
  const parts = entry.path.split('/');
32697
33109
  const name = parts.pop();
@@ -32705,27 +33117,28 @@ export const materializeAbsoluteWebBundle = async () => {
32705
33117
  let destination: File;
32706
33118
  try {
32707
33119
  destination = new File(directory, name);
32708
- if (destination.exists && destination.size === entry.length) continue;
33120
+ if (destination.exists && destination.size === entry.length && destination.md5 === entry.md5) continue;
32709
33121
  if (destination.exists) destination.delete();
32710
33122
  } catch { throw new Error('assets-destination-failed'); }
32711
33123
  try { destination.write(contents.slice(entry.offset, entry.offset + entry.length)); }
32712
33124
  catch { throw new Error('assets-write-failed'); }
33125
+ if (destination.size !== entry.length || destination.md5 !== entry.md5) throw new Error('assets-integrity-failed');
32713
33126
  }
32714
33127
  try { archive.delete(); }
32715
33128
  catch { throw new Error('assets-finalize-failed'); }
32716
33129
 
32717
- try { return new File(root, 'index.html').uri; }
33130
+ try { return await registerAbsoluteEmbeddedBundle(root.uri, ASSETS.map(entry => entry.path), new File(root, 'index.html').uri); }
32718
33131
  catch { throw new Error('assets-finalize-failed'); }
32719
33132
  };
32720
33133
  `;
32721
33134
  var syncAbsoluteExpoWebAssets = async (config) => {
32722
33135
  if (config.engine !== "expo")
32723
33136
  throw new TypeError("Expo asset sync requires mobile.engine: expo.");
32724
- const marker = join20(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
33137
+ const marker = join21(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
32725
33138
  if (!await exists6(marker)) {
32726
33139
  throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
32727
33140
  }
32728
- const manifestPath = join20(config.bundleDirectory, "absolute-mobile-manifest.json");
33141
+ const manifestPath = join21(config.bundleDirectory, "absolute-mobile-manifest.json");
32729
33142
  const manifest = JSON.parse(await readFile17(manifestPath, "utf8"));
32730
33143
  const nativeDataManifest = expoNativeDataManifest(manifest);
32731
33144
  const { appBuild } = nativeDataManifest;
@@ -32739,16 +33152,18 @@ var syncAbsoluteExpoWebAssets = async (config) => {
32739
33152
  bundleHash.update("\x00");
32740
33153
  });
32741
33154
  const bundleId = `amexpo_${bundleHash.digest("hex")}`;
32742
- const destination = join20(config.nativeProjectDirectory, "assets", "absolute");
32743
- await mkdir14(dirname13(destination), { recursive: true });
32744
- const staging = await mkdtemp9(join20(dirname13(destination), `.${basename6(destination)}.stage-`));
33155
+ const destination = join21(config.nativeProjectDirectory, "assets", "absolute");
33156
+ await mkdir15(dirname13(destination), { recursive: true });
33157
+ const staging = await mkdtemp9(join21(dirname13(destination), `.${basename6(destination)}.stage-`));
32745
33158
  let assets;
32746
33159
  let archiveAsset;
33160
+ let archiveMd5;
32747
33161
  try {
32748
33162
  let offset = 0;
32749
33163
  assets = filesWithContents.map(({ contents, file }) => {
32750
33164
  const entry = {
32751
33165
  length: contents.byteLength,
33166
+ md5: createHash15("md5").update(contents).digest("hex"),
32752
33167
  offset,
32753
33168
  path: relative13(config.bundleDirectory, file).replaceAll("\\", "/")
32754
33169
  };
@@ -32756,15 +33171,17 @@ var syncAbsoluteExpoWebAssets = async (config) => {
32756
33171
  return entry;
32757
33172
  });
32758
33173
  const name = `bundle${EXPO_ASSET_EXTENSION}`;
32759
- await writeFile14(join20(staging, name), Buffer.concat(filesWithContents.map(({ contents }) => contents)));
32760
- archiveAsset = portableRelative3(join20(config.nativeProjectDirectory, "src", "generated"), join20(destination, name));
33174
+ const archiveContents = Buffer.concat(filesWithContents.map(({ contents }) => contents));
33175
+ archiveMd5 = createHash15("md5").update(archiveContents).digest("hex");
33176
+ await writeFile14(join21(staging, name), archiveContents);
33177
+ archiveAsset = portableRelative3(join21(config.nativeProjectDirectory, "src", "generated"), join21(destination, name));
32761
33178
  await installStagedDirectory(staging, destination);
32762
33179
  } catch (error) {
32763
33180
  await rm13(staging, { force: true, recursive: true });
32764
33181
  throw error;
32765
33182
  }
32766
- const generated = join20(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
32767
- await writeManagedFile(generated, assetModuleSource(assets, archiveAsset, bundleId, nativeDataManifest), true);
33183
+ const generated = join21(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
33184
+ await writeManagedFile(generated, assetModuleSource(assets, archiveAsset, bundleId, archiveMd5, nativeDataManifest), true);
32768
33185
  return { appBuild, assets: assets.length, bundleId, path: destination };
32769
33186
  };
32770
33187
 
@@ -32804,9 +33221,9 @@ var loadServerApp = async (producerPath) => {
32804
33221
  var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
32805
33222
  const buildDirectory = resolve16(options.buildDirectory);
32806
33223
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
32807
- const root = join21(buildDirectory, ".absolutejs", "mobile-compatibility");
33224
+ const root = join22(buildDirectory, ".absolutejs", "mobile-compatibility");
32808
33225
  const [manifestSource, previous] = await Promise.all([
32809
- readFile18(join21(buildDirectory, "manifest.json"), "utf8"),
33226
+ readFile18(join22(buildDirectory, "manifest.json"), "utf8"),
32810
33227
  readAbsoluteMobileMaterializedReleases(root)
32811
33228
  ]);
32812
33229
  const manifest = JSON.parse(manifestSource);
@@ -33134,7 +33551,7 @@ var parseRequest = (value) => {
33134
33551
  throw new TypeError("Expo bridge HTTP method cannot contain a body.");
33135
33552
  if (!isRecord10(value.params.headers))
33136
33553
  throw new TypeError("Expo bridge HTTP headers must be an object.");
33137
- const headersAllowed = Object.entries(value.params.headers).every(([name, header]) => typeof header === "string" && (name.toLowerCase() === "accept" || name.toLowerCase() === "content-type" || name.toLowerCase().startsWith("x-absolute-mobile-")));
33554
+ const headersAllowed = Object.entries(value.params.headers).every(([name, header2]) => typeof header2 === "string" && (name.toLowerCase() === "accept" || name.toLowerCase() === "content-type" || name.toLowerCase().startsWith("x-absolute-mobile-")));
33138
33555
  if (!headersAllowed) {
33139
33556
  throw new TypeError("Expo bridge HTTP header is not allowed.");
33140
33557
  }
@@ -33235,7 +33652,7 @@ var parseAbsoluteExpoBridgeMessage = (source) => {
33235
33652
  };
33236
33653
  // src/mobile/expoCodeSigning.ts
33237
33654
  var import_code_signing_certificates = __toESM(require_main(), 1);
33238
- import { access as access14, mkdir as mkdir15, writeFile as writeFile15 } from "fs/promises";
33655
+ import { access as access14, mkdir as mkdir16, writeFile as writeFile15 } from "fs/promises";
33239
33656
  import { dirname as dirname14, isAbsolute as isAbsolute8, relative as relative14, resolve as resolve17, sep as sep9 } from "path";
33240
33657
  var exists7 = async (path) => access14(path).then(() => true).catch(() => false);
33241
33658
  var inside3 = (root, path) => {
@@ -33276,7 +33693,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
33276
33693
  import_code_signing_certificates.validateSelfSignedCertificate(certificate, keyPair);
33277
33694
  const { privateKeyPEM, publicKeyPEM } = import_code_signing_certificates.convertKeyPairToPEM(keyPair);
33278
33695
  const certificatePem = import_code_signing_certificates.convertCertificateToCertificatePEM(certificate);
33279
- await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map((path) => mkdir15(dirname14(path), { recursive: true })));
33696
+ await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map((path) => mkdir16(dirname14(path), { recursive: true })));
33280
33697
  await Promise.all([
33281
33698
  writeFile15(certificatePath, certificatePem, { flag: "wx", mode: 420 }),
33282
33699
  writeFile15(privateKeyPath, privateKeyPEM, { flag: "wx", mode: 384 }),
@@ -33383,7 +33800,7 @@ var parseAbsoluteAndroidAccessibilityHierarchy = (source) => [...source.matchAll
33383
33800
  // src/mobile/expoNativeWatcher.ts
33384
33801
  import { watch as watch2 } from "fs";
33385
33802
  import { access as access15, readdir as readdir6, readFile as readFile19 } from "fs/promises";
33386
- import { basename as basename7, join as join22, relative as relative15 } from "path";
33803
+ import { basename as basename7, join as join23, relative as relative15 } from "path";
33387
33804
  import { createHash as createHash16 } from "crypto";
33388
33805
  var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
33389
33806
  var ROOT_NATIVE_INPUTS2 = new Set([
@@ -33404,7 +33821,7 @@ var filesIn = async (directory, prefix) => {
33404
33821
  return [];
33405
33822
  const entries = await readdir6(directory, { withFileTypes: true });
33406
33823
  const nested = await Promise.all(entries.map((entry) => {
33407
- const path = join22(directory, entry.name);
33824
+ const path = join23(directory, entry.name);
33408
33825
  const name = `${prefix}/${entry.name}`;
33409
33826
  if (entry.isDirectory())
33410
33827
  return filesIn(path, name);
@@ -33415,10 +33832,10 @@ var filesIn = async (directory, prefix) => {
33415
33832
  var fingerprintAbsoluteExpoNativeInputs = async (options) => {
33416
33833
  const hash = createHash16("sha256");
33417
33834
  const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
33418
- const path = join22(options.projectRoot, name);
33835
+ const path = join23(options.projectRoot, name);
33419
33836
  return await exists8(path) ? [{ name: `root/${name}`, path }] : [];
33420
33837
  }));
33421
- const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join22(options.expoProjectDirectory, name), name)));
33838
+ const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join23(options.expoProjectDirectory, name), name)));
33422
33839
  const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
33423
33840
  const contents = await Promise.all(files.map(({ path }) => readFile19(path)));
33424
33841
  files.forEach(({ name }, index) => {
@@ -33489,14 +33906,14 @@ var createAbsoluteExpoNativeWatcher = async (options) => {
33489
33906
  }
33490
33907
  };
33491
33908
  const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
33492
- const directory = join22(options.expoProjectDirectory, name);
33909
+ const directory = join23(options.expoProjectDirectory, name);
33493
33910
  return await exists8(directory) ? [directory] : [];
33494
33911
  }))).flat();
33495
33912
  nativeDirectories.forEach((directory) => {
33496
33913
  watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
33497
33914
  if (!filename)
33498
33915
  return;
33499
- record(relative15(options.expoProjectDirectory, join22(directory, String(filename))), false);
33916
+ record(relative15(options.expoProjectDirectory, join23(directory, String(filename))), false);
33500
33917
  }));
33501
33918
  });
33502
33919
  watchers.push(watch2(options.projectRoot, (_event, filename) => {
@@ -33511,8 +33928,8 @@ var createAbsoluteExpoNativeWatcher = async (options) => {
33511
33928
  return { close };
33512
33929
  };
33513
33930
  // src/mobile/expoUpdate.ts
33514
- import { access as access16, mkdir as mkdir16, readFile as readFile20, writeFile as writeFile16 } from "fs/promises";
33515
- import { dirname as dirname15, extname as extname4, join as join23 } from "path";
33931
+ import { access as access16, mkdir as mkdir17, readFile as readFile20, writeFile as writeFile16 } from "fs/promises";
33932
+ import { dirname as dirname15, extname as extname4, join as join24 } from "path";
33516
33933
  var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
33517
33934
  var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
33518
33935
  var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -33578,7 +33995,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
33578
33995
  };
33579
33996
  };
33580
33997
  var finalizeAbsoluteExpoUpdateExport = async (options) => {
33581
- const metadata = JSON.parse(await readFile20(join23(options.exportDirectory, "metadata.json"), "utf8"));
33998
+ const metadata = JSON.parse(await readFile20(join24(options.exportDirectory, "metadata.json"), "utf8"));
33582
33999
  if (!object4(metadata) || !object4(metadata.fileMetadata))
33583
34000
  throw new TypeError("Expo export metadata.json is invalid.");
33584
34001
  const descriptor = parseAbsoluteExpoUpdateDescriptor({
@@ -33589,11 +34006,11 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
33589
34006
  runtimeVersion: options.runtimeVersion
33590
34007
  });
33591
34008
  const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
33592
- await Promise.all(referenced.map(({ path }) => access16(join23(options.exportDirectory, path)).catch(() => {
34009
+ await Promise.all(referenced.map(({ path }) => access16(join24(options.exportDirectory, path)).catch(() => {
33593
34010
  throw new TypeError(`Expo export metadata references missing asset ${path}.`);
33594
34011
  })));
33595
- const destination = join23(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
33596
- await mkdir16(dirname15(destination), { recursive: true });
34012
+ const destination = join24(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
34013
+ await mkdir17(dirname15(destination), { recursive: true });
33597
34014
  await writeFile16(destination, `${JSON.stringify(descriptor, null, "\t")}
33598
34015
  `);
33599
34016
  return { descriptor, path: destination };
@@ -33605,7 +34022,7 @@ init_config();
33605
34022
  // src/mobile/ciPromotionAudit.ts
33606
34023
  import {
33607
34024
  access as access19,
33608
- mkdir as mkdir19,
34025
+ mkdir as mkdir20,
33609
34026
  mkdtemp as mkdtemp11,
33610
34027
  readFile as readFile23,
33611
34028
  readdir as readdir7,
@@ -33614,10 +34031,10 @@ import {
33614
34031
  stat as stat7,
33615
34032
  writeFile as writeFile19
33616
34033
  } from "fs/promises";
33617
- import { dirname as dirname17, isAbsolute as isAbsolute11, join as join25, relative as relative18, resolve as resolve20, sep as sep12 } from "path";
34034
+ import { dirname as dirname17, isAbsolute as isAbsolute11, join as join26, relative as relative18, resolve as resolve20, sep as sep12 } from "path";
33618
34035
 
33619
34036
  // src/mobile/certificationVerification.ts
33620
- import { access as access17, mkdir as mkdir17, readFile as readFile21, stat as stat6, writeFile as writeFile17 } from "fs/promises";
34037
+ import { access as access17, mkdir as mkdir18, readFile as readFile21, stat as stat6, writeFile as writeFile17 } from "fs/promises";
33621
34038
  import { dirname as dirname16, isAbsolute as isAbsolute9, relative as relative16, resolve as resolve18, sep as sep10 } from "path";
33622
34039
  var ABSOLUTE_MOBILE_CERTIFICATION_VERIFICATION_FORMAT = 1;
33623
34040
  var MAX_VERIFICATION_BYTES = 1048576;
@@ -33710,7 +34127,7 @@ var readAbsoluteSigstoreBundle = async (projectRoot, requested) => {
33710
34127
  var writeAbsoluteMobileCertificationVerification = async (projectRoot, requested, verification) => {
33711
34128
  const path = projectFile(projectRoot, requested);
33712
34129
  const parsed = parseAbsoluteMobileCertificationVerification(verification);
33713
- await mkdir17(dirname16(path), { recursive: true });
34130
+ await mkdir18(dirname16(path), { recursive: true });
33714
34131
  await writeFile17(path, `${JSON.stringify(parsed, null, 2)}
33715
34132
  `, {
33716
34133
  mode: 384
@@ -33722,14 +34139,14 @@ var writeAbsoluteMobileCertificationVerification = async (projectRoot, requested
33722
34139
  import { createHash as createHash17 } from "crypto";
33723
34140
  import {
33724
34141
  access as access18,
33725
- mkdir as mkdir18,
34142
+ mkdir as mkdir19,
33726
34143
  mkdtemp as mkdtemp10,
33727
34144
  readFile as readFile22,
33728
34145
  rename as rename14,
33729
34146
  rm as rm14,
33730
34147
  writeFile as writeFile18
33731
34148
  } from "fs/promises";
33732
- import { basename as basename8, isAbsolute as isAbsolute10, join as join24, relative as relative17, resolve as resolve19, sep as sep11 } from "path";
34149
+ import { basename as basename8, isAbsolute as isAbsolute10, join as join25, relative as relative17, resolve as resolve19, sep as sep11 } from "path";
33733
34150
  var ABSOLUTE_MOBILE_RELEASE_CERTIFICATION_FORMAT = 1;
33734
34151
  var CERTIFICATION_PREFIX = "amobile_cert_";
33735
34152
  var SHA256 = /^[a-f0-9]{64}$/u;
@@ -33773,7 +34190,7 @@ var resolveEvidencePath = async (projectRoot, requested) => {
33773
34190
  throw new TypeError("Mobile certification evidence must remain inside the project.");
33774
34191
  if (basename8(selected) === "report.json")
33775
34192
  return selected;
33776
- const report = join24(selected, "report.json");
34193
+ const report = join25(selected, "report.json");
33777
34194
  if (!await exists9(report))
33778
34195
  throw new TypeError(`Mobile certification evidence does not contain report.json: ${requested}`);
33779
34196
  return report;
@@ -34038,7 +34455,7 @@ var readAbsoluteMobileReleaseCertification = async (projectRoot, requested) => {
34038
34455
  const selected = resolve19(projectRoot, requested);
34039
34456
  if (!inside4(projectRoot, selected))
34040
34457
  throw new TypeError("Mobile release certification must remain inside the project.");
34041
- const path = basename8(selected) === "certification.json" ? selected : join24(selected, "certification.json");
34458
+ const path = basename8(selected) === "certification.json" ? selected : join25(selected, "certification.json");
34042
34459
  const value = JSON.parse(await readFile22(path, "utf8"));
34043
34460
  return { certification: parseCertification(value), path };
34044
34461
  };
@@ -34085,15 +34502,15 @@ var verifyAbsoluteMobileReleaseCertification = (certification, release, requirem
34085
34502
  };
34086
34503
  var writeAbsoluteMobileReleaseCertification = async (projectRoot, certification, outputDirectory) => {
34087
34504
  const root = resolve19(projectRoot);
34088
- const parent = resolve19(root, outputDirectory ?? join24(".absolutejs", "mobile", "certifications", certification.release.platform, certification.release.releaseId));
34505
+ const parent = resolve19(root, outputDirectory ?? join25(".absolutejs", "mobile", "certifications", certification.release.platform, certification.release.releaseId));
34089
34506
  if (!inside4(root, parent))
34090
34507
  throw new TypeError("Mobile certification output must remain inside the project.");
34091
- await mkdir18(parent, { recursive: true });
34092
- const destination = join24(parent, certification.certificationId);
34508
+ await mkdir19(parent, { recursive: true });
34509
+ const destination = join25(parent, certification.certificationId);
34093
34510
  const paths = {
34094
34511
  directory: destination,
34095
- jsonPath: join24(destination, "certification.json"),
34096
- markdownPath: join24(destination, "certification.md")
34512
+ jsonPath: join25(destination, "certification.json"),
34513
+ markdownPath: join25(destination, "certification.md")
34097
34514
  };
34098
34515
  const json = serializeAbsoluteMobileReleaseCertification(certification);
34099
34516
  const markdown = renderAbsoluteMobileReleaseCertification(certification);
@@ -34109,13 +34526,13 @@ var writeAbsoluteMobileReleaseCertification = async (projectRoot, certification,
34109
34526
  await verifyExisting();
34110
34527
  return paths;
34111
34528
  }
34112
- const staging = await mkdtemp10(join24(parent, ".certification-"));
34529
+ const staging = await mkdtemp10(join25(parent, ".certification-"));
34113
34530
  try {
34114
34531
  await Promise.all([
34115
- writeFile18(join24(staging, "certification.json"), json, {
34532
+ writeFile18(join25(staging, "certification.json"), json, {
34116
34533
  flag: "wx"
34117
34534
  }),
34118
- writeFile18(join24(staging, "certification.md"), markdown, {
34535
+ writeFile18(join25(staging, "certification.md"), markdown, {
34119
34536
  flag: "wx"
34120
34537
  })
34121
34538
  ]);
@@ -34347,7 +34764,7 @@ var findFiles = async (root, name) => {
34347
34764
  visited += 1;
34348
34765
  if (visited > MAX_SEARCH_FILES)
34349
34766
  throw new TypeError("Downloaded GitHub artifact contains too many files.");
34350
- const path = join25(directory, entry.name);
34767
+ const path = join26(directory, entry.name);
34351
34768
  if (entry.isDirectory()) {
34352
34769
  await walk(path);
34353
34770
  return;
@@ -34461,11 +34878,11 @@ var auditAbsoluteMobileCiPromotion = async (options) => {
34461
34878
  const output = projectPath(options.projectRoot, options.outputDirectory ?? `.absolutejs/mobile-ci/audits/${promotionRunId}`);
34462
34879
  if (await access19(output).then(() => true).catch(() => false))
34463
34880
  throw new TypeError(`Mobile CI audit output already exists: ${output}`);
34464
- await mkdir19(dirname17(output), { recursive: true });
34465
- const staging = await mkdtemp11(join25(dirname17(output), ".promotion-audit-"));
34881
+ await mkdir20(dirname17(output), { recursive: true });
34882
+ const staging = await mkdtemp11(join26(dirname17(output), ".promotion-audit-"));
34466
34883
  try {
34467
- const evidenceRoot = join25(staging, "promotion-evidence");
34468
- await mkdir19(evidenceRoot);
34884
+ const evidenceRoot = join26(staging, "promotion-evidence");
34885
+ await mkdir20(evidenceRoot);
34469
34886
  await requireCommand(runner, [
34470
34887
  "gh",
34471
34888
  "run",
@@ -34495,8 +34912,8 @@ var auditAbsoluteMobileCiPromotion = async (options) => {
34495
34912
  if (context && options.sourceRunId && context.sourceRunId !== sourceRunId)
34496
34913
  throw new TypeError("Requested source run does not match promotion context.");
34497
34914
  const sourceArtifact = context?.sourceArtifact ?? `absolute-mobile-${platform3}`;
34498
- const sourceRoot = join25(staging, "source-release");
34499
- await mkdir19(sourceRoot);
34915
+ const sourceRoot = join26(staging, "source-release");
34916
+ await mkdir20(sourceRoot);
34500
34917
  await requireCommand(runner, [
34501
34918
  "gh",
34502
34919
  "run",
@@ -34579,9 +34996,9 @@ var auditAbsoluteMobileCiPromotion = async (options) => {
34579
34996
  verifiedAt: new Date().toISOString()
34580
34997
  };
34581
34998
  await Promise.all([
34582
- writeFile19(join25(staging, "audit.json"), `${JSON.stringify(audit, null, 2)}
34999
+ writeFile19(join26(staging, "audit.json"), `${JSON.stringify(audit, null, 2)}
34583
35000
  `, { mode: 384 }),
34584
- writeFile19(join25(staging, "audit.md"), renderAuditMarkdown(audit), {
35001
+ writeFile19(join26(staging, "audit.md"), renderAuditMarkdown(audit), {
34585
35002
  mode: 384
34586
35003
  })
34587
35004
  ]);
@@ -34597,14 +35014,14 @@ import {
34597
35014
  access as access20,
34598
35015
  link,
34599
35016
  lstat as lstat2,
34600
- mkdir as mkdir20,
35017
+ mkdir as mkdir21,
34601
35018
  open,
34602
35019
  readFile as readFile24,
34603
35020
  readdir as readdir8,
34604
35021
  rename as rename16,
34605
35022
  rm as rm16
34606
35023
  } from "fs/promises";
34607
- import { dirname as dirname18, isAbsolute as isAbsolute12, join as join26, relative as relative19, resolve as resolve21, sep as sep13 } from "path";
35024
+ import { dirname as dirname18, isAbsolute as isAbsolute12, join as join27, relative as relative19, resolve as resolve21, sep as sep13 } from "path";
34608
35025
  import { randomUUID as randomUUID5 } from "crypto";
34609
35026
  var ABSOLUTE_MOBILE_CI_PROMOTION_OPERATION_FORMAT = 1;
34610
35027
  var MAX_OPERATION_BYTES = 65536;
@@ -34670,8 +35087,8 @@ var runId2 = (value, label) => {
34670
35087
  return parsed;
34671
35088
  };
34672
35089
  var nullableRunId = (value, label) => value === null ? null : runId2(value, label);
34673
- var operationRoot = (projectRoot) => join26(resolve21(projectRoot), ".absolutejs", "mobile-ci", "promotions");
34674
- var absoluteMobilePromotionOperationPath = (projectRoot, requestedDispatchId) => join26(operationRoot(projectRoot), dispatchId2(requestedDispatchId), "operation.json");
35090
+ var operationRoot = (projectRoot) => join27(resolve21(projectRoot), ".absolutejs", "mobile-ci", "promotions");
35091
+ var absoluteMobilePromotionOperationPath = (projectRoot, requestedDispatchId) => join27(operationRoot(projectRoot), dispatchId2(requestedDispatchId), "operation.json");
34675
35092
  var operationPhase = (value) => {
34676
35093
  const phase = PHASES.find((candidate) => candidate === value);
34677
35094
  if (!phase)
@@ -34741,8 +35158,8 @@ var writeSynced = async (path, source) => {
34741
35158
  }
34742
35159
  };
34743
35160
  var atomicWrite = async (path, source, exclusive) => {
34744
- await mkdir20(dirname18(path), { recursive: true });
34745
- const temporary = join26(dirname18(path), `.operation-${randomUUID5()}.tmp`);
35161
+ await mkdir21(dirname18(path), { recursive: true });
35162
+ const temporary = join27(dirname18(path), `.operation-${randomUUID5()}.tmp`);
34746
35163
  try {
34747
35164
  await writeSynced(temporary, source);
34748
35165
  if (exclusive)
@@ -34812,7 +35229,7 @@ var readAbsoluteMobilePromotionOperation = async (projectRoot, requestedDispatch
34812
35229
  var relativeAbsoluteMobilePromotionOperationPath = (projectRoot, dispatchIdValue) => relative19(resolve21(projectRoot), absoluteMobilePromotionOperationPath(projectRoot, dispatchIdValue)).replaceAll("\\", "/");
34813
35230
  // src/mobile/ciWorkflow.ts
34814
35231
  import { existsSync as existsSync4 } from "fs";
34815
- import { access as access21, mkdir as mkdir21, readFile as readFile25, writeFile as writeFile20 } from "fs/promises";
35232
+ import { access as access21, mkdir as mkdir22, readFile as readFile25, writeFile as writeFile20 } from "fs/promises";
34816
35233
  import { dirname as dirname19, extname as extname5, relative as relative20, resolve as resolve22, sep as sep14 } from "path";
34817
35234
  var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 4;
34818
35235
  var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
@@ -35624,7 +36041,7 @@ var writeAbsoluteMobileGithubWorkflow = async (options) => {
35624
36041
  if (previous !== undefined && previous !== generated.workflow && !options.force)
35625
36042
  throw new TypeError(`${relative20(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
35626
36043
  if (previous !== generated.workflow) {
35627
- await mkdir21(dirname19(path), { recursive: true });
36044
+ await mkdir22(dirname19(path), { recursive: true });
35628
36045
  await writeFile20(path, generated.workflow);
35629
36046
  }
35630
36047
  return {
@@ -35644,7 +36061,7 @@ init_mobilePreview();
35644
36061
 
35645
36062
  // src/mobile/nativeDeepLinks.ts
35646
36063
  import { readFile as readFile26, rename as rename17, writeFile as writeFile21 } from "fs/promises";
35647
- import { join as join29 } from "path";
36064
+ import { join as join30 } from "path";
35648
36065
  var START_MARKER = "<!-- absolutejs:deep-links:start -->";
35649
36066
  var END_MARKER = "<!-- absolutejs:deep-links:end -->";
35650
36067
  var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
@@ -35701,7 +36118,7 @@ ${hosts}
35701
36118
  `;
35702
36119
  };
35703
36120
  var configureAndroid = async (config) => {
35704
- const path = join29(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
36121
+ const path = join30(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
35705
36122
  const source = await readFile26(path, "utf8");
35706
36123
  const mainActivity = source.indexOf('android:name=".MainActivity"');
35707
36124
  if (mainActivity === NOT_FOUND) {
@@ -35727,7 +36144,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
35727
36144
  ${END_MARKER}
35728
36145
  `;
35729
36146
  var configureIosInfo = async (config) => {
35730
- const path = join29(config.nativeProjectDirectory, "ios/App/App/Info.plist");
36147
+ const path = join30(config.nativeProjectDirectory, "ios/App/App/Info.plist");
35731
36148
  const source = await readFile26(path, "utf8");
35732
36149
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
35733
36150
  ${END_MARKER}
@@ -35751,7 +36168,7 @@ ${domains}
35751
36168
  `;
35752
36169
  };
35753
36170
  var configureIosEntitlements = async (config) => {
35754
- const path = join29(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
36171
+ const path = join30(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
35755
36172
  let current = "";
35756
36173
  try {
35757
36174
  current = await readFile26(path, "utf8");
@@ -35769,7 +36186,7 @@ var configureIosEntitlements = async (config) => {
35769
36186
  return true;
35770
36187
  };
35771
36188
  var configureIosProject = async (config) => {
35772
- const path = join29(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
36189
+ const path = join30(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
35773
36190
  const source = await readFile26(path, "utf8");
35774
36191
  const declarations = [
35775
36192
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
@@ -35810,7 +36227,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
35810
36227
  // src/mobile/nativeDeviceCapabilities.ts
35811
36228
  init_deviceCapabilities();
35812
36229
  import { readFile as readFile27, rename as rename18, writeFile as writeFile22 } from "fs/promises";
35813
- import { join as join30 } from "path";
36230
+ import { join as join31 } from "path";
35814
36231
  var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
35815
36232
  var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
35816
36233
  var NOT_FOUND2 = -1;
@@ -35960,7 +36377,7 @@ var writeIosPrivacyManifest = async (path, current, source) => {
35960
36377
  var configureIosPrivacyProject = async (config, requirements) => {
35961
36378
  if (requirements.iosPrivacyAccessedApis.length === 0)
35962
36379
  return false;
35963
- const projectPath3 = join30(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
36380
+ const projectPath3 = join31(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
35964
36381
  const project = await readFile27(projectPath3, "utf8");
35965
36382
  return writeChangedFile2(projectPath3, addIosPrivacyProjectReference(project));
35966
36383
  };
@@ -36013,7 +36430,7 @@ ${next.slice(index)}`;
36013
36430
  return next;
36014
36431
  };
36015
36432
  var configureIos2 = async (config, plan) => {
36016
- const path = join30(config.nativeProjectDirectory, "ios/App/App/Info.plist");
36433
+ const path = join31(config.nativeProjectDirectory, "ios/App/App/Info.plist");
36017
36434
  const source = await readFile27(path, "utf8");
36018
36435
  const requirements = absoluteDeviceNativeRequirements(plan);
36019
36436
  const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
@@ -36034,7 +36451,7 @@ ${content}
36034
36451
  ${END_MARKER2}
36035
36452
  ` : "";
36036
36453
  const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
36037
- const privacyPath = join30(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
36454
+ const privacyPath = join31(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
36038
36455
  const privacyCurrent = await optionalSource(privacyPath);
36039
36456
  const privacySource = privacyManifestSource(privacyCurrent, requirements);
36040
36457
  const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
@@ -36045,7 +36462,7 @@ ${content}
36045
36462
  return infoChanged || privacyChanged || projectChanged || pushChanged;
36046
36463
  };
36047
36464
  var configureIosPushNotifications = async (config, enabled) => {
36048
- const entitlementsPath = join30(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
36465
+ const entitlementsPath = join31(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
36049
36466
  const entitlements = await optionalSource(entitlementsPath);
36050
36467
  if (entitlements === null && !enabled)
36051
36468
  return false;
@@ -36057,7 +36474,7 @@ var configureIosPushNotifications = async (config, enabled) => {
36057
36474
  <!-- ${PUSH_END_MARKER} -->
36058
36475
  ` : "";
36059
36476
  const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
36060
- const delegatePath = join30(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
36477
+ const delegatePath = join31(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
36061
36478
  const delegate = await optionalSource(delegatePath);
36062
36479
  if (delegate === null && !enabled)
36063
36480
  return false;
@@ -36106,7 +36523,7 @@ var replacePushRegion = (source, region, insertion) => {
36106
36523
  return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
36107
36524
  };
36108
36525
  var configureAndroid2 = async (config, plan) => {
36109
- const path = join30(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
36526
+ const path = join31(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
36110
36527
  const source = await readFile27(path, "utf8");
36111
36528
  const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
36112
36529
  const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
@@ -36135,14 +36552,14 @@ ${content}
36135
36552
  const clients = typeof firebase === "object" && firebase !== null ? Reflect.get(firebase, "client") : undefined;
36136
36553
  const matchesApp = Array.isArray(clients) && clients.some((client) => {
36137
36554
  const info = typeof client === "object" && client !== null ? Reflect.get(client, "client_info") : undefined;
36138
- const android = typeof info === "object" && info !== null ? Reflect.get(info, "android_client_info") : undefined;
36139
- return typeof android === "object" && android !== null && Reflect.get(android, "package_name") === config.appId;
36555
+ const android2 = typeof info === "object" && info !== null ? Reflect.get(info, "android_client_info") : undefined;
36556
+ return typeof android2 === "object" && android2 !== null && Reflect.get(android2, "package_name") === config.appId;
36140
36557
  });
36141
36558
  if (!matchesApp)
36142
36559
  throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
36143
36560
  const [manifestChanged, firebaseChanged] = await Promise.all([
36144
36561
  writeChangedFile2(path, nextManifest),
36145
- writeOptionalChangedFile(join30(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
36562
+ writeOptionalChangedFile(join31(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
36146
36563
  ]);
36147
36564
  return manifestChanged || firebaseChanged;
36148
36565
  };
@@ -36161,14 +36578,14 @@ init_nativeAuth();
36161
36578
 
36162
36579
  // src/mobile/nativeUpdates.ts
36163
36580
  import {
36164
- mkdir as mkdir22,
36581
+ mkdir as mkdir23,
36165
36582
  readFile as readFile28,
36166
36583
  readdir as readdir9,
36167
36584
  rename as rename19,
36168
36585
  rm as rm17,
36169
36586
  writeFile as writeFile23
36170
36587
  } from "fs/promises";
36171
- import { dirname as dirname21, join as join31 } from "path";
36588
+ import { dirname as dirname21, join as join32 } from "path";
36172
36589
  var START = "// absolutejs:mobile-updates:start";
36173
36590
  var END = "// absolutejs:mobile-updates:end";
36174
36591
  var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
@@ -36188,7 +36605,7 @@ var writeChanged = async (path, source) => {
36188
36605
  const current = await optionalSource2(path);
36189
36606
  if (current === source)
36190
36607
  return false;
36191
- await mkdir22(dirname21(path), { recursive: true });
36608
+ await mkdir23(dirname21(path), { recursive: true });
36192
36609
  if (current === null) {
36193
36610
  await writeFile23(path, source, { flag: "wx" });
36194
36611
  return true;
@@ -36338,8 +36755,8 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
36338
36755
  ${PLUGIN_END}
36339
36756
  `;
36340
36757
  var configureIos3 = async (config, enabled) => {
36341
- const path = join31(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
36342
- const capacitorConfigPath = join31(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
36758
+ const path = join32(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
36759
+ const capacitorConfigPath = join32(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
36343
36760
  let source = await readFile28(path, "utf8");
36344
36761
  const launch2 = source.indexOf("didFinishLaunchingWithOptions");
36345
36762
  const brace = launch2 < 0 ? -1 : source.indexOf("{", launch2);
@@ -36349,8 +36766,8 @@ var configureIos3 = async (config, enabled) => {
36349
36766
  ` : "";
36350
36767
  source = replaceMarkedRegion(source, START, END, launchRegion, brace < 0 ? -1 : source.indexOf(`
36351
36768
  `, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
36352
- const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
36353
- source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
36769
+ const plugin2 = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
36770
+ source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin2, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
36354
36771
  const capacitorConfigSource2 = await readFile28(capacitorConfigPath, "utf8");
36355
36772
  let capacitorConfig;
36356
36773
  try {
@@ -36531,12 +36948,12 @@ var androidActivityInRoot = async (root) => {
36531
36948
  throw error;
36532
36949
  }
36533
36950
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
36534
- return candidate ? join31(root, candidate) : undefined;
36951
+ return candidate ? join32(root, candidate) : undefined;
36535
36952
  };
36536
36953
  var androidActivity = async (config) => {
36537
36954
  const roots = [
36538
- join31(config.nativeProjectDirectory, "android/app/src/main/java"),
36539
- join31(config.nativeProjectDirectory, "android/app/src/main/kotlin")
36955
+ join32(config.nativeProjectDirectory, "android/app/src/main/java"),
36956
+ join32(config.nativeProjectDirectory, "android/app/src/main/kotlin")
36540
36957
  ];
36541
36958
  const candidates = await Promise.all(roots.map(androidActivityInRoot));
36542
36959
  const candidate = candidates.find((value) => value !== undefined);
@@ -36640,7 +37057,7 @@ var configureAndroid3 = async (config, enabled) => {
36640
37057
  if (!packageName)
36641
37058
  throw new TypeError("Android MainActivity package declaration was not found.");
36642
37059
  const packagePath = packageName.replaceAll(".", "/");
36643
- const pluginPath = join31(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
37060
+ const pluginPath = join32(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
36644
37061
  const changed = await Promise.all([
36645
37062
  writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
36646
37063
  enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
@@ -36660,14 +37077,14 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
36660
37077
  };
36661
37078
  // src/mobile/nativeObservability.ts
36662
37079
  import {
36663
- mkdir as mkdir23,
37080
+ mkdir as mkdir24,
36664
37081
  readFile as readFile29,
36665
37082
  readdir as readdir10,
36666
37083
  rename as rename20,
36667
37084
  rm as rm18,
36668
37085
  writeFile as writeFile24
36669
37086
  } from "fs/promises";
36670
- import { dirname as dirname22, join as join32 } from "path";
37087
+ import { dirname as dirname22, join as join33 } from "path";
36671
37088
  var START2 = "// absolutejs:native-observability:start";
36672
37089
  var END2 = "// absolutejs:native-observability:end";
36673
37090
  var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
@@ -36686,7 +37103,7 @@ var writeChanged2 = async (path, source) => {
36686
37103
  const current = await optionalSource3(path);
36687
37104
  if (current === source)
36688
37105
  return false;
36689
- await mkdir23(dirname22(path), { recursive: true });
37106
+ await mkdir24(dirname22(path), { recursive: true });
36690
37107
  if (current === null) {
36691
37108
  await writeFile24(path, source, { flag: "wx" });
36692
37109
  return true;
@@ -36835,8 +37252,8 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
36835
37252
  ${PLUGIN_END2}
36836
37253
  `;
36837
37254
  var configureIos4 = async (config, enabled) => {
36838
- const path = join32(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
36839
- const capacitorConfigPath = join32(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
37255
+ const path = join33(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
37256
+ const capacitorConfigPath = join33(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
36840
37257
  let source = await readFile29(path, "utf8");
36841
37258
  if (enabled && !source.includes("import MetricKit")) {
36842
37259
  const capacitorImport = source.lastIndexOf("import Capacitor");
@@ -37096,12 +37513,12 @@ var androidActivityInRoot2 = async (root) => {
37096
37513
  throw error;
37097
37514
  }
37098
37515
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
37099
- return candidate ? join32(root, candidate) : undefined;
37516
+ return candidate ? join33(root, candidate) : undefined;
37100
37517
  };
37101
37518
  var androidActivity2 = async (config) => {
37102
37519
  const roots = [
37103
- join32(config.nativeProjectDirectory, "android/app/src/main/java"),
37104
- join32(config.nativeProjectDirectory, "android/app/src/main/kotlin")
37520
+ join33(config.nativeProjectDirectory, "android/app/src/main/java"),
37521
+ join33(config.nativeProjectDirectory, "android/app/src/main/kotlin")
37105
37522
  ];
37106
37523
  const candidates = await Promise.all(roots.map(androidActivityInRoot2));
37107
37524
  const candidate = candidates.find((value) => value !== undefined);
@@ -37173,7 +37590,7 @@ var configureAndroid4 = async (config, enabled) => {
37173
37590
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
37174
37591
  if (!packageName)
37175
37592
  throw new TypeError("Android MainActivity package declaration was not found.");
37176
- const pluginPath = join32(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
37593
+ const pluginPath = join33(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
37177
37594
  const changed = await Promise.all([
37178
37595
  writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
37179
37596
  enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
@@ -37192,8 +37609,8 @@ var applyAbsoluteNativeObservability = async (config, platforms = config.platfor
37192
37609
  return { changed: changed.some(Boolean) };
37193
37610
  };
37194
37611
  // src/mobile/nativeReleaseReadiness.ts
37195
- import { mkdir as mkdir24, readFile as readFile30, readdir as readdir11, rename as rename21, writeFile as writeFile25 } from "fs/promises";
37196
- import { dirname as dirname23, join as join33 } from "path";
37612
+ import { mkdir as mkdir25, readFile as readFile30, readdir as readdir11, rename as rename21, writeFile as writeFile25 } from "fs/promises";
37613
+ import { dirname as dirname23, join as join34 } from "path";
37197
37614
  var START3 = "// absolutejs:release-readiness:start";
37198
37615
  var END3 = "// absolutejs:release-readiness:end";
37199
37616
  var IOS_PLUGIN_START = "// absolutejs:release-readiness-plugin:start";
@@ -37212,7 +37629,7 @@ var writeChanged3 = async (path, source) => {
37212
37629
  const current = await optionalSource4(path);
37213
37630
  if (current === source)
37214
37631
  return false;
37215
- await mkdir24(dirname23(path), { recursive: true });
37632
+ await mkdir25(dirname23(path), { recursive: true });
37216
37633
  if (current === null) {
37217
37634
  await writeFile25(path, source, { flag: "wx" });
37218
37635
  return true;
@@ -37232,12 +37649,12 @@ var activityInRoot = async (root) => {
37232
37649
  throw error;
37233
37650
  }
37234
37651
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
37235
- return candidate ? join33(root, candidate) : undefined;
37652
+ return candidate ? join34(root, candidate) : undefined;
37236
37653
  };
37237
37654
  var activityPath = async (config) => {
37238
37655
  const roots = [
37239
- join33(config.nativeProjectDirectory, "android/app/src/main/java"),
37240
- join33(config.nativeProjectDirectory, "android/app/src/main/kotlin")
37656
+ join34(config.nativeProjectDirectory, "android/app/src/main/java"),
37657
+ join34(config.nativeProjectDirectory, "android/app/src/main/kotlin")
37241
37658
  ];
37242
37659
  const candidates = await Promise.all(roots.map(activityInRoot));
37243
37660
  const candidate = candidates.find((value) => value !== undefined);
@@ -37347,8 +37764,8 @@ var replaceIosPluginRegion = (appDelegate, existingStart, existingEnd) => {
37347
37764
  return `${appDelegate.slice(0, from)}${iosPluginRegion3}${appDelegate.slice(through)}`;
37348
37765
  };
37349
37766
  var configureIos5 = async (config) => {
37350
- const appDelegatePath = join33(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
37351
- const capacitorConfigPath = join33(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
37767
+ const appDelegatePath = join34(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
37768
+ const capacitorConfigPath = join34(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
37352
37769
  const appDelegate = await readFile30(appDelegatePath, "utf8");
37353
37770
  const existingStart = appDelegate.indexOf(IOS_PLUGIN_START);
37354
37771
  const existingEnd = appDelegate.indexOf(IOS_PLUGIN_END);
@@ -37388,7 +37805,7 @@ var configureAndroid5 = async (config) => {
37388
37805
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
37389
37806
  if (!packageName)
37390
37807
  throw new TypeError("Android MainActivity package declaration was not found.");
37391
- const pluginPath = join33(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN3);
37808
+ const pluginPath = join34(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN3);
37392
37809
  const changed = await Promise.all([
37393
37810
  writeChanged3(mainActivityPath, injectRegistration(activity)),
37394
37811
  writeChanged3(pluginPath, pluginSource(packageName))
@@ -38129,11 +38546,11 @@ var resolveAbsoluteHttpUrl = (target, origin) => {
38129
38546
  var createAbsoluteHttpTransport = ({
38130
38547
  fetch: fetchImpl = globalThis.fetch,
38131
38548
  origin,
38132
- runtime: runtime2
38549
+ runtime: runtime3
38133
38550
  }) => ({
38134
38551
  fetch: fetchImpl,
38135
38552
  origin: normalizeAbsoluteHttpOrigin(origin),
38136
- runtime: runtime2
38553
+ runtime: runtime3
38137
38554
  });
38138
38555
  var createWebHttpTransport = (options = {}) => {
38139
38556
  const origin = options.origin ?? globalThis.location?.origin;
@@ -38316,8 +38733,8 @@ var createCapacitor = (win) => {
38316
38733
  };
38317
38734
  const isNativePlatform = () => getPlatform() !== "web";
38318
38735
  const isPluginAvailable = (pluginName) => {
38319
- const plugin = registeredPlugins.get(pluginName);
38320
- if (plugin === null || plugin === undefined ? undefined : plugin.platforms.has(getPlatform())) {
38736
+ const plugin2 = registeredPlugins.get(pluginName);
38737
+ if (plugin2 === null || plugin2 === undefined ? undefined : plugin2.platforms.has(getPlatform())) {
38321
38738
  return true;
38322
38739
  }
38323
38740
  if (getPluginHeader(pluginName)) {
@@ -38872,12 +39289,12 @@ var drainAbsoluteMobileNativeObservability = async (manifest, fetch2, options =
38872
39289
  const config = manifest.observability;
38873
39290
  if (!config || !(options.native ?? Capacitor.isNativePlatform()))
38874
39291
  return 0;
38875
- const plugin = options.plugin ?? nativeObservability;
38876
- const pending = await plugin.pending();
39292
+ const plugin2 = options.plugin ?? nativeObservability;
39293
+ const pending = await plugin2.pending();
38877
39294
  const reports = pending.reports.slice(0, MAX_REPORTS).map(parseReport).filter((report) => report !== undefined);
38878
39295
  const discarded = reports.filter((report) => !sampled(report.id, config.sampleRate));
38879
39296
  if (discarded.length > 0)
38880
- await plugin.acknowledge({
39297
+ await plugin2.acknowledge({
38881
39298
  ids: discarded.map(({ id }) => id)
38882
39299
  });
38883
39300
  const selected = reports.filter((report) => sampled(report.id, config.sampleRate));
@@ -38897,7 +39314,7 @@ var drainAbsoluteMobileNativeObservability = async (manifest, fetch2, options =
38897
39314
  });
38898
39315
  if (!response.ok)
38899
39316
  return 0;
38900
- await plugin.acknowledge({
39317
+ await plugin2.acknowledge({
38901
39318
  ids: selected.map(({ id }) => id)
38902
39319
  });
38903
39320
  return selected.length;
@@ -44270,7 +44687,7 @@ import { pathToFileURL as pathToFileURL4 } from "url";
44270
44687
  import { createHash as createHash18, sign, verify } from "crypto";
44271
44688
  import {
44272
44689
  cp as cp2,
44273
- mkdir as mkdir25,
44690
+ mkdir as mkdir26,
44274
44691
  mkdtemp as mkdtemp12,
44275
44692
  readdir as readdir12,
44276
44693
  readFile as readFile31,
@@ -44279,14 +44696,14 @@ import {
44279
44696
  stat as stat8,
44280
44697
  writeFile as writeFile26
44281
44698
  } from "fs/promises";
44282
- import { dirname as dirname25, join as join34, relative as relative23, resolve as resolve25 } from "path";
44699
+ import { dirname as dirname25, join as join35, relative as relative23, resolve as resolve25 } from "path";
44283
44700
  var UPDATE_MANIFEST_FILE = "update.json";
44284
44701
  var UPDATE_FILES_DIRECTORY = "files";
44285
44702
  var sha2565 = (value) => createHash18("sha256").update(value).digest("hex");
44286
44703
  var listFiles = async (root, directory = root) => {
44287
44704
  const entries = await readdir12(directory, { withFileTypes: true });
44288
44705
  const paths = await Promise.all(entries.map(async (entry) => {
44289
- const path = join34(directory, entry.name);
44706
+ const path = join35(directory, entry.name);
44290
44707
  if (entry.isDirectory())
44291
44708
  return listFiles(root, path);
44292
44709
  if (!entry.isFile())
@@ -44296,7 +44713,7 @@ var listFiles = async (root, directory = root) => {
44296
44713
  return paths.flat().sort((left, right) => left.localeCompare(right));
44297
44714
  };
44298
44715
  var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
44299
- const source = join34(root, path);
44716
+ const source = join35(root, path);
44300
44717
  const [metadata, contents] = await Promise.all([
44301
44718
  stat8(source),
44302
44719
  readFile31(source)
@@ -44334,15 +44751,15 @@ var buildAbsoluteMobileUpdate = async (options) => {
44334
44751
  value: signature.toString("base64")
44335
44752
  }
44336
44753
  });
44337
- await mkdir25(outputRoot, { recursive: true });
44338
- const outputDirectory = join34(outputRoot, manifest.releaseId);
44339
- const staging = await mkdtemp12(join34(outputRoot, ".stage-"));
44754
+ await mkdir26(outputRoot, { recursive: true });
44755
+ const outputDirectory = join35(outputRoot, manifest.releaseId);
44756
+ const staging = await mkdtemp12(join35(outputRoot, ".stage-"));
44340
44757
  try {
44341
- await cp2(bundleDirectory, join34(staging, UPDATE_FILES_DIRECTORY), {
44758
+ await cp2(bundleDirectory, join35(staging, UPDATE_FILES_DIRECTORY), {
44342
44759
  force: true,
44343
44760
  recursive: true
44344
44761
  });
44345
- await writeFile26(join34(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
44762
+ await writeFile26(join35(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
44346
44763
  `);
44347
44764
  await rename22(staging, outputDirectory);
44348
44765
  } catch (error) {
@@ -44353,7 +44770,7 @@ var buildAbsoluteMobileUpdate = async (options) => {
44353
44770
  }
44354
44771
  return {
44355
44772
  manifest,
44356
- manifestPath: join34(outputDirectory, UPDATE_MANIFEST_FILE),
44773
+ manifestPath: join35(outputDirectory, UPDATE_MANIFEST_FILE),
44357
44774
  outputDirectory
44358
44775
  };
44359
44776
  };
@@ -44362,10 +44779,10 @@ var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) =>
44362
44779
  const root = resolve25(updateDirectory, UPDATE_FILES_DIRECTORY);
44363
44780
  if (!source.startsWith(`${root}/`))
44364
44781
  throw new TypeError("Update file escaped its release.");
44365
- await mkdir25(dirname25(destination), { recursive: true });
44782
+ await mkdir26(dirname25(destination), { recursive: true });
44366
44783
  await cp2(source, destination, { force: true });
44367
44784
  };
44368
- var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile31(join34(resolve25(directory), UPDATE_MANIFEST_FILE), "utf8")));
44785
+ var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile31(join35(resolve25(directory), UPDATE_MANIFEST_FILE), "utf8")));
44369
44786
  var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
44370
44787
  const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
44371
44788
  const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
@@ -44811,6 +45228,7 @@ export {
44811
45228
  pauseAbsoluteMobileUpdateRollout,
44812
45229
  planAbsoluteExpoDevSession,
44813
45230
  prepareAbsoluteAndroidRelease,
45231
+ prepareAbsoluteCapacitorInitialization,
44814
45232
  prepareAbsoluteIosDevProject,
44815
45233
  prepareAbsoluteIosRelease,
44816
45234
  projectImportsAbsoluteDeviceCapability,
@@ -44890,5 +45308,5 @@ export {
44890
45308
  writeAbsoluteMobileUpdateRegistry
44891
45309
  };
44892
45310
 
44893
- //# debugId=B5D4F1D4350A15F564756E2164756E21
45311
+ //# debugId=0FE744BA265F0CF164756E2164756E21
44894
45312
  //# sourceMappingURL=index.js.map