@absolutejs/absolute 0.20.0-beta.103 → 0.20.0-beta.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/changelog.json +33 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/{compile-4xbpm6hf.js → compile-hsbs1xf6.js} +2 -2
- package/dist/cli/{dev-m4r4zs2k.js → dev-9cp5t2n1.js} +4 -4
- package/dist/cli/{expoProject-780thyfd.js → expoProject-zkprmjjz.js} +1 -1
- package/dist/cli/{index-d5fr1xp3.js → index-0zcebhm4.js} +59 -1
- package/dist/cli/{index-wpfvpsk7.js → index-5skbydh0.js} +1 -1
- package/dist/cli/{index-3sdvzrv2.js → index-7fxrgx5q.js} +1 -1
- package/dist/cli/{index-6ff78meg.js → index-hrzd7e5x.js} +10 -2
- package/dist/cli/{index-rvpd4w9t.js → index-mazxtfh4.js} +1 -1
- package/dist/cli/{index-qxnptvwn.js → index-q1d4ns4n.js} +100 -9
- package/dist/cli/index.js +5 -5
- package/dist/cli/{iosNativeWatcher-3k715hq0.js → iosNativeWatcher-t6gv0p1w.js} +2 -2
- package/dist/cli/{iosSimulatorController-dr98a0p9.js → iosSimulatorController-5n2a9fxv.js} +2 -2
- package/dist/cli/{mobile-6xe6zysv.js → mobile-fbtq3s5x.js} +1240 -370
- package/dist/cli/{remoteMacProtocol-kqvkp0qd.js → remoteMacProtocol-bbramzh6.js} +2 -2
- package/dist/cli/{start-nmyy64tr.js → start-5grq7nfr.js} +3 -3
- package/dist/mobile/index.js +1340 -571
- package/dist/mobile/index.js.map +10 -8
- package/dist/mobile/remoteMacAgentEntry.js +302 -255
- package/dist/src/mobile/index.d.ts +2 -0
- package/dist/src/mobile/iosRelease.d.ts +31 -7
- package/dist/src/mobile/iosReleaseAcceptance.d.ts +63 -0
- package/dist/src/mobile/iosTestReport.d.ts +1 -0
- package/dist/src/mobile/nativeReleaseReadiness.d.ts +5 -0
- package/dist/src/mobile/nativeTestReport.d.ts +15 -0
- package/dist/src/mobile/releaseDoctor.d.ts +2 -0
- package/dist/src/mobile/remoteMacProtocol.d.ts +7 -1
- package/dist/src/mobile/shellReleaseReadiness.d.ts +2 -0
- package/package.json +2 -1
package/dist/mobile/index.js
CHANGED
|
@@ -611,11 +611,11 @@ __export(exports_config, {
|
|
|
611
611
|
normalizeAbsoluteMobileConfig: () => normalizeAbsoluteMobileConfig
|
|
612
612
|
});
|
|
613
613
|
import { readFileSync as readFileSync2 } from "fs";
|
|
614
|
-
import { resolve as
|
|
615
|
-
import { createHash as
|
|
614
|
+
import { resolve as resolve8 } from "path";
|
|
615
|
+
import { createHash as createHash10, createPublicKey, X509Certificate as X509Certificate2 } from "crypto";
|
|
616
616
|
var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, UPDATE_NAME_PATTERN, UPDATE_PUBLIC_KEY_PATTERN, ENVIRONMENT_NAME_PATTERN, DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000, DEFAULT_UPDATE_HEALTH_FAILURE_RATE = 0.2, DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS = 20, DEFAULT_UPDATE_ROLLOUT_FAILURE_RATE = 0.05, DEFAULT_UPDATE_ROLLOUT_OBSERVATION_MINUTES = 60, MINUTE_MS, DEFAULT_UPDATE_ROLLOUT_STAGES, MINIMUM_UPDATE_BOOT_TIMEOUT_MS = 5000, MAXIMUM_UPDATE_BOOT_TIMEOUT_MS = 120000, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field2) => {
|
|
617
|
-
const root =
|
|
618
|
-
const path =
|
|
617
|
+
const root = resolve8(projectRoot);
|
|
618
|
+
const path = resolve8(root, value);
|
|
619
619
|
if (path !== root && !path.startsWith(`${root}/`)) {
|
|
620
620
|
throw new TypeError(`${field2} must remain inside the project root.`);
|
|
621
621
|
}
|
|
@@ -787,7 +787,7 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
|
|
|
787
787
|
expoCodeSigning = {
|
|
788
788
|
algorithm: "rsa-v1_5-sha256",
|
|
789
789
|
certificatePem,
|
|
790
|
-
certificateSha256:
|
|
790
|
+
certificateSha256: createHash10("sha256").update(certificate.raw).digest("hex"),
|
|
791
791
|
keyId
|
|
792
792
|
};
|
|
793
793
|
}
|
|
@@ -1017,14 +1017,14 @@ __export(exports_associationFiles, {
|
|
|
1017
1017
|
verifyAbsoluteMobileAssociationFiles: () => verifyAbsoluteMobileAssociationFiles
|
|
1018
1018
|
});
|
|
1019
1019
|
import {
|
|
1020
|
-
access as
|
|
1021
|
-
mkdir as
|
|
1022
|
-
readFile as
|
|
1020
|
+
access as access10,
|
|
1021
|
+
mkdir as mkdir9,
|
|
1022
|
+
readFile as readFile12,
|
|
1023
1023
|
rename as rename9,
|
|
1024
|
-
rm as
|
|
1024
|
+
rm as rm9,
|
|
1025
1025
|
writeFile as writeFile9
|
|
1026
1026
|
} from "fs/promises";
|
|
1027
|
-
import { resolve as
|
|
1027
|
+
import { resolve as resolve9 } from "path";
|
|
1028
1028
|
import { Elysia } from "elysia";
|
|
1029
1029
|
var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERIFY_TIMEOUT_MS = 1e4, ANDROID_ASSOCIATION_PATH = "/.well-known/assetlinks.json", APPLE_ASSOCIATION_PATH = "/.well-known/apple-app-site-association", missingIdentity = (field2, platform2) => new TypeError(`${field2} is required to publish ${platform2} deep-link association files.`), createAppleDocument = (config, requireAll) => {
|
|
1030
1030
|
if (!config.platforms.includes("ios"))
|
|
@@ -1091,7 +1091,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
|
|
|
1091
1091
|
}, writeAtomic = async (path, source) => {
|
|
1092
1092
|
let current;
|
|
1093
1093
|
try {
|
|
1094
|
-
current = await
|
|
1094
|
+
current = await readFile12(path, "utf8");
|
|
1095
1095
|
} catch (error) {
|
|
1096
1096
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
1097
1097
|
throw error;
|
|
@@ -1103,18 +1103,18 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
|
|
|
1103
1103
|
await writeFile9(temporary, source, { flag: "wx" });
|
|
1104
1104
|
await rename9(temporary, path);
|
|
1105
1105
|
return true;
|
|
1106
|
-
},
|
|
1106
|
+
}, exists4 = async (path) => {
|
|
1107
1107
|
try {
|
|
1108
|
-
await
|
|
1108
|
+
await access10(path);
|
|
1109
1109
|
return true;
|
|
1110
1110
|
} catch {
|
|
1111
1111
|
return false;
|
|
1112
1112
|
}
|
|
1113
1113
|
}, assertOwnedOutput = async (root) => {
|
|
1114
|
-
const path =
|
|
1114
|
+
const path = resolve9(root, OWNERSHIP_FILE);
|
|
1115
1115
|
let ownership;
|
|
1116
1116
|
try {
|
|
1117
|
-
ownership = JSON.parse(await
|
|
1117
|
+
ownership = JSON.parse(await readFile12(path, "utf8"));
|
|
1118
1118
|
} catch {
|
|
1119
1119
|
throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
|
|
1120
1120
|
}
|
|
@@ -1122,7 +1122,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
|
|
|
1122
1122
|
throw new TypeError(`Association output ${root} has an unsupported ownership manifest.`);
|
|
1123
1123
|
}
|
|
1124
1124
|
}, publishGeneratedDirectory = async (temporary, root) => {
|
|
1125
|
-
const hasCurrent = await
|
|
1125
|
+
const hasCurrent = await exists4(root);
|
|
1126
1126
|
if (hasCurrent)
|
|
1127
1127
|
await assertOwnedOutput(root);
|
|
1128
1128
|
const backup = `${root}.${crypto.randomUUID()}.previous`;
|
|
@@ -1136,12 +1136,12 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
|
|
|
1136
1136
|
throw error;
|
|
1137
1137
|
}
|
|
1138
1138
|
if (hasCurrent)
|
|
1139
|
-
await
|
|
1139
|
+
await rm9(backup, { force: true, recursive: true });
|
|
1140
1140
|
}, materializeHost = async (root, host, files) => {
|
|
1141
|
-
const directory =
|
|
1142
|
-
await
|
|
1141
|
+
const directory = resolve9(root, host, ".well-known");
|
|
1142
|
+
await mkdir9(directory, { recursive: true });
|
|
1143
1143
|
return Promise.all(files.map(async ([name, document2]) => {
|
|
1144
|
-
const path =
|
|
1144
|
+
const path = resolve9(directory, name);
|
|
1145
1145
|
await writeAtomic(path, `${JSON.stringify(document2, null, 2)}
|
|
1146
1146
|
`);
|
|
1147
1147
|
return path;
|
|
@@ -1164,7 +1164,7 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
|
|
|
1164
1164
|
});
|
|
1165
1165
|
return endpoints;
|
|
1166
1166
|
}), materializeAbsoluteMobileAssociationFiles = async (config, outputDirectory) => {
|
|
1167
|
-
const root =
|
|
1167
|
+
const root = resolve9(outputDirectory);
|
|
1168
1168
|
const temporary = `${root}.${crypto.randomUUID()}.tmp`;
|
|
1169
1169
|
const documents = createAbsoluteMobileAssociationDocuments(config, {
|
|
1170
1170
|
requireAll: true
|
|
@@ -1175,16 +1175,16 @@ var JSON_HEADERS, OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_
|
|
|
1175
1175
|
if (documents.apple) {
|
|
1176
1176
|
files.push(["apple-app-site-association", documents.apple]);
|
|
1177
1177
|
}
|
|
1178
|
-
await
|
|
1178
|
+
await mkdir9(temporary, { recursive: true });
|
|
1179
1179
|
try {
|
|
1180
1180
|
const temporaryPaths = (await Promise.all(config.deepLinkHosts.map((host) => materializeHost(temporary, host, files)))).flat();
|
|
1181
|
-
await writeAtomic(
|
|
1181
|
+
await writeAtomic(resolve9(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
|
|
1182
1182
|
`);
|
|
1183
1183
|
await publishGeneratedDirectory(temporary, root);
|
|
1184
|
-
const written = temporaryPaths.map((path) =>
|
|
1184
|
+
const written = temporaryPaths.map((path) => resolve9(root, path.slice(temporary.length + 1)));
|
|
1185
1185
|
return { root, written };
|
|
1186
1186
|
} catch (error) {
|
|
1187
|
-
await
|
|
1187
|
+
await rm9(temporary, { force: true, recursive: true });
|
|
1188
1188
|
throw error;
|
|
1189
1189
|
}
|
|
1190
1190
|
}, verifyAbsoluteMobileAssociationFiles = async (config, request = globalThis.fetch) => {
|
|
@@ -1607,24 +1607,24 @@ __export(exports_materializedBundle, {
|
|
|
1607
1607
|
materializeAbsoluteMobileCompatibilityBundle: () => materializeAbsoluteMobileCompatibilityBundle,
|
|
1608
1608
|
readAbsoluteMobileMaterializedReleases: () => readAbsoluteMobileMaterializedReleases
|
|
1609
1609
|
});
|
|
1610
|
-
import { createHash as
|
|
1610
|
+
import { createHash as createHash12 } from "crypto";
|
|
1611
1611
|
import {
|
|
1612
|
-
access as
|
|
1613
|
-
mkdir as
|
|
1614
|
-
mkdtemp as
|
|
1615
|
-
readFile as
|
|
1612
|
+
access as access11,
|
|
1613
|
+
mkdir as mkdir12,
|
|
1614
|
+
mkdtemp as mkdtemp8,
|
|
1615
|
+
readFile as readFile15,
|
|
1616
1616
|
rename as rename11,
|
|
1617
|
-
rm as
|
|
1617
|
+
rm as rm11,
|
|
1618
1618
|
writeFile as writeFile12
|
|
1619
1619
|
} from "fs/promises";
|
|
1620
|
-
import { dirname as
|
|
1620
|
+
import { dirname as dirname10, join as join13, resolve as resolvePath4 } from "path";
|
|
1621
1621
|
import { pathToFileURL } from "url";
|
|
1622
1622
|
var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE2 = "artifact.json", BUNDLE_ID_PATTERN, isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), errorHasCode3 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, bundleIdFor = (currentReleaseId, releases) => {
|
|
1623
1623
|
const identity = JSON.stringify({
|
|
1624
1624
|
currentReleaseId,
|
|
1625
1625
|
releases: releases.map(({ releaseId }) => releaseId)
|
|
1626
1626
|
});
|
|
1627
|
-
return `amb_${
|
|
1627
|
+
return `amb_${createHash12("sha256").update(identity).digest("hex")}`;
|
|
1628
1628
|
}, parseBundleIndex = (value) => {
|
|
1629
1629
|
if (!isRecord8(value) || value.format !== ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT || typeof value.bundleId !== "string" || !BUNDLE_ID_PATTERN.test(value.bundleId) || typeof value.currentReleaseId !== "string" || !Array.isArray(value.releases)) {
|
|
1630
1630
|
throw new TypeError("Invalid materialized mobile compatibility bundle.");
|
|
@@ -1648,29 +1648,29 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
1648
1648
|
releases
|
|
1649
1649
|
};
|
|
1650
1650
|
}, writeRelease = async (root, release) => {
|
|
1651
|
-
const directory =
|
|
1652
|
-
const producerPath =
|
|
1653
|
-
await
|
|
1651
|
+
const directory = join13(root, release.artifact.releaseId);
|
|
1652
|
+
const producerPath = join13(directory, release.artifact.producer.module);
|
|
1653
|
+
await mkdir12(dirname10(producerPath), { recursive: true });
|
|
1654
1654
|
await Promise.all([
|
|
1655
|
-
writeFile12(
|
|
1655
|
+
writeFile12(join13(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
|
|
1656
1656
|
`),
|
|
1657
1657
|
writeFile12(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
|
|
1658
1658
|
]);
|
|
1659
1659
|
}, installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
|
|
1660
|
-
const destination =
|
|
1660
|
+
const destination = join13(bundlesRoot, bundleId);
|
|
1661
1661
|
try {
|
|
1662
|
-
await
|
|
1662
|
+
await access11(destination);
|
|
1663
1663
|
return destination;
|
|
1664
1664
|
} catch (error) {
|
|
1665
1665
|
if (!errorHasCode3(error, "ENOENT"))
|
|
1666
1666
|
throw error;
|
|
1667
1667
|
}
|
|
1668
|
-
const staging = await
|
|
1668
|
+
const staging = await mkdtemp8(join13(bundlesRoot, ".stage-"));
|
|
1669
1669
|
try {
|
|
1670
1670
|
await Promise.all(releases.map((release) => writeRelease(staging, release)));
|
|
1671
1671
|
await rename11(staging, destination);
|
|
1672
1672
|
} catch (error) {
|
|
1673
|
-
await
|
|
1673
|
+
await rm11(staging, { force: true, recursive: true });
|
|
1674
1674
|
if (errorHasCode3(error, "EEXIST") || errorHasCode3(error, "ENOTEMPTY")) {
|
|
1675
1675
|
return destination;
|
|
1676
1676
|
}
|
|
@@ -1696,15 +1696,15 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
1696
1696
|
};
|
|
1697
1697
|
}, loadAbsoluteMobileMaterializedBundle = async (root) => {
|
|
1698
1698
|
const resolvedRoot = resolvePath4(root);
|
|
1699
|
-
const serialized = await
|
|
1699
|
+
const serialized = await readFile15(join13(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
1700
1700
|
const parsed = JSON.parse(serialized);
|
|
1701
1701
|
const index = parseBundleIndex(parsed);
|
|
1702
|
-
const bundleRoot =
|
|
1702
|
+
const bundleRoot = join13(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
1703
1703
|
return {
|
|
1704
1704
|
artifacts: index.releases,
|
|
1705
1705
|
currentReleaseId: index.currentReleaseId,
|
|
1706
1706
|
loadProducer: async (artifact) => {
|
|
1707
|
-
const modulePath =
|
|
1707
|
+
const modulePath = join13(bundleRoot, artifact.releaseId, artifact.producer.module);
|
|
1708
1708
|
await verifyAbsoluteMobileCompatibilityProducer({
|
|
1709
1709
|
artifact,
|
|
1710
1710
|
producer: Bun.file(modulePath)
|
|
@@ -1730,8 +1730,8 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
1730
1730
|
return release;
|
|
1731
1731
|
});
|
|
1732
1732
|
const root = resolvePath4(input.root);
|
|
1733
|
-
const bundlesRoot =
|
|
1734
|
-
await
|
|
1733
|
+
const bundlesRoot = join13(root, BUNDLES_DIRECTORY);
|
|
1734
|
+
await mkdir12(bundlesRoot, { recursive: true });
|
|
1735
1735
|
const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
|
|
1736
1736
|
await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
|
|
1737
1737
|
const index = {
|
|
@@ -1740,8 +1740,8 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
1740
1740
|
format: ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
|
|
1741
1741
|
releases: artifacts
|
|
1742
1742
|
};
|
|
1743
|
-
const pointerPath =
|
|
1744
|
-
const temporaryPointerPath =
|
|
1743
|
+
const pointerPath = join13(root, CURRENT_BUNDLE_FILE);
|
|
1744
|
+
const temporaryPointerPath = join13(root, `.current-${crypto.randomUUID()}.json`);
|
|
1745
1745
|
await writeFile12(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
|
|
1746
1746
|
`, { flag: "wx" });
|
|
1747
1747
|
await rename11(temporaryPointerPath, pointerPath);
|
|
@@ -1749,12 +1749,12 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
1749
1749
|
}, readAbsoluteMobileMaterializedReleases = async (root) => {
|
|
1750
1750
|
const resolvedRoot = resolvePath4(root);
|
|
1751
1751
|
try {
|
|
1752
|
-
const serialized = await
|
|
1752
|
+
const serialized = await readFile15(join13(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
1753
1753
|
const parsed = JSON.parse(serialized);
|
|
1754
1754
|
const index = parseBundleIndex(parsed);
|
|
1755
|
-
const bundleRoot =
|
|
1755
|
+
const bundleRoot = join13(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
1756
1756
|
return Promise.all(index.releases.map(async (artifact) => {
|
|
1757
|
-
const producer = Bun.file(
|
|
1757
|
+
const producer = Bun.file(join13(bundleRoot, artifact.releaseId, artifact.producer.module));
|
|
1758
1758
|
await verifyAbsoluteMobileCompatibilityProducer({
|
|
1759
1759
|
artifact,
|
|
1760
1760
|
producer
|
|
@@ -1775,7 +1775,7 @@ var init_materializedBundle = __esm(() => {
|
|
|
1775
1775
|
|
|
1776
1776
|
// src/mobile/deviceCapabilities.ts
|
|
1777
1777
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
1778
|
-
import { extname as extname3, join as
|
|
1778
|
+
import { extname as extname3, join as join14, relative as relative11, resolve as resolve12 } from "path";
|
|
1779
1779
|
import { fileURLToPath } from "url";
|
|
1780
1780
|
import ts from "typescript";
|
|
1781
1781
|
var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES, ADAPTERS, SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, providerModulePattern = (provider) => new RegExp(`^@absolutejs/devices-${provider}/[a-z][a-z0-9-]*$`, "u"), providerPackagePattern = (provider) => provider === "capacitor" ? /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u : /^(?:expo-[a-z][a-z0-9-]*|@react-native-[a-z0-9-]+\/[a-z][a-z0-9-]*)@\d+\.\d+\.\d+$/u, providerLabel = (provider) => provider === "capacitor" ? "Capacitor" : "Expo", ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, IOS_PRIVACY_ACCESSED_API_REASONS, IOS_PRIVACY_ACCESSED_APIS, object = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
|
|
@@ -1903,7 +1903,7 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
|
|
|
1903
1903
|
};
|
|
1904
1904
|
}, loadAbsoluteDeviceCapabilityProviders = (projectRoot, provider = "capacitor") => {
|
|
1905
1905
|
const adapter = ADAPTERS[provider];
|
|
1906
|
-
let path =
|
|
1906
|
+
let path = join14(resolve12(projectRoot), "node_modules", adapter, "package.json");
|
|
1907
1907
|
try {
|
|
1908
1908
|
readFileSync3(path, "utf8");
|
|
1909
1909
|
} catch {
|
|
@@ -1958,7 +1958,7 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
|
|
|
1958
1958
|
if (missing.includes(spec))
|
|
1959
1959
|
return false;
|
|
1960
1960
|
try {
|
|
1961
|
-
return readJson(
|
|
1961
|
+
return readJson(join14(resolve12(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
|
|
1962
1962
|
} catch {
|
|
1963
1963
|
return true;
|
|
1964
1964
|
}
|
|
@@ -1967,7 +1967,7 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
|
|
|
1967
1967
|
if (unmet.length > 0)
|
|
1968
1968
|
throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
|
|
1969
1969
|
}, directAbsoluteProjectPackages = (projectRoot) => {
|
|
1970
|
-
const manifest = readJson(
|
|
1970
|
+
const manifest = readJson(join14(resolve12(projectRoot), "package.json"));
|
|
1971
1971
|
const packages = new Set;
|
|
1972
1972
|
for (const field2 of ["dependencies", "devDependencies"]) {
|
|
1973
1973
|
const dependencies = manifest[field2];
|
|
@@ -1977,16 +1977,16 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
|
|
|
1977
1977
|
}
|
|
1978
1978
|
return packages;
|
|
1979
1979
|
}, discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
|
|
1980
|
-
const root =
|
|
1980
|
+
const root = resolve12(projectRoot);
|
|
1981
1981
|
if (!existsSync3(root))
|
|
1982
1982
|
return [];
|
|
1983
1983
|
const known = new Set(Object.keys(providers));
|
|
1984
1984
|
const capabilities = new Set;
|
|
1985
1985
|
for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
|
|
1986
|
-
const portable =
|
|
1986
|
+
const portable = relative11(root, resolve12(root, path)).replaceAll("\\", "/");
|
|
1987
1987
|
if (isIgnored(portable))
|
|
1988
1988
|
continue;
|
|
1989
|
-
const source = readFileSync3(
|
|
1989
|
+
const source = readFileSync3(resolve12(root, portable), "utf8");
|
|
1990
1990
|
for (const name of importedCapabilities(source, portable))
|
|
1991
1991
|
if (known.has(name))
|
|
1992
1992
|
capabilities.add(name);
|
|
@@ -1996,12 +1996,12 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABI
|
|
|
1996
1996
|
const packageName = spec.slice(0, spec.lastIndexOf("@"));
|
|
1997
1997
|
return !directPackages.has(packageName);
|
|
1998
1998
|
}), projectImportsAbsoluteDeviceCapability = (projectRoot, capability) => {
|
|
1999
|
-
const root =
|
|
1999
|
+
const root = resolve12(projectRoot);
|
|
2000
2000
|
for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
|
|
2001
|
-
const portable =
|
|
2001
|
+
const portable = relative11(root, resolve12(root, path)).replaceAll("\\", "/");
|
|
2002
2002
|
if (isIgnored(portable))
|
|
2003
2003
|
continue;
|
|
2004
|
-
const source = readFileSync3(
|
|
2004
|
+
const source = readFileSync3(resolve12(root, portable), "utf8");
|
|
2005
2005
|
if (importedCapabilities(source, portable).has(capability))
|
|
2006
2006
|
return true;
|
|
2007
2007
|
}
|
|
@@ -2068,10 +2068,10 @@ var init_deviceCapabilities = __esm(() => {
|
|
|
2068
2068
|
|
|
2069
2069
|
// src/mobile/nativeAuth.ts
|
|
2070
2070
|
import { readFileSync as readFileSync4 } from "fs";
|
|
2071
|
-
import { join as
|
|
2071
|
+
import { join as join15 } from "path";
|
|
2072
2072
|
var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth", ABSOLUTE_EXPO_AUTH_CORE_VERSION = "0.76.3", ABSOLUTE_EXPO_AUTH_PACKAGE = "@absolutejs/auth-expo", ABSOLUTE_EXPO_AUTH_VERSION = "0.0.6", ABSOLUTE_EXPO_SYNC_CORE_VERSION = "2.31.0", ABSOLUTE_EXPO_SYNC_PACKAGE = "@absolutejs/sync-expo", ABSOLUTE_EXPO_SYNC_VERSION = "0.0.4", ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS", ABSOLUTE_NATIVE_AUTH_SCOPES, ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync", readPackageManifest = (projectRoot) => {
|
|
2073
2073
|
try {
|
|
2074
|
-
return JSON.parse(readFileSync4(
|
|
2074
|
+
return JSON.parse(readFileSync4(join15(projectRoot, "package.json"), "utf8"));
|
|
2075
2075
|
} catch {
|
|
2076
2076
|
return;
|
|
2077
2077
|
}
|
|
@@ -2241,7 +2241,7 @@ var init_client = __esm(() => {
|
|
|
2241
2241
|
|
|
2242
2242
|
// src/mobile/syncSchema.ts
|
|
2243
2243
|
import { readFileSync as readFileSync5 } from "fs";
|
|
2244
|
-
import { dirname as
|
|
2244
|
+
import { dirname as dirname11, join as join16, resolve as resolve13 } from "path";
|
|
2245
2245
|
var object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), manifestAt = (path) => {
|
|
2246
2246
|
try {
|
|
2247
2247
|
const value = JSON.parse(readFileSync5(path, "utf8"));
|
|
@@ -2258,13 +2258,13 @@ var object2 = (value) => typeof value === "object" && value !== null && !Array.i
|
|
|
2258
2258
|
return;
|
|
2259
2259
|
return Reflect.get(sync, "localSchema");
|
|
2260
2260
|
}, packageManifestPath = (projectRoot, packageName) => {
|
|
2261
|
-
let directory =
|
|
2261
|
+
let directory = resolve13(projectRoot);
|
|
2262
2262
|
while (true) {
|
|
2263
|
-
const candidate =
|
|
2263
|
+
const candidate = join16(directory, "node_modules", packageName, "package.json");
|
|
2264
2264
|
const manifest = manifestAt(candidate);
|
|
2265
2265
|
if (manifest && Reflect.get(manifest, "name") === packageName)
|
|
2266
2266
|
return candidate;
|
|
2267
|
-
const parent =
|
|
2267
|
+
const parent = dirname11(directory);
|
|
2268
2268
|
if (parent === directory)
|
|
2269
2269
|
return;
|
|
2270
2270
|
directory = parent;
|
|
@@ -2491,7 +2491,7 @@ var object2 = (value) => typeof value === "object" && value !== null && !Array.i
|
|
|
2491
2491
|
Reflect.get(manifest, "devDependencies"),
|
|
2492
2492
|
Reflect.get(manifest, "peerDependencies")
|
|
2493
2493
|
].flatMap((dependencies) => object2(dependencies) ? Object.keys(dependencies) : []).filter((name, index, names) => names.indexOf(name) === index).sort(), discoverAbsoluteSyncSchema = (projectRoot) => {
|
|
2494
|
-
const appManifestPath =
|
|
2494
|
+
const appManifestPath = join16(resolve13(projectRoot), "package.json");
|
|
2495
2495
|
const appManifest = manifestAt(appManifestPath);
|
|
2496
2496
|
if (!appManifest)
|
|
2497
2497
|
return {
|
|
@@ -6838,9 +6838,9 @@ var require_sha256 = __commonJS(function(exports, module) {
|
|
|
6838
6838
|
var forge = require_forge();
|
|
6839
6839
|
require_md();
|
|
6840
6840
|
require_util();
|
|
6841
|
-
var
|
|
6842
|
-
forge.md.sha256 = forge.md.algorithms.sha256 =
|
|
6843
|
-
|
|
6841
|
+
var sha2564 = module.exports = forge.sha256 = forge.sha256 || {};
|
|
6842
|
+
forge.md.sha256 = forge.md.algorithms.sha256 = sha2564;
|
|
6843
|
+
sha2564.create = function() {
|
|
6844
6844
|
if (!_initialized) {
|
|
6845
6845
|
_init();
|
|
6846
6846
|
}
|
|
@@ -19351,7 +19351,7 @@ var init_compatibilityDispatcher = __esm(() => {
|
|
|
19351
19351
|
// src/cli/scripts/telemetry.ts
|
|
19352
19352
|
import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
|
|
19353
19353
|
import { homedir as homedir4 } from "os";
|
|
19354
|
-
import { join as
|
|
19354
|
+
import { join as join23 } from "path";
|
|
19355
19355
|
var configDir, configPath, getTelemetryConfig = () => {
|
|
19356
19356
|
try {
|
|
19357
19357
|
if (!existsSync5(configPath))
|
|
@@ -19364,14 +19364,14 @@ var configDir, configPath, getTelemetryConfig = () => {
|
|
|
19364
19364
|
}
|
|
19365
19365
|
};
|
|
19366
19366
|
var init_telemetry = __esm(() => {
|
|
19367
|
-
configDir =
|
|
19368
|
-
configPath =
|
|
19367
|
+
configDir = join23(homedir4(), ".absolutejs");
|
|
19368
|
+
configPath = join23(configDir, "telemetry.json");
|
|
19369
19369
|
});
|
|
19370
19370
|
|
|
19371
19371
|
// src/cli/telemetryEvent.ts
|
|
19372
19372
|
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
19373
19373
|
import { arch, platform as platform3 } from "os";
|
|
19374
|
-
import { dirname as
|
|
19374
|
+
import { dirname as dirname16, join as join24, parse } from "path";
|
|
19375
19375
|
var checkCandidate = (candidate) => {
|
|
19376
19376
|
if (!existsSync6(candidate)) {
|
|
19377
19377
|
return null;
|
|
@@ -19391,12 +19391,12 @@ var checkCandidate = (candidate) => {
|
|
|
19391
19391
|
}, findPackageVersion = () => {
|
|
19392
19392
|
let { dir } = import.meta;
|
|
19393
19393
|
while (dir !== parse(dir).root) {
|
|
19394
|
-
const candidate =
|
|
19394
|
+
const candidate = join24(dir, "package.json");
|
|
19395
19395
|
const version = checkCandidate(candidate);
|
|
19396
19396
|
if (version) {
|
|
19397
19397
|
return version;
|
|
19398
19398
|
}
|
|
19399
|
-
dir =
|
|
19399
|
+
dir = dirname16(dir);
|
|
19400
19400
|
}
|
|
19401
19401
|
return "unknown";
|
|
19402
19402
|
}, sendTelemetryEvent = (event, payload) => {
|
|
@@ -20032,7 +20032,7 @@ __export(exports_mobileUpdate, {
|
|
|
20032
20032
|
parseMobileUpdateManifest: () => parseMobileUpdateManifest
|
|
20033
20033
|
});
|
|
20034
20034
|
import {
|
|
20035
|
-
createHash as
|
|
20035
|
+
createHash as createHash18,
|
|
20036
20036
|
createHmac,
|
|
20037
20037
|
createPrivateKey,
|
|
20038
20038
|
createPublicKey as createPublicKey2,
|
|
@@ -20042,7 +20042,7 @@ import {
|
|
|
20042
20042
|
verify as verify2,
|
|
20043
20043
|
X509Certificate as X509Certificate3
|
|
20044
20044
|
} from "crypto";
|
|
20045
|
-
import { readFile as
|
|
20045
|
+
import { readFile as readFile27, stat as stat7 } from "fs/promises";
|
|
20046
20046
|
import path from "path";
|
|
20047
20047
|
var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updates", MAX_FILE_BYTES, MAX_TOTAL_BYTES, DAY_MS, DEFAULT_MIN_AGE_MS, DEFAULT_GRACE_PERIOD_MS, DEFAULT_RETAIN_RECENT = 5, HASH, RELEASE, APP_ID, NAME, EXPO_DESCRIPTOR = "_absolute/expo-update.json", EXPO_CODE_SIGNING_ALGORITHM = "rsa-v1_5-sha256", HEALTH_TOKEN_VERSION = 1, HEALTH_KINDS, FAILURE_HEALTH_KINDS, MobileUpdateRegistryError, object6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), text2 = (value, field2) => {
|
|
20048
20048
|
if (typeof value !== "string" || value.length === 0)
|
|
@@ -20192,7 +20192,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20192
20192
|
if (!prefix || prefix.split("/").some((segment) => segment === "." || segment === ".."))
|
|
20193
20193
|
throw new MobileUpdateRegistryError("Mobile update prefix is invalid");
|
|
20194
20194
|
return prefix;
|
|
20195
|
-
}, appHash = (appId) =>
|
|
20195
|
+
}, appHash = (appId) => createHash18("sha256").update(appId).digest("hex"), digest = (bytes) => createHash18("sha256").update(bytes).digest("hex"), json = (value) => new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
|
|
20196
20196
|
`), decode2 = (value) => JSON.parse(new TextDecoder().decode(value)), fileDigest = async (file) => {
|
|
20197
20197
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
20198
20198
|
for await (const chunk of file.stream())
|
|
@@ -20203,7 +20203,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20203
20203
|
return false;
|
|
20204
20204
|
if (input.rollout === 1)
|
|
20205
20205
|
return true;
|
|
20206
|
-
const value =
|
|
20206
|
+
const value = createHash18("sha256").update(`${input.appId}\x00${input.channel}\x00${input.releaseId}\x00${input.installationId}`).digest().readUInt32BE(0);
|
|
20207
20207
|
return value / 4294967296 < input.rollout;
|
|
20208
20208
|
}, base64Url = (value) => Buffer.from(value).toString("base64url"), healthPromotionId = (channel) => channel.promotionId ?? digest(new TextEncoder().encode(`${channel.appId}\x00${channel.channel}\x00${channel.releaseId ?? "embedded"}\x00${channel.promotedAt}`)), finiteMetric = (value, field2) => {
|
|
20209
20209
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
|
|
@@ -20243,7 +20243,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20243
20243
|
const releaseRoot = (manifest) => `${root(manifest.appId)}/releases/${manifest.releaseId}`;
|
|
20244
20244
|
const manifestKey = (manifest) => `${releaseRoot(manifest)}/update.json`;
|
|
20245
20245
|
const fileKey = (manifest, file) => `${releaseRoot(manifest)}/files/${file.path}`;
|
|
20246
|
-
const contentBlobKey = (appId,
|
|
20246
|
+
const contentBlobKey = (appId, sha2565) => `${root(appId)}/blobs/${sha2565}`;
|
|
20247
20247
|
const tombstoneKey = (appId, releaseId) => `${root(appId)}/gc/${releaseId}.json`;
|
|
20248
20248
|
const healthRoot = (appId, promotionId, releaseId) => `${root(appId)}/health/${promotionId}/${releaseId}`;
|
|
20249
20249
|
const pauseKey = (appId, promotionId, releaseId) => `${healthRoot(appId, promotionId, releaseId)}/paused.json`;
|
|
@@ -20864,10 +20864,10 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20864
20864
|
const objectBytesByDigest = new Map;
|
|
20865
20865
|
for (const blobObject of objects) {
|
|
20866
20866
|
if (blobObject.key.startsWith(blobPrefix)) {
|
|
20867
|
-
const
|
|
20868
|
-
if (HASH.test(
|
|
20869
|
-
objectKeysByDigest.set(
|
|
20870
|
-
objectBytesByDigest.set(
|
|
20867
|
+
const sha2565 = blobObject.key.slice(blobPrefix.length);
|
|
20868
|
+
if (HASH.test(sha2565)) {
|
|
20869
|
+
objectKeysByDigest.set(sha2565, blobObject.key);
|
|
20870
|
+
objectBytesByDigest.set(sha2565, blobObject.size);
|
|
20871
20871
|
}
|
|
20872
20872
|
}
|
|
20873
20873
|
if (!blobObject.key.startsWith(releasePrefix))
|
|
@@ -20950,7 +20950,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20950
20950
|
}).toSorted((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
20951
20951
|
const protectedReleaseIds = new Set(releases.filter((release) => release.protectedBy.length > 0).map((release) => release.releaseId));
|
|
20952
20952
|
const protectedDigests = new Set(manifests.filter((manifest) => protectedReleaseIds.has(manifest.releaseId)).flatMap((manifest) => manifest.files.map((file) => file.sha256)));
|
|
20953
|
-
const reclaimableContentBytes = [...objectBytesByDigest].filter(([
|
|
20953
|
+
const reclaimableContentBytes = [...objectBytesByDigest].filter(([sha2565]) => !protectedDigests.has(sha2565)).reduce((total, [, bytes]) => total + bytes, 0);
|
|
20954
20954
|
const contentBlobBytes = [...objectBytesByDigest.values()].reduce((total, bytes) => total + bytes, 0);
|
|
20955
20955
|
const releaseBytes = releases.reduce((total, release) => total + release.bytes, 0);
|
|
20956
20956
|
const totalBytes = objects.reduce((total, object22) => total + object22.size, 0);
|
|
@@ -21047,13 +21047,13 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21047
21047
|
for (const file of manifest?.manifest.files ?? [])
|
|
21048
21048
|
referencedDigests.add(file.sha256);
|
|
21049
21049
|
}
|
|
21050
|
-
for (const [
|
|
21051
|
-
if (referencedDigests.has(
|
|
21050
|
+
for (const [sha2565, key] of afterReleaseSweep.objectKeysByDigest) {
|
|
21051
|
+
if (referencedDigests.has(sha2565))
|
|
21052
21052
|
continue;
|
|
21053
21053
|
const head = await options.store.head(key);
|
|
21054
21054
|
await remove(key);
|
|
21055
21055
|
result.reclaimedBytes += head?.size ?? 0;
|
|
21056
|
-
result.sweptContentBlobs.push(
|
|
21056
|
+
result.sweptContentBlobs.push(sha2565);
|
|
21057
21057
|
}
|
|
21058
21058
|
return result;
|
|
21059
21059
|
};
|
|
@@ -21075,7 +21075,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21075
21075
|
verifyManifestSignature(manifest, options.publicKeys);
|
|
21076
21076
|
await assertNotMarked(manifest.appId, manifest.releaseId);
|
|
21077
21077
|
const localRoot = path.resolve(input.releaseDirectory);
|
|
21078
|
-
const localManifest = parseMobileUpdateManifest(JSON.parse(await
|
|
21078
|
+
const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile27(path.join(localRoot, "update.json"), "utf8")));
|
|
21079
21079
|
if (JSON.stringify(localManifest) !== JSON.stringify(manifest))
|
|
21080
21080
|
throw new MobileUpdateRegistryError("Local mobile update manifest changed");
|
|
21081
21081
|
const existing = await readManifest(manifest.appId, manifest.releaseId);
|
|
@@ -21093,7 +21093,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21093
21093
|
if (!existing) {
|
|
21094
21094
|
for (const file of manifest.files) {
|
|
21095
21095
|
const local = path.join(localRoot, "files", file.path);
|
|
21096
|
-
const metadata = await
|
|
21096
|
+
const metadata = await stat7(local).catch(() => null);
|
|
21097
21097
|
if (!metadata?.isFile() || metadata.size !== file.bytes)
|
|
21098
21098
|
throw new MobileUpdateRegistryError(`Mobile update file ${file.path} size changed`);
|
|
21099
21099
|
if (await fileDigest(Bun.file(local)) !== file.sha256)
|
|
@@ -21208,7 +21208,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21208
21208
|
}
|
|
21209
21209
|
};
|
|
21210
21210
|
}, expoUpdateId = (releaseId) => {
|
|
21211
|
-
const hash = RELEASE.test(releaseId) ? releaseId.slice("amu_".length, "amu_".length + 32) :
|
|
21211
|
+
const hash = RELEASE.test(releaseId) ? releaseId.slice("amu_".length, "amu_".length + 32) : createHash18("sha256").update(releaseId).digest("hex").slice(0, 32);
|
|
21212
21212
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20)}`;
|
|
21213
21213
|
}, expoContentType = (extension2, launch2) => {
|
|
21214
21214
|
if (launch2)
|
|
@@ -21361,8 +21361,8 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21361
21361
|
});
|
|
21362
21362
|
}
|
|
21363
21363
|
const pathname = new URL(request.url).pathname.replace(/^\/+/, "");
|
|
21364
|
-
const
|
|
21365
|
-
if (request.method === "POST" &&
|
|
21364
|
+
const relative20 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
|
|
21365
|
+
if (request.method === "POST" && relative20 === "health") {
|
|
21366
21366
|
if (!options.registry.recordUpdateHealth)
|
|
21367
21367
|
return new Response(null, { status: 404 });
|
|
21368
21368
|
const appId = request.headers.get("x-absolute-mobile-app");
|
|
@@ -21405,7 +21405,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21405
21405
|
}
|
|
21406
21406
|
if (request.method !== "GET")
|
|
21407
21407
|
return new Response(null, { status: 405 });
|
|
21408
|
-
if (
|
|
21408
|
+
if (relative20 === "update.json") {
|
|
21409
21409
|
const expoProtocolVersion = request.headers.get("expo-protocol-version");
|
|
21410
21410
|
const expoProtocol = expoProtocolVersion !== null;
|
|
21411
21411
|
if (expoProtocol && expoProtocolVersion !== "1")
|
|
@@ -21523,7 +21523,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21523
21523
|
}
|
|
21524
21524
|
});
|
|
21525
21525
|
}
|
|
21526
|
-
const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(
|
|
21526
|
+
const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative20);
|
|
21527
21527
|
if (!match?.[1] || !match[2])
|
|
21528
21528
|
return new Response(null, { status: 404 });
|
|
21529
21529
|
const file = await options.registry.readUpdateFile({
|
|
@@ -21616,15 +21616,15 @@ import {
|
|
|
21616
21616
|
createPublicKey as createPublicKey3,
|
|
21617
21617
|
X509Certificate as X509Certificate4
|
|
21618
21618
|
} from "crypto";
|
|
21619
|
-
import { access as
|
|
21620
|
-
import { dirname as
|
|
21619
|
+
import { access as access19, mkdir as mkdir21 } from "fs/promises";
|
|
21620
|
+
import { dirname as dirname22, isAbsolute as isAbsolute11, relative as relative20, resolve as resolve22, sep as sep13 } from "path";
|
|
21621
21621
|
import { pathToFileURL as pathToFileURL5 } from "url";
|
|
21622
21622
|
import { Elysia as Elysia4 } from "elysia";
|
|
21623
21623
|
var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE = "mobile.update.ts", object7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), projectPath3 = (projectRoot, requested) => {
|
|
21624
|
-
const root =
|
|
21625
|
-
const path2 =
|
|
21626
|
-
const projectRelative =
|
|
21627
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
21624
|
+
const root = resolve22(projectRoot);
|
|
21625
|
+
const path2 = resolve22(root, requested);
|
|
21626
|
+
const projectRelative = relative20(root, path2);
|
|
21627
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep13}`) || isAbsolute11(projectRelative))
|
|
21628
21628
|
throw new TypeError("mobile.updates.server.registry must remain inside the project.");
|
|
21629
21629
|
return path2;
|
|
21630
21630
|
}, isRegistry4 = (value) => object7(value) && [
|
|
@@ -21647,7 +21647,7 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
|
|
|
21647
21647
|
return metadata;
|
|
21648
21648
|
}, loadAbsoluteMobileUpdateServerModule = async (projectRoot, requestedModulePath = DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE) => {
|
|
21649
21649
|
const modulePath = projectPath3(projectRoot, requestedModulePath);
|
|
21650
|
-
await
|
|
21650
|
+
await access19(modulePath).catch(() => {
|
|
21651
21651
|
throw new TypeError(`Mobile update server registry does not exist: ${modulePath}. Run \`absolute mobile update provision\`.`);
|
|
21652
21652
|
});
|
|
21653
21653
|
const loaded = await import(pathToFileURL5(modulePath).href);
|
|
@@ -21836,13 +21836,13 @@ ${generated}`);
|
|
|
21836
21836
|
}, writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
21837
21837
|
const path2 = projectPath3(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
|
|
21838
21838
|
if (!options.force) {
|
|
21839
|
-
await
|
|
21839
|
+
await access19(path2).then(() => {
|
|
21840
21840
|
throw new TypeError(`Mobile update registry already exists: ${path2}. Pass --force to replace it.`);
|
|
21841
21841
|
}, () => {
|
|
21842
21842
|
return;
|
|
21843
21843
|
});
|
|
21844
21844
|
}
|
|
21845
|
-
await
|
|
21845
|
+
await mkdir21(dirname22(path2), { recursive: true });
|
|
21846
21846
|
await Bun.write(path2, renderAbsoluteMobileUpdateRegistry({
|
|
21847
21847
|
...options.health ? { health: options.health } : {},
|
|
21848
21848
|
...options.rollout ? { rollout: options.rollout } : {},
|
|
@@ -25010,7 +25010,10 @@ var runAbsoluteAndroidUpgradeConformance = async (options) => {
|
|
|
25010
25010
|
var ABSOLUTE_BUNDLETOOL_VERSION = "1.18.3";
|
|
25011
25011
|
var ABSOLUTE_BUNDLETOOL_SHA256 = "a099cfa1543f55593bc2ed16a70a7c67fe54b1747bb7301f37fdfd6d91028e29";
|
|
25012
25012
|
var ABSOLUTE_BUNDLETOOL_URL = `https://github.com/google/bundletool/releases/download/${ABSOLUTE_BUNDLETOOL_VERSION}/bundletool-all-${ABSOLUTE_BUNDLETOOL_VERSION}.jar`;
|
|
25013
|
-
var
|
|
25013
|
+
var EMBEDDED_READY_MARKERS = {
|
|
25014
|
+
capacitor: "Capacitor embedded web content ready",
|
|
25015
|
+
expo: "Expo embedded web content ready"
|
|
25016
|
+
};
|
|
25014
25017
|
var RELEASE_READY_POLL_MS = 250;
|
|
25015
25018
|
var RELEASE_READY_TIMEOUT_MS = 30000;
|
|
25016
25019
|
var RELEASE_STABILITY_MS = 2000;
|
|
@@ -25151,7 +25154,7 @@ var adb = (path, serial, ...args) => [
|
|
|
25151
25154
|
serial,
|
|
25152
25155
|
...args
|
|
25153
25156
|
];
|
|
25154
|
-
var waitForMarker = async (run, adbPath, serial, appId, timeoutMs) => {
|
|
25157
|
+
var waitForMarker = async (run, adbPath, serial, appId, engine, timeoutMs) => {
|
|
25155
25158
|
const startedAt = performance.now();
|
|
25156
25159
|
const inspect = async () => {
|
|
25157
25160
|
if (performance.now() - startedAt >= timeoutMs)
|
|
@@ -25162,9 +25165,9 @@ var waitForMarker = async (run, adbPath, serial, appId, timeoutMs) => {
|
|
|
25162
25165
|
]);
|
|
25163
25166
|
if (process2.exitCode !== 0 || !process2.stdout.trim())
|
|
25164
25167
|
throw new Error("The installed Android release exited before becoming ready.");
|
|
25165
|
-
if (logs.stdout.includes(
|
|
25168
|
+
if (logs.stdout.includes(EMBEDDED_READY_MARKERS[engine]))
|
|
25166
25169
|
return;
|
|
25167
|
-
const failedPhase = /Expo embedded web phase: (assets-(?:root|directory|destination|module|source|download|copy|read|write|finalize|unexpected)|devices)-failed/u.exec(logs.stdout)?.[1];
|
|
25170
|
+
const failedPhase = engine === "expo" ? /Expo embedded web phase: (assets-(?:root|directory|destination|module|source|download|copy|read|write|finalize|unexpected)|devices)-failed/u.exec(logs.stdout)?.[1] : undefined;
|
|
25168
25171
|
if (failedPhase)
|
|
25169
25172
|
throw new Error(`The installed release could not initialize its embedded ${failedPhase} runtime offline.`);
|
|
25170
25173
|
await Bun.sleep(RELEASE_READY_POLL_MS);
|
|
@@ -25182,8 +25185,6 @@ var launch = async (run, adbPath, serial, appId, launchUrl) => {
|
|
|
25182
25185
|
return Math.round(performance.now() - startedAt);
|
|
25183
25186
|
};
|
|
25184
25187
|
var runAbsoluteAndroidReleaseAcceptance = async (options) => {
|
|
25185
|
-
if (options.release.metadata.engine !== "expo")
|
|
25186
|
-
throw new TypeError("Installed AAB release acceptance currently requires the Expo engine.");
|
|
25187
25188
|
if (!options.serial.startsWith("emulator-"))
|
|
25188
25189
|
throw new TypeError("Installed release acceptance changes network state and therefore requires an Android emulator.");
|
|
25189
25190
|
const run = options.run ?? defaultRun;
|
|
@@ -25244,12 +25245,12 @@ var runAbsoluteAndroidReleaseAcceptance = async (options) => {
|
|
|
25244
25245
|
]);
|
|
25245
25246
|
await requireSuccess2(run, adb(options.adb, options.serial, "shell", "am", "force-stop", options.release.metadata.appId), "Android release stop");
|
|
25246
25247
|
launchMs = await launch(run, options.adb, options.serial, options.release.metadata.appId, options.launchUrl);
|
|
25247
|
-
await waitForMarker(run, options.adb, options.serial, options.release.metadata.appId, RELEASE_READY_TIMEOUT_MS);
|
|
25248
|
+
await waitForMarker(run, options.adb, options.serial, options.release.metadata.appId, options.release.metadata.engine, RELEASE_READY_TIMEOUT_MS);
|
|
25248
25249
|
await Bun.sleep(options.stabilityMs ?? RELEASE_STABILITY_MS);
|
|
25249
25250
|
await requireSuccess2(run, adb(options.adb, options.serial, "shell", "am", "force-stop", options.release.metadata.appId), "Android release relaunch stop");
|
|
25250
25251
|
await requireSuccess2(run, adb(options.adb, options.serial, "logcat", "-c"), "Android release relaunch log isolation");
|
|
25251
25252
|
relaunchMs = await launch(run, options.adb, options.serial, options.release.metadata.appId, options.launchUrl);
|
|
25252
|
-
await waitForMarker(run, options.adb, options.serial, options.release.metadata.appId, RELEASE_READY_TIMEOUT_MS);
|
|
25253
|
+
await waitForMarker(run, options.adb, options.serial, options.release.metadata.appId, options.release.metadata.engine, RELEASE_READY_TIMEOUT_MS);
|
|
25253
25254
|
} finally {
|
|
25254
25255
|
await Promise.all([
|
|
25255
25256
|
requireSuccess2(run, adb(options.adb, options.serial, "shell", "svc", "wifi", wifi.stdout.trim() === "1" ? "enable" : "disable"), "Android Wi-Fi restore"),
|
|
@@ -25392,6 +25393,25 @@ var safeOutputDirectory2 = (projectRoot, requested) => {
|
|
|
25392
25393
|
return output;
|
|
25393
25394
|
};
|
|
25394
25395
|
var sha256File2 = async (path) => createHash6("sha256").update(await readFile7(path)).digest("hex");
|
|
25396
|
+
var verifyRegisteredReleaseArtifact = async (releaseRoot, metadata) => {
|
|
25397
|
+
if (!metadata.registeredDevice)
|
|
25398
|
+
return;
|
|
25399
|
+
const destination = join7(releaseRoot, metadata.registeredDevice.artifact);
|
|
25400
|
+
const [bytes, sha2562] = await Promise.all([
|
|
25401
|
+
stat3(destination).then(({ size }) => size),
|
|
25402
|
+
sha256File2(destination)
|
|
25403
|
+
]);
|
|
25404
|
+
if (bytes !== metadata.registeredDevice.bytes || sha2562 !== metadata.registeredDevice.sha256)
|
|
25405
|
+
throw new TypeError(`Immutable iOS release ${metadata.releaseId} registered-device artifact is missing or modified.`);
|
|
25406
|
+
return destination;
|
|
25407
|
+
};
|
|
25408
|
+
var copyRegisteredReleaseArtifact = async (staging, metadata, registeredArtifactPath) => {
|
|
25409
|
+
if (!metadata.registeredDevice)
|
|
25410
|
+
return;
|
|
25411
|
+
if (!registeredArtifactPath)
|
|
25412
|
+
throw new TypeError("iOS release metadata requires a registered-device artifact.");
|
|
25413
|
+
await copyFile3(registeredArtifactPath, join7(staging, metadata.registeredDevice.artifact));
|
|
25414
|
+
};
|
|
25395
25415
|
var findByExtension = async (root, extension) => {
|
|
25396
25416
|
if (!await pathExists4(root))
|
|
25397
25417
|
return;
|
|
@@ -25447,12 +25467,12 @@ var resolveAbsoluteIosXcodeProject = async (nativeDirectory, options = {}) => {
|
|
|
25447
25467
|
throw new TypeError(schemes.length > 1 ? `iOS release found multiple shared Xcode schemes: ${schemes.join(", ")}. Pass an explicit scheme.` : "iOS release could not find a shared Xcode scheme.");
|
|
25448
25468
|
return { scheme: schemes[0], workspacePath };
|
|
25449
25469
|
};
|
|
25450
|
-
var exportOptions = () => `<?xml version="1.0" encoding="UTF-8"?>
|
|
25470
|
+
var exportOptions = (method) => `<?xml version="1.0" encoding="UTF-8"?>
|
|
25451
25471
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
25452
25472
|
<plist version="1.0"><dict>
|
|
25453
25473
|
<key>destination</key><string>export</string>
|
|
25454
25474
|
<key>manageAppVersionAndBuildNumber</key><false/>
|
|
25455
|
-
<key>method</key><string
|
|
25475
|
+
<key>method</key><string>${method}</string>
|
|
25456
25476
|
<key>signingStyle</key><string>automatic</string>
|
|
25457
25477
|
<key>stripSwiftSymbols</key><true/>
|
|
25458
25478
|
<key>uploadSymbols</key><true/>
|
|
@@ -25463,7 +25483,19 @@ var requireBuildNumber = (value) => {
|
|
|
25463
25483
|
throw new TypeError("iOS build number must be a positive integer.");
|
|
25464
25484
|
return value;
|
|
25465
25485
|
};
|
|
25486
|
+
var normalizeRegisteredDevice = (value) => {
|
|
25487
|
+
if (value === undefined)
|
|
25488
|
+
return;
|
|
25489
|
+
if (!isRecord3(value) || value.artifact !== "App.registered.ipa" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || typeof value.sha256 !== "string" || !/^[a-f0-9]{64}$/u.test(value.sha256))
|
|
25490
|
+
throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
|
|
25491
|
+
return {
|
|
25492
|
+
artifact: "App.registered.ipa",
|
|
25493
|
+
bytes: value.bytes,
|
|
25494
|
+
sha256: value.sha256
|
|
25495
|
+
};
|
|
25496
|
+
};
|
|
25466
25497
|
var requireAbsoluteIosReleaseMetadata = (value) => {
|
|
25498
|
+
const registeredDevice = normalizeRegisteredDevice(isRecord3(value) ? value.registeredDevice : undefined);
|
|
25467
25499
|
if (!isRecord3(value) || value.artifact !== "App.ipa" || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || value.engine !== "capacitor" && value.engine !== "expo" || value.format !== ABSOLUTE_IOS_RELEASE_FORMAT || typeof value.marketingVersion !== "string" || value.platform !== "ios" || typeof value.releaseId !== "string" || typeof value.runtime !== "string" || typeof value.sha256 !== "string" || typeof value.signed !== "boolean" || value.type !== "ipa" || value.buildNumber !== undefined && (typeof value.buildNumber !== "number" || !Number.isSafeInteger(value.buildNumber) || value.buildNumber < 1) || !/^amobile_ios_[a-f0-9]{64}$/u.test(value.releaseId) || !/^[a-f0-9]{64}$/u.test(value.sha256) || value.releaseId !== `amobile_ios_${value.sha256}`) {
|
|
25468
25500
|
throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
|
|
25469
25501
|
}
|
|
@@ -25477,6 +25509,7 @@ var requireAbsoluteIosReleaseMetadata = (value) => {
|
|
|
25477
25509
|
format: value.format,
|
|
25478
25510
|
marketingVersion: value.marketingVersion,
|
|
25479
25511
|
platform: value.platform,
|
|
25512
|
+
...registeredDevice ? { registeredDevice } : {},
|
|
25480
25513
|
releaseId: value.releaseId,
|
|
25481
25514
|
runtime: value.runtime,
|
|
25482
25515
|
sha256: value.sha256,
|
|
@@ -25484,12 +25517,13 @@ var requireAbsoluteIosReleaseMetadata = (value) => {
|
|
|
25484
25517
|
type: value.type
|
|
25485
25518
|
};
|
|
25486
25519
|
};
|
|
25487
|
-
var installRelease2 = async (artifactPath, metadata, outputRoot) => {
|
|
25520
|
+
var installRelease2 = async (artifactPath, metadata, outputRoot, registeredArtifactPath) => {
|
|
25488
25521
|
const releaseRoot = join7(outputRoot, metadata.releaseId);
|
|
25489
25522
|
const destination = join7(releaseRoot, "App.ipa");
|
|
25490
25523
|
if (await pathExists4(releaseRoot)) {
|
|
25491
25524
|
const value = JSON.parse(await readFile7(join7(releaseRoot, "release.json"), "utf8"));
|
|
25492
|
-
|
|
25525
|
+
const existing = requireAbsoluteIosReleaseMetadata(value);
|
|
25526
|
+
if (JSON.stringify(existing) !== JSON.stringify({ ...metadata, artifact: "App.ipa" })) {
|
|
25493
25527
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} does not match its content.`);
|
|
25494
25528
|
}
|
|
25495
25529
|
const [bytes, sha2562] = await Promise.all([
|
|
@@ -25498,12 +25532,14 @@ var installRelease2 = async (artifactPath, metadata, outputRoot) => {
|
|
|
25498
25532
|
]);
|
|
25499
25533
|
if (bytes !== metadata.bytes || sha2562 !== metadata.sha256)
|
|
25500
25534
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} artifact is missing or modified.`);
|
|
25535
|
+
const registeredDestination = await verifyRegisteredReleaseArtifact(releaseRoot, metadata);
|
|
25501
25536
|
return {
|
|
25502
25537
|
artifactPath: destination,
|
|
25503
25538
|
metadata: {
|
|
25504
25539
|
...metadata,
|
|
25505
25540
|
artifact: "App.ipa"
|
|
25506
25541
|
},
|
|
25542
|
+
...registeredDestination ? { registeredArtifactPath: registeredDestination } : {},
|
|
25507
25543
|
releaseRoot
|
|
25508
25544
|
};
|
|
25509
25545
|
}
|
|
@@ -25511,6 +25547,7 @@ var installRelease2 = async (artifactPath, metadata, outputRoot) => {
|
|
|
25511
25547
|
const staging = await mkdtemp4(join7(dirname4(releaseRoot), ".ios-stage-"));
|
|
25512
25548
|
try {
|
|
25513
25549
|
await copyFile3(artifactPath, join7(staging, "App.ipa"));
|
|
25550
|
+
await copyRegisteredReleaseArtifact(staging, metadata, registeredArtifactPath);
|
|
25514
25551
|
const complete = {
|
|
25515
25552
|
...metadata,
|
|
25516
25553
|
artifact: "App.ipa"
|
|
@@ -25518,13 +25555,50 @@ var installRelease2 = async (artifactPath, metadata, outputRoot) => {
|
|
|
25518
25555
|
await writeFile6(join7(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
|
|
25519
25556
|
`, { flag: "wx" });
|
|
25520
25557
|
await rename6(staging, releaseRoot);
|
|
25521
|
-
return {
|
|
25558
|
+
return {
|
|
25559
|
+
artifactPath: destination,
|
|
25560
|
+
metadata: complete,
|
|
25561
|
+
...metadata.registeredDevice ? {
|
|
25562
|
+
registeredArtifactPath: join7(releaseRoot, metadata.registeredDevice.artifact)
|
|
25563
|
+
} : {},
|
|
25564
|
+
releaseRoot
|
|
25565
|
+
};
|
|
25522
25566
|
} finally {
|
|
25523
25567
|
await rm5(staging, { force: true, recursive: true }).catch(() => {
|
|
25524
25568
|
return;
|
|
25525
25569
|
});
|
|
25526
25570
|
}
|
|
25527
25571
|
};
|
|
25572
|
+
var exportRegisteredDeviceArtifact = async (options) => {
|
|
25573
|
+
const exportPath = join7(options.staging, "registered-export");
|
|
25574
|
+
const exportPlist = join7(options.staging, "RegisteredExportOptions.plist");
|
|
25575
|
+
await mkdir5(exportPath, { recursive: true });
|
|
25576
|
+
await writeFile6(exportPlist, exportOptions("debugging"));
|
|
25577
|
+
const exitCode = await options.run([
|
|
25578
|
+
"xcodebuild",
|
|
25579
|
+
"-exportArchive",
|
|
25580
|
+
"-archivePath",
|
|
25581
|
+
options.archivePath,
|
|
25582
|
+
"-exportPath",
|
|
25583
|
+
exportPath,
|
|
25584
|
+
"-exportOptionsPlist",
|
|
25585
|
+
exportPlist
|
|
25586
|
+
], { cwd: options.nativeDirectory, env: options.env });
|
|
25587
|
+
if (exitCode !== 0)
|
|
25588
|
+
throw new TypeError("Xcode failed to export the registered-device IPA. Confirm the selected development team includes the test device.");
|
|
25589
|
+
const artifactPath = await findByExtension(exportPath, ".ipa");
|
|
25590
|
+
if (!artifactPath)
|
|
25591
|
+
throw new TypeError("Xcode did not produce a registered-device IPA.");
|
|
25592
|
+
const [bytes, sha2562] = await Promise.all([
|
|
25593
|
+
stat3(artifactPath).then(({ size }) => size),
|
|
25594
|
+
sha256File2(artifactPath)
|
|
25595
|
+
]);
|
|
25596
|
+
const metadata = { artifact: "App.registered.ipa", bytes, sha256: sha2562 };
|
|
25597
|
+
return {
|
|
25598
|
+
artifactPath,
|
|
25599
|
+
metadata
|
|
25600
|
+
};
|
|
25601
|
+
};
|
|
25528
25602
|
var buildAbsoluteIosRelease = async (options) => {
|
|
25529
25603
|
if (options.buildNumber !== undefined && options.prepareBuildNumber)
|
|
25530
25604
|
throw new TypeError("iOS release buildNumber and prepareBuildNumber cannot be combined.");
|
|
@@ -25554,7 +25628,7 @@ var buildAbsoluteIosRelease = async (options) => {
|
|
|
25554
25628
|
const exportPath = join7(staging, "export");
|
|
25555
25629
|
const exportPlist = join7(staging, "ExportOptions.plist");
|
|
25556
25630
|
await mkdir5(exportPath, { recursive: true });
|
|
25557
|
-
await writeFile6(exportPlist, exportOptions());
|
|
25631
|
+
await writeFile6(exportPlist, exportOptions("app-store-connect"));
|
|
25558
25632
|
const run = options.run ?? defaultRun2;
|
|
25559
25633
|
try {
|
|
25560
25634
|
const developmentTeam = developmentTeamArgument(options.developmentTeam);
|
|
@@ -25611,6 +25685,13 @@ var buildAbsoluteIosRelease = async (options) => {
|
|
|
25611
25685
|
sha256File2(artifactPath)
|
|
25612
25686
|
]);
|
|
25613
25687
|
const releaseId = `amobile_ios_${sha2562}`;
|
|
25688
|
+
const registered = options.registeredDeviceArtifact ? await exportRegisteredDeviceArtifact({
|
|
25689
|
+
archivePath,
|
|
25690
|
+
...options.env ? { env: options.env } : {},
|
|
25691
|
+
nativeDirectory,
|
|
25692
|
+
run,
|
|
25693
|
+
staging
|
|
25694
|
+
}) : undefined;
|
|
25614
25695
|
return await installRelease2(artifactPath, {
|
|
25615
25696
|
appBuild: manifest.appBuild,
|
|
25616
25697
|
appId: manifest.appId,
|
|
@@ -25620,12 +25701,13 @@ var buildAbsoluteIosRelease = async (options) => {
|
|
|
25620
25701
|
format: 1,
|
|
25621
25702
|
marketingVersion,
|
|
25622
25703
|
platform: "ios",
|
|
25704
|
+
...registered ? { registeredDevice: registered.metadata } : {},
|
|
25623
25705
|
releaseId,
|
|
25624
25706
|
runtime: manifest.runtime,
|
|
25625
25707
|
sha256: sha2562,
|
|
25626
25708
|
signed,
|
|
25627
25709
|
type: "ipa"
|
|
25628
|
-
}, safeOutputDirectory2(options.projectRoot, options.outputDirectory));
|
|
25710
|
+
}, safeOutputDirectory2(options.projectRoot, options.outputDirectory), registered?.artifactPath);
|
|
25629
25711
|
} finally {
|
|
25630
25712
|
await rm5(staging, { force: true, recursive: true }).catch(() => {
|
|
25631
25713
|
return;
|
|
@@ -25640,9 +25722,40 @@ var installAbsoluteIosRelease = async (options) => {
|
|
|
25640
25722
|
]);
|
|
25641
25723
|
if (bytes !== metadata.bytes || sha2562 !== metadata.sha256)
|
|
25642
25724
|
throw new TypeError("Remote iOS release artifact does not match its signed metadata.");
|
|
25725
|
+
if (metadata.registeredDevice) {
|
|
25726
|
+
if (!options.registeredArtifactPath)
|
|
25727
|
+
throw new TypeError("Remote iOS release metadata requires its registered-device artifact.");
|
|
25728
|
+
const [registeredBytes, registeredSha256] = await Promise.all([
|
|
25729
|
+
stat3(options.registeredArtifactPath).then(({ size }) => size),
|
|
25730
|
+
sha256File2(options.registeredArtifactPath)
|
|
25731
|
+
]);
|
|
25732
|
+
if (registeredBytes !== metadata.registeredDevice.bytes || registeredSha256 !== metadata.registeredDevice.sha256)
|
|
25733
|
+
throw new TypeError("Remote iOS registered-device artifact does not match its signed metadata.");
|
|
25734
|
+
}
|
|
25643
25735
|
const { artifact: _artifact, ...releaseMetadata } = metadata;
|
|
25644
|
-
return installRelease2(options.artifactPath, releaseMetadata, safeOutputDirectory2(options.projectRoot, options.outputDirectory));
|
|
25736
|
+
return installRelease2(options.artifactPath, releaseMetadata, safeOutputDirectory2(options.projectRoot, options.outputDirectory), options.registeredArtifactPath);
|
|
25645
25737
|
};
|
|
25738
|
+
// src/mobile/iosReleaseAcceptance.ts
|
|
25739
|
+
import { createHash as createHash7 } from "crypto";
|
|
25740
|
+
import {
|
|
25741
|
+
access as access8,
|
|
25742
|
+
mkdir as mkdir6,
|
|
25743
|
+
mkdtemp as mkdtemp5,
|
|
25744
|
+
readFile as readFile8,
|
|
25745
|
+
readdir as readdir4,
|
|
25746
|
+
rm as rm6,
|
|
25747
|
+
stat as stat4
|
|
25748
|
+
} from "fs/promises";
|
|
25749
|
+
import {
|
|
25750
|
+
basename as basename2,
|
|
25751
|
+
dirname as dirname5,
|
|
25752
|
+
isAbsolute as isAbsolute5,
|
|
25753
|
+
join as join8,
|
|
25754
|
+
relative as relative6,
|
|
25755
|
+
resolve as resolve6,
|
|
25756
|
+
sep as sep5
|
|
25757
|
+
} from "path";
|
|
25758
|
+
|
|
25646
25759
|
// src/mobile/iosUpgradeConformance.ts
|
|
25647
25760
|
var captureCommand5 = async (command) => {
|
|
25648
25761
|
const process2 = Bun.spawn(command, { stderr: "pipe", stdout: "pipe" });
|
|
@@ -25713,8 +25826,381 @@ var assertAbsoluteIosInstalledAppUpgrade = (before, after) => {
|
|
|
25713
25826
|
if (afterBuild <= beforeBuild)
|
|
25714
25827
|
throw new Error(`iOS CFBundleVersion did not increase (${before.buildNumber} -> ${after.buildNumber}).`);
|
|
25715
25828
|
};
|
|
25829
|
+
|
|
25830
|
+
// src/mobile/iosReleaseAcceptance.ts
|
|
25831
|
+
var READY_MARKERS = {
|
|
25832
|
+
capacitor: "Capacitor embedded web content ready",
|
|
25833
|
+
expo: "Expo embedded web content ready"
|
|
25834
|
+
};
|
|
25835
|
+
var READY_TIMEOUT_MS = 30000;
|
|
25836
|
+
var READY_POLL_MS = 250;
|
|
25837
|
+
var defaultRun3 = async (command, options = {}) => {
|
|
25838
|
+
const process2 = Bun.spawn(command, {
|
|
25839
|
+
cwd: options.cwd,
|
|
25840
|
+
env: options.env,
|
|
25841
|
+
stderr: "pipe",
|
|
25842
|
+
stdin: "ignore",
|
|
25843
|
+
stdout: "pipe"
|
|
25844
|
+
});
|
|
25845
|
+
const [exitCode, stderr, stdout] = await Promise.all([
|
|
25846
|
+
process2.exited,
|
|
25847
|
+
new Response(process2.stderr).text(),
|
|
25848
|
+
new Response(process2.stdout).text()
|
|
25849
|
+
]);
|
|
25850
|
+
return { exitCode, stderr, stdout };
|
|
25851
|
+
};
|
|
25852
|
+
var exists3 = async (path) => {
|
|
25853
|
+
try {
|
|
25854
|
+
await access8(path);
|
|
25855
|
+
return true;
|
|
25856
|
+
} catch {
|
|
25857
|
+
return false;
|
|
25858
|
+
}
|
|
25859
|
+
};
|
|
25860
|
+
var sha2562 = async (path) => createHash7("sha256").update(await readFile8(path)).digest("hex");
|
|
25861
|
+
var inside2 = (root, candidate) => {
|
|
25862
|
+
const path = relative6(resolve6(root), resolve6(candidate));
|
|
25863
|
+
return path === "" || !isAbsolute5(path) && path !== ".." && !path.startsWith(`..${sep5}`);
|
|
25864
|
+
};
|
|
25865
|
+
var requireSuccess3 = async (run, command, label, options) => {
|
|
25866
|
+
const result = await run(command, options);
|
|
25867
|
+
if (result.exitCode !== 0)
|
|
25868
|
+
throw new Error(`${label} failed: ${result.stderr.trim() || result.stdout.trim() || `status ${result.exitCode}`}`);
|
|
25869
|
+
return result;
|
|
25870
|
+
};
|
|
25871
|
+
var findByExtension2 = async (root, extension) => {
|
|
25872
|
+
if (!await exists3(root))
|
|
25873
|
+
return;
|
|
25874
|
+
const entries = await readdir4(root, { withFileTypes: true });
|
|
25875
|
+
const matches2 = await Promise.all(entries.map(async (entry) => {
|
|
25876
|
+
const path = join8(root, entry.name);
|
|
25877
|
+
if (entry.name.endsWith(extension))
|
|
25878
|
+
return path;
|
|
25879
|
+
return entry.isDirectory() ? findByExtension2(path, extension) : undefined;
|
|
25880
|
+
}));
|
|
25881
|
+
return matches2.find((match) => match !== undefined);
|
|
25882
|
+
};
|
|
25883
|
+
var readAbsoluteIosRelease = async (projectRoot, requested) => {
|
|
25884
|
+
const root = resolve6(projectRoot);
|
|
25885
|
+
const selected = resolve6(root, requested);
|
|
25886
|
+
if (!inside2(root, selected))
|
|
25887
|
+
throw new TypeError("mobile test ios --release must remain inside the project.");
|
|
25888
|
+
const metadataPath = basename2(selected) === "release.json" ? selected : join8(selected, "release.json");
|
|
25889
|
+
const releaseRoot = dirname5(metadataPath);
|
|
25890
|
+
const metadata = requireAbsoluteIosReleaseMetadata(JSON.parse(await readFile8(metadataPath, "utf8")));
|
|
25891
|
+
const artifactPath = resolve6(releaseRoot, metadata.artifact);
|
|
25892
|
+
if (!inside2(releaseRoot, artifactPath))
|
|
25893
|
+
throw new TypeError("iOS release artifact path is invalid.");
|
|
25894
|
+
const [artifactStat, artifactSha256] = await Promise.all([
|
|
25895
|
+
stat4(artifactPath),
|
|
25896
|
+
sha2562(artifactPath)
|
|
25897
|
+
]);
|
|
25898
|
+
if (artifactStat.size !== metadata.bytes || artifactSha256 !== metadata.sha256)
|
|
25899
|
+
throw new TypeError(`Immutable iOS release ${metadata.releaseId} is missing or modified.`);
|
|
25900
|
+
const registered = metadata.registeredDevice;
|
|
25901
|
+
let registeredArtifactPath;
|
|
25902
|
+
if (registered) {
|
|
25903
|
+
registeredArtifactPath = resolve6(releaseRoot, registered.artifact);
|
|
25904
|
+
if (!inside2(releaseRoot, registeredArtifactPath))
|
|
25905
|
+
throw new TypeError("iOS registered-device artifact path is invalid.");
|
|
25906
|
+
const [registeredStat, registeredSha256] = await Promise.all([
|
|
25907
|
+
stat4(registeredArtifactPath),
|
|
25908
|
+
sha2562(registeredArtifactPath)
|
|
25909
|
+
]);
|
|
25910
|
+
if (registeredStat.size !== registered.bytes || registeredSha256 !== registered.sha256)
|
|
25911
|
+
throw new TypeError(`Registered-device export for ${metadata.releaseId} is missing or modified.`);
|
|
25912
|
+
}
|
|
25913
|
+
return {
|
|
25914
|
+
artifactPath,
|
|
25915
|
+
metadata,
|
|
25916
|
+
metadataPath,
|
|
25917
|
+
registeredArtifactPath,
|
|
25918
|
+
releaseRoot
|
|
25919
|
+
};
|
|
25920
|
+
};
|
|
25921
|
+
var releaseMarker = (release) => {
|
|
25922
|
+
const marker = READY_MARKERS[release.metadata.engine];
|
|
25923
|
+
return release.metadata.buildNumber === undefined ? marker : `${marker}; version=${release.metadata.marketingVersion}; build=${release.metadata.buildNumber}`;
|
|
25924
|
+
};
|
|
25925
|
+
var waitForSimulatorMarker = async (options) => {
|
|
25926
|
+
const startedAt = performance.now();
|
|
25927
|
+
const poll = async () => {
|
|
25928
|
+
if (performance.now() - startedAt >= READY_TIMEOUT_MS)
|
|
25929
|
+
throw new Error("The installed iOS Release app launched but its embedded content did not become ready.");
|
|
25930
|
+
const logs = await options.run([
|
|
25931
|
+
options.xcrun,
|
|
25932
|
+
"simctl",
|
|
25933
|
+
"spawn",
|
|
25934
|
+
options.udid,
|
|
25935
|
+
"log",
|
|
25936
|
+
"show",
|
|
25937
|
+
"--style",
|
|
25938
|
+
"compact",
|
|
25939
|
+
"--start",
|
|
25940
|
+
options.startedAt.toISOString(),
|
|
25941
|
+
"--predicate",
|
|
25942
|
+
`eventMessage CONTAINS "${releaseMarker(options.release)}"`
|
|
25943
|
+
]);
|
|
25944
|
+
if (logs.exitCode === 0 && logs.stdout.includes(releaseMarker(options.release)))
|
|
25945
|
+
return;
|
|
25946
|
+
await Bun.sleep(READY_POLL_MS);
|
|
25947
|
+
await poll();
|
|
25948
|
+
};
|
|
25949
|
+
await poll();
|
|
25950
|
+
};
|
|
25951
|
+
var launchSimulator = async (options) => {
|
|
25952
|
+
const startedAt = performance.now();
|
|
25953
|
+
const logStartedAt = new Date;
|
|
25954
|
+
await requireSuccess3(options.run, [
|
|
25955
|
+
options.xcrun,
|
|
25956
|
+
"simctl",
|
|
25957
|
+
"launch",
|
|
25958
|
+
"--terminate-running-process",
|
|
25959
|
+
options.udid,
|
|
25960
|
+
options.release.metadata.appId
|
|
25961
|
+
], "iOS Simulator Release launch");
|
|
25962
|
+
await waitForSimulatorMarker({ ...options, startedAt: logStartedAt });
|
|
25963
|
+
return Math.round(performance.now() - startedAt);
|
|
25964
|
+
};
|
|
25965
|
+
var runAbsoluteIosSimulatorReleaseAcceptance = async (options) => {
|
|
25966
|
+
const run = options.run ?? defaultRun3;
|
|
25967
|
+
const xcodebuild = options.xcodebuild ?? "/usr/bin/xcodebuild";
|
|
25968
|
+
const xcrun = options.xcrun ?? "/usr/bin/xcrun";
|
|
25969
|
+
const startedAt = performance.now();
|
|
25970
|
+
const iosRoot = join8(options.config.nativeProjectDirectory, "ios");
|
|
25971
|
+
const xcode = await resolveAbsoluteIosXcodeProject(iosRoot);
|
|
25972
|
+
const derivedData = join8(options.artifactDirectory, "DerivedData");
|
|
25973
|
+
await mkdir6(options.artifactDirectory, { recursive: true });
|
|
25974
|
+
await requireSuccess3(run, [
|
|
25975
|
+
xcodebuild,
|
|
25976
|
+
"-workspace",
|
|
25977
|
+
xcode.workspacePath,
|
|
25978
|
+
"-scheme",
|
|
25979
|
+
xcode.scheme,
|
|
25980
|
+
"-configuration",
|
|
25981
|
+
"Release",
|
|
25982
|
+
"-destination",
|
|
25983
|
+
`platform=iOS Simulator,id=${options.udid}`,
|
|
25984
|
+
"-derivedDataPath",
|
|
25985
|
+
derivedData,
|
|
25986
|
+
`MARKETING_VERSION=${options.release.metadata.marketingVersion}`,
|
|
25987
|
+
...options.release.metadata.buildNumber === undefined ? [] : [
|
|
25988
|
+
`CURRENT_PROJECT_VERSION=${options.release.metadata.buildNumber}`
|
|
25989
|
+
],
|
|
25990
|
+
"build"
|
|
25991
|
+
], "iOS Simulator Release build", { cwd: iosRoot });
|
|
25992
|
+
const app = await findByExtension2(join8(derivedData, "Build", "Products"), ".app");
|
|
25993
|
+
if (!app)
|
|
25994
|
+
throw new Error("Xcode did not produce a Simulator Release app.");
|
|
25995
|
+
const installStartedAt = performance.now();
|
|
25996
|
+
await requireSuccess3(run, [xcrun, "simctl", "install", options.udid, app], "iOS Simulator Release installation");
|
|
25997
|
+
const installMs = Math.round(performance.now() - installStartedAt);
|
|
25998
|
+
const installed = await inspectAbsoluteIosInstalledApp(xcrun, options.udid, options.release.metadata.appId, (command) => run(command));
|
|
25999
|
+
if (installed.version !== options.release.metadata.marketingVersion)
|
|
26000
|
+
throw new Error(`Installed iOS version ${installed.version ?? "unknown"} does not match release ${options.release.metadata.marketingVersion}.`);
|
|
26001
|
+
if (options.release.metadata.buildNumber !== undefined && installed.buildNumber !== String(options.release.metadata.buildNumber))
|
|
26002
|
+
throw new Error(`Installed iOS build ${installed.buildNumber ?? "unknown"} does not match release ${options.release.metadata.buildNumber}.`);
|
|
26003
|
+
const launchMs = await launchSimulator({
|
|
26004
|
+
release: options.release,
|
|
26005
|
+
run,
|
|
26006
|
+
udid: options.udid,
|
|
26007
|
+
xcrun
|
|
26008
|
+
});
|
|
26009
|
+
await requireSuccess3(run, [
|
|
26010
|
+
xcrun,
|
|
26011
|
+
"simctl",
|
|
26012
|
+
"terminate",
|
|
26013
|
+
options.udid,
|
|
26014
|
+
options.release.metadata.appId
|
|
26015
|
+
], "iOS Simulator Release termination");
|
|
26016
|
+
const relaunchMs = await launchSimulator({
|
|
26017
|
+
release: options.release,
|
|
26018
|
+
run,
|
|
26019
|
+
udid: options.udid,
|
|
26020
|
+
xcrun
|
|
26021
|
+
});
|
|
26022
|
+
return {
|
|
26023
|
+
artifactBytes: options.release.metadata.bytes,
|
|
26024
|
+
artifactExactness: "source-equivalent",
|
|
26025
|
+
artifactSha256: options.release.metadata.sha256,
|
|
26026
|
+
...options.release.metadata.buildNumber === undefined ? {} : { buildNumber: options.release.metadata.buildNumber },
|
|
26027
|
+
distribution: "simulator-release",
|
|
26028
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
26029
|
+
embeddedLocal: true,
|
|
26030
|
+
engine: options.release.metadata.engine,
|
|
26031
|
+
installMs,
|
|
26032
|
+
launchMs,
|
|
26033
|
+
marketingVersion: options.release.metadata.marketingVersion,
|
|
26034
|
+
networkUnavailable: "not-proven",
|
|
26035
|
+
relaunchMs,
|
|
26036
|
+
releaseId: options.release.metadata.releaseId,
|
|
26037
|
+
signed: options.release.metadata.signed,
|
|
26038
|
+
status: "pass",
|
|
26039
|
+
target: "simulator"
|
|
26040
|
+
};
|
|
26041
|
+
};
|
|
26042
|
+
var readUntilMarker = async (reader, marker, output = "") => {
|
|
26043
|
+
const { done, value } = await reader.read();
|
|
26044
|
+
if (done)
|
|
26045
|
+
return { found: false, output };
|
|
26046
|
+
const next = `${output}${new TextDecoder().decode(value)}`;
|
|
26047
|
+
if (next.includes(marker))
|
|
26048
|
+
return { found: true, output: next };
|
|
26049
|
+
return readUntilMarker(reader, marker, next);
|
|
26050
|
+
};
|
|
26051
|
+
var observeDeviceLaunch = async (options) => {
|
|
26052
|
+
const startedAt = performance.now();
|
|
26053
|
+
const process2 = Bun.spawn([
|
|
26054
|
+
options.xcrun,
|
|
26055
|
+
"devicectl",
|
|
26056
|
+
"device",
|
|
26057
|
+
"process",
|
|
26058
|
+
"launch",
|
|
26059
|
+
"--console",
|
|
26060
|
+
"--terminate-existing",
|
|
26061
|
+
"--device",
|
|
26062
|
+
options.device,
|
|
26063
|
+
options.appId
|
|
26064
|
+
], { stderr: "pipe", stdin: "ignore", stdout: "pipe" });
|
|
26065
|
+
const stdoutReader = process2.stdout.getReader();
|
|
26066
|
+
const stderrReader = process2.stderr.getReader();
|
|
26067
|
+
const requireMarker = async (reader) => {
|
|
26068
|
+
const result = await readUntilMarker(reader, options.marker);
|
|
26069
|
+
if (!result.found)
|
|
26070
|
+
throw new Error(`Console stream closed before readiness.${result.output.trim() ? ` Output: ${result.output.trim()}` : ""}`);
|
|
26071
|
+
return result;
|
|
26072
|
+
};
|
|
26073
|
+
const observed = Promise.any([
|
|
26074
|
+
requireMarker(stdoutReader),
|
|
26075
|
+
requireMarker(stderrReader)
|
|
26076
|
+
]);
|
|
26077
|
+
try {
|
|
26078
|
+
const result = await Promise.race([
|
|
26079
|
+
observed.then((value) => ({ type: "output", value })).catch(() => ({ type: "closed" })),
|
|
26080
|
+
Bun.sleep(options.timeoutMs ?? READY_TIMEOUT_MS).then(() => ({
|
|
26081
|
+
type: "timeout"
|
|
26082
|
+
}))
|
|
26083
|
+
]);
|
|
26084
|
+
if (result.type === "output" && result.value.found)
|
|
26085
|
+
return Math.round(performance.now() - startedAt);
|
|
26086
|
+
if (result.type === "closed")
|
|
26087
|
+
throw new Error("The physical iOS app exited before embedded content became ready.");
|
|
26088
|
+
throw new Error("The physical iOS app did not report embedded readiness before the timeout.");
|
|
26089
|
+
} finally {
|
|
26090
|
+
process2.kill();
|
|
26091
|
+
await Promise.all([
|
|
26092
|
+
stdoutReader.cancel().catch(() => {
|
|
26093
|
+
return;
|
|
26094
|
+
}),
|
|
26095
|
+
stderrReader.cancel().catch(() => {
|
|
26096
|
+
return;
|
|
26097
|
+
})
|
|
26098
|
+
]);
|
|
26099
|
+
stdoutReader.releaseLock();
|
|
26100
|
+
stderrReader.releaseLock();
|
|
26101
|
+
}
|
|
26102
|
+
};
|
|
26103
|
+
var installRegisteredDeviceRelease = async (options) => {
|
|
26104
|
+
if (!options.release.registeredArtifactPath)
|
|
26105
|
+
throw new TypeError("This release has no same-archive registered-device IPA. Rebuild with `absolute mobile build ios --registered-device-artifact`.");
|
|
26106
|
+
const staging = await mkdtemp5(join8(dirname5(options.release.releaseRoot), ".ios-device-"));
|
|
26107
|
+
try {
|
|
26108
|
+
await requireSuccess3(options.run, [
|
|
26109
|
+
"/usr/bin/ditto",
|
|
26110
|
+
"-x",
|
|
26111
|
+
"-k",
|
|
26112
|
+
options.release.registeredArtifactPath,
|
|
26113
|
+
staging
|
|
26114
|
+
], "iOS registered-device IPA extraction");
|
|
26115
|
+
const app = await findByExtension2(staging, ".app");
|
|
26116
|
+
if (!app)
|
|
26117
|
+
throw new Error("The registered-device IPA contains no installable app.");
|
|
26118
|
+
const startedAt = performance.now();
|
|
26119
|
+
await requireSuccess3(options.run, [
|
|
26120
|
+
options.xcrun,
|
|
26121
|
+
"devicectl",
|
|
26122
|
+
"device",
|
|
26123
|
+
"install",
|
|
26124
|
+
"app",
|
|
26125
|
+
"--device",
|
|
26126
|
+
options.device,
|
|
26127
|
+
app
|
|
26128
|
+
], "iOS registered-device Release installation");
|
|
26129
|
+
return Math.round(performance.now() - startedAt);
|
|
26130
|
+
} finally {
|
|
26131
|
+
await rm6(staging, { force: true, recursive: true });
|
|
26132
|
+
}
|
|
26133
|
+
};
|
|
26134
|
+
var inspectTestFlightInstallation = async (options) => {
|
|
26135
|
+
const apps = await requireSuccess3(options.run, [
|
|
26136
|
+
options.xcrun,
|
|
26137
|
+
"devicectl",
|
|
26138
|
+
"device",
|
|
26139
|
+
"info",
|
|
26140
|
+
"apps",
|
|
26141
|
+
"--device",
|
|
26142
|
+
options.device
|
|
26143
|
+
], "TestFlight installation inspection");
|
|
26144
|
+
if (!apps.stdout.includes(options.release.metadata.appId))
|
|
26145
|
+
throw new Error("The selected device does not have the requested TestFlight app installed.");
|
|
26146
|
+
return 0;
|
|
26147
|
+
};
|
|
26148
|
+
var runAbsoluteIosDeviceReleaseAcceptance = async (options) => {
|
|
26149
|
+
if (!options.networkUnavailableConfirmed)
|
|
26150
|
+
throw new TypeError("Physical iOS offline acceptance requires explicit confirmation that Airplane Mode is enabled and Wi-Fi is disabled in Settings.");
|
|
26151
|
+
const run = options.run ?? defaultRun3;
|
|
26152
|
+
const xcrun = options.xcrun ?? "/usr/bin/xcrun";
|
|
26153
|
+
const startedAt = performance.now();
|
|
26154
|
+
await requireSuccess3(run, [
|
|
26155
|
+
xcrun,
|
|
26156
|
+
"devicectl",
|
|
26157
|
+
"device",
|
|
26158
|
+
"info",
|
|
26159
|
+
"details",
|
|
26160
|
+
"--device",
|
|
26161
|
+
options.device
|
|
26162
|
+
], "iOS physical-device availability inspection");
|
|
26163
|
+
const installation = {
|
|
26164
|
+
device: options.device,
|
|
26165
|
+
release: options.release,
|
|
26166
|
+
run,
|
|
26167
|
+
xcrun
|
|
26168
|
+
};
|
|
26169
|
+
const installMs = options.distribution === "registered-device" ? await installRegisteredDeviceRelease(installation) : await inspectTestFlightInstallation(installation);
|
|
26170
|
+
const observe = options.observeLaunch ?? ((launch2) => observeDeviceLaunch({ ...launch2, xcrun }));
|
|
26171
|
+
const marker = releaseMarker(options.release);
|
|
26172
|
+
const launchMs = await observe({
|
|
26173
|
+
appId: options.release.metadata.appId,
|
|
26174
|
+
device: options.device,
|
|
26175
|
+
marker
|
|
26176
|
+
});
|
|
26177
|
+
const relaunchMs = await observe({
|
|
26178
|
+
appId: options.release.metadata.appId,
|
|
26179
|
+
device: options.device,
|
|
26180
|
+
marker
|
|
26181
|
+
});
|
|
26182
|
+
return {
|
|
26183
|
+
artifactBytes: options.release.metadata.bytes,
|
|
26184
|
+
artifactExactness: options.distribution === "testflight" ? "store-delivered" : "archive-equivalent",
|
|
26185
|
+
artifactSha256: options.release.metadata.sha256,
|
|
26186
|
+
...options.release.metadata.buildNumber === undefined ? {} : { buildNumber: options.release.metadata.buildNumber },
|
|
26187
|
+
distribution: options.distribution === "testflight" ? "apple-processed" : "registered-device",
|
|
26188
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
26189
|
+
embeddedLocal: true,
|
|
26190
|
+
engine: options.release.metadata.engine,
|
|
26191
|
+
installMs,
|
|
26192
|
+
launchMs,
|
|
26193
|
+
marketingVersion: options.release.metadata.marketingVersion,
|
|
26194
|
+
networkUnavailable: "user-confirmed",
|
|
26195
|
+
relaunchMs,
|
|
26196
|
+
releaseId: options.release.metadata.releaseId,
|
|
26197
|
+
signed: options.release.metadata.signed,
|
|
26198
|
+
status: "pass",
|
|
26199
|
+
target: "device"
|
|
26200
|
+
};
|
|
26201
|
+
};
|
|
25716
26202
|
// src/mobile/iosConformance.ts
|
|
25717
|
-
import { readFile as
|
|
26203
|
+
import { readFile as readFile9, stat as stat5 } from "fs/promises";
|
|
25718
26204
|
var HMR_LINE = new RegExp(String.raw`\[hmr:ios\]\s+([^\n]*?)\s+(applied in|falling back to reload after|failed after)\s+(\d+)ms(?:; server\s+(\d+)ms, client\s+(\d+)ms)?`, "u");
|
|
25719
26205
|
var parseAbsoluteIosHmrLog = (line) => {
|
|
25720
26206
|
const match = HMR_LINE.exec(line);
|
|
@@ -25746,13 +26232,13 @@ var waitForAbsoluteIosHmrLog = async (options) => {
|
|
|
25746
26232
|
const sleep = options.sleep ?? Bun.sleep;
|
|
25747
26233
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
25748
26234
|
const deadline = Date.now() + timeoutMs;
|
|
25749
|
-
let offset = options.startOffset ?? await
|
|
26235
|
+
let offset = options.startOffset ?? await stat5(options.logPath).then(({ size }) => size).catch(() => 0);
|
|
25750
26236
|
let buffered = "";
|
|
25751
26237
|
const poll = async () => {
|
|
25752
26238
|
if (Date.now() > deadline)
|
|
25753
26239
|
throw new Error(`No iOS native HMR acknowledgement was observed within ${timeoutMs}ms.`);
|
|
25754
26240
|
options.signal?.throwIfAborted();
|
|
25755
|
-
const contents = await
|
|
26241
|
+
const contents = await readFile9(options.logPath).catch(() => Buffer.alloc(0));
|
|
25756
26242
|
if (contents.byteLength < offset) {
|
|
25757
26243
|
offset = 0;
|
|
25758
26244
|
buffered = "";
|
|
@@ -25772,18 +26258,18 @@ var waitForAbsoluteIosHmrLog = async (options) => {
|
|
|
25772
26258
|
return poll();
|
|
25773
26259
|
};
|
|
25774
26260
|
// src/mobile/iosSimulatorController.ts
|
|
25775
|
-
import { createHash as
|
|
26261
|
+
import { createHash as createHash8, randomUUID as randomUUID3 } from "crypto";
|
|
25776
26262
|
import {
|
|
25777
|
-
access as
|
|
26263
|
+
access as access9,
|
|
25778
26264
|
copyFile as copyFile4,
|
|
25779
|
-
mkdir as
|
|
25780
|
-
readFile as
|
|
26265
|
+
mkdir as mkdir7,
|
|
26266
|
+
readFile as readFile10,
|
|
25781
26267
|
rename as rename7,
|
|
25782
|
-
rm as
|
|
26268
|
+
rm as rm7,
|
|
25783
26269
|
writeFile as writeFile7
|
|
25784
26270
|
} from "fs/promises";
|
|
25785
26271
|
import { isIP as isIP2 } from "net";
|
|
25786
|
-
import { dirname as
|
|
26272
|
+
import { dirname as dirname6, isAbsolute as isAbsolute6, join as join9, relative as relative7, resolve as resolve7, sep as sep6 } from "path";
|
|
25787
26273
|
init_getDurationString();
|
|
25788
26274
|
var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone";
|
|
25789
26275
|
var BOOT_TIMEOUT_MS = 180000;
|
|
@@ -25793,7 +26279,7 @@ var NATIVE_CACHE_FORMAT = 1;
|
|
|
25793
26279
|
var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25794
26280
|
var pathExists5 = async (path) => {
|
|
25795
26281
|
try {
|
|
25796
|
-
await
|
|
26282
|
+
await access9(path);
|
|
25797
26283
|
return true;
|
|
25798
26284
|
} catch {
|
|
25799
26285
|
return false;
|
|
@@ -25822,7 +26308,7 @@ var defaultCapture3 = (command, options = {}) => {
|
|
|
25822
26308
|
};
|
|
25823
26309
|
}
|
|
25824
26310
|
};
|
|
25825
|
-
var
|
|
26311
|
+
var defaultRun4 = async (command, options = {}) => {
|
|
25826
26312
|
const process2 = Bun.spawn(command, {
|
|
25827
26313
|
cwd: options.cwd,
|
|
25828
26314
|
env: options.env,
|
|
@@ -25888,7 +26374,7 @@ var defaultStartNativeLogs = (command, options, onLine) => {
|
|
|
25888
26374
|
}
|
|
25889
26375
|
};
|
|
25890
26376
|
};
|
|
25891
|
-
var
|
|
26377
|
+
var requireSuccess4 = async (command, label, run, options) => {
|
|
25892
26378
|
const exitCode = await run(command, options);
|
|
25893
26379
|
if (exitCode !== 0)
|
|
25894
26380
|
throw new Error(`${label} failed with status ${exitCode}.`);
|
|
@@ -25899,7 +26385,7 @@ var trustIosSimulatorDevelopmentCa = async (options, udid, run, log) => {
|
|
|
25899
26385
|
if (!options.certificateAuthorityPath) {
|
|
25900
26386
|
throw new Error("iOS Simulator HTTPS requires the AbsoluteJS development CA certificate.");
|
|
25901
26387
|
}
|
|
25902
|
-
await
|
|
26388
|
+
await requireSuccess4([
|
|
25903
26389
|
options.project.xcrun,
|
|
25904
26390
|
"simctl",
|
|
25905
26391
|
"keychain",
|
|
@@ -26028,18 +26514,18 @@ var preferredIphoneType = (types) => types.filter((type) => type.name.startsWith
|
|
|
26028
26514
|
return rightPro - leftPro;
|
|
26029
26515
|
})[0];
|
|
26030
26516
|
var journalPaths = (projectRoot) => {
|
|
26031
|
-
const root =
|
|
26517
|
+
const root = join9(projectRoot, ".absolutejs", "mobile", "ios-dev-session");
|
|
26032
26518
|
return {
|
|
26033
|
-
configBackup:
|
|
26034
|
-
infoBackup:
|
|
26035
|
-
journal:
|
|
26519
|
+
configBackup: join9(root, "capacitor-config.backup"),
|
|
26520
|
+
infoBackup: join9(root, "Info.plist.backup"),
|
|
26521
|
+
journal: join9(root, "journal.json"),
|
|
26036
26522
|
root
|
|
26037
26523
|
};
|
|
26038
26524
|
};
|
|
26039
|
-
var nativeCachePath = (projectRoot) =>
|
|
26525
|
+
var nativeCachePath = (projectRoot) => join9(projectRoot, ".absolutejs", "mobile", "ios-native-cache.json");
|
|
26040
26526
|
var isInside = (root, path) => {
|
|
26041
|
-
const value =
|
|
26042
|
-
return value === "" || !value.startsWith(`..${
|
|
26527
|
+
const value = relative7(resolve7(root), resolve7(path));
|
|
26528
|
+
return value === "" || !value.startsWith(`..${sep6}`) && value !== ".." && !isAbsolute6(value);
|
|
26043
26529
|
};
|
|
26044
26530
|
var parseJournal = (value) => {
|
|
26045
26531
|
if (!isRecord4(value) || value.format !== DEV_JOURNAL_FORMAT)
|
|
@@ -26061,10 +26547,10 @@ var parseJournal = (value) => {
|
|
|
26061
26547
|
var repairAbsoluteIosDevSession = async (projectRoot) => {
|
|
26062
26548
|
const paths = journalPaths(projectRoot);
|
|
26063
26549
|
if (!await pathExists5(paths.journal)) {
|
|
26064
|
-
await
|
|
26550
|
+
await rm7(paths.root, { force: true, recursive: true });
|
|
26065
26551
|
return false;
|
|
26066
26552
|
}
|
|
26067
|
-
const journal = await
|
|
26553
|
+
const journal = await readFile10(paths.journal, "utf8").then((source) => parseJournal(JSON.parse(source))).catch(() => null);
|
|
26068
26554
|
if (!journal || !isInside(projectRoot, journal.nativeConfigPath) || !isInside(projectRoot, journal.infoPath) || !isInside(paths.root, journal.configBackupPath) || !isInside(paths.root, journal.infoBackupPath)) {
|
|
26069
26555
|
throw new Error(`Refusing unsafe or invalid iOS dev journal at ${paths.journal}.`);
|
|
26070
26556
|
}
|
|
@@ -26072,7 +26558,7 @@ var repairAbsoluteIosDevSession = async (projectRoot) => {
|
|
|
26072
26558
|
await copyFile4(journal.configBackupPath, journal.nativeConfigPath);
|
|
26073
26559
|
if (await pathExists5(journal.infoBackupPath))
|
|
26074
26560
|
await copyFile4(journal.infoBackupPath, journal.infoPath);
|
|
26075
|
-
await
|
|
26561
|
+
await rm7(paths.root, { force: true, recursive: true });
|
|
26076
26562
|
return true;
|
|
26077
26563
|
};
|
|
26078
26564
|
var iosDevelopmentInfoPlist = (source, cleartext) => {
|
|
@@ -26098,16 +26584,16 @@ var iosDevelopmentInfoPlist = (source, cleartext) => {
|
|
|
26098
26584
|
var writeDevProjection = async (project, port, https, serverHost = "localhost") => {
|
|
26099
26585
|
const paths = journalPaths(project.projectRoot);
|
|
26100
26586
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
26101
|
-
const nativeConfigPath =
|
|
26102
|
-
const infoPath =
|
|
26587
|
+
const nativeConfigPath = join9(project.nativeDirectory, "App", "App", "capacitor.config.json");
|
|
26588
|
+
const infoPath = join9(project.nativeDirectory, "App", "App", "Info.plist");
|
|
26103
26589
|
const [configSource, infoSource] = await Promise.all([
|
|
26104
|
-
|
|
26105
|
-
|
|
26590
|
+
readFile10(nativeConfigPath, "utf8"),
|
|
26591
|
+
readFile10(infoPath, "utf8")
|
|
26106
26592
|
]);
|
|
26107
26593
|
const parsed = JSON.parse(configSource);
|
|
26108
26594
|
if (!isRecord4(parsed))
|
|
26109
26595
|
throw new Error(`Invalid Capacitor native config at ${nativeConfigPath}.`);
|
|
26110
|
-
await
|
|
26596
|
+
await mkdir7(paths.root, { recursive: true });
|
|
26111
26597
|
await Promise.all([
|
|
26112
26598
|
writeFile7(paths.configBackup, configSource, { flag: "wx" }),
|
|
26113
26599
|
writeFile7(paths.infoBackup, infoSource, { flag: "wx" })
|
|
@@ -26154,11 +26640,11 @@ var parseNativeCache = (value) => {
|
|
|
26154
26640
|
]))
|
|
26155
26641
|
};
|
|
26156
26642
|
};
|
|
26157
|
-
var readNativeCache = (projectRoot) =>
|
|
26643
|
+
var readNativeCache = (projectRoot) => readFile10(nativeCachePath(projectRoot), "utf8").then((source) => parseNativeCache(JSON.parse(source))).catch(() => null);
|
|
26158
26644
|
var writeNativeCache = async (projectRoot, cache) => {
|
|
26159
26645
|
const destination = nativeCachePath(projectRoot);
|
|
26160
26646
|
const temporary = `${destination}.${process.pid}.${randomUUID3()}.tmp`;
|
|
26161
|
-
await
|
|
26647
|
+
await mkdir7(dirname6(destination), { recursive: true });
|
|
26162
26648
|
try {
|
|
26163
26649
|
await writeFile7(temporary, `${JSON.stringify(cache, null, "\t")}
|
|
26164
26650
|
`, {
|
|
@@ -26166,7 +26652,7 @@ var writeNativeCache = async (projectRoot, cache) => {
|
|
|
26166
26652
|
});
|
|
26167
26653
|
await rename7(temporary, destination);
|
|
26168
26654
|
} finally {
|
|
26169
|
-
await
|
|
26655
|
+
await rm7(temporary, { force: true }).catch(() => {
|
|
26170
26656
|
return;
|
|
26171
26657
|
});
|
|
26172
26658
|
}
|
|
@@ -26272,12 +26758,12 @@ var physicalIosAppIsInstalled = (project, identifier, capture) => {
|
|
|
26272
26758
|
return result.exitCode === 0 && result.stdout.includes(project.config.appId);
|
|
26273
26759
|
};
|
|
26274
26760
|
var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
26275
|
-
const derivedDataPath =
|
|
26276
|
-
await
|
|
26277
|
-
await
|
|
26761
|
+
const derivedDataPath = join9(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash8("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
26762
|
+
await mkdir7(derivedDataPath, { recursive: true });
|
|
26763
|
+
await requireSuccess4([
|
|
26278
26764
|
project.xcodebuild,
|
|
26279
26765
|
"-workspace",
|
|
26280
|
-
|
|
26766
|
+
join9(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
26281
26767
|
"-scheme",
|
|
26282
26768
|
"App",
|
|
26283
26769
|
"-configuration",
|
|
@@ -26288,18 +26774,18 @@ var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
|
26288
26774
|
derivedDataPath,
|
|
26289
26775
|
"build"
|
|
26290
26776
|
], "iOS simulator build", run, { cwd: project.nativeDirectory, signal });
|
|
26291
|
-
const appPath =
|
|
26777
|
+
const appPath = join9(derivedDataPath, "Build", "Products", "Debug-iphonesimulator", "App.app");
|
|
26292
26778
|
if (!await pathExists5(appPath))
|
|
26293
26779
|
throw new Error(`Xcode did not produce the simulator app at ${appPath}.`);
|
|
26294
26780
|
return appPath;
|
|
26295
26781
|
};
|
|
26296
26782
|
var buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
|
|
26297
|
-
const derivedDataPath =
|
|
26298
|
-
await
|
|
26299
|
-
await
|
|
26783
|
+
const derivedDataPath = join9(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash8("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
26784
|
+
await mkdir7(derivedDataPath, { recursive: true });
|
|
26785
|
+
await requireSuccess4([
|
|
26300
26786
|
project.xcodebuild,
|
|
26301
26787
|
"-workspace",
|
|
26302
|
-
|
|
26788
|
+
join9(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
26303
26789
|
"-scheme",
|
|
26304
26790
|
"App",
|
|
26305
26791
|
"-configuration",
|
|
@@ -26311,7 +26797,7 @@ var buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
|
|
|
26311
26797
|
"-allowProvisioningUpdates",
|
|
26312
26798
|
"build"
|
|
26313
26799
|
], "iOS physical-device build (configure automatic signing and a Development Team in Xcode if this is the first run)", run, { cwd: project.nativeDirectory, signal });
|
|
26314
|
-
const appPath =
|
|
26800
|
+
const appPath = join9(derivedDataPath, "Build", "Products", "Debug-iphoneos", "App.app");
|
|
26315
26801
|
if (!await pathExists5(appPath))
|
|
26316
26802
|
throw new Error(`Xcode did not produce the physical-device app at ${appPath}.`);
|
|
26317
26803
|
return appPath;
|
|
@@ -26327,7 +26813,7 @@ var ensurePhysicalIosDebugApp = async (options) => {
|
|
|
26327
26813
|
const appPath = await buildPhysicalIosDebugApp(options.project, options.identifier, options.run, options.signal);
|
|
26328
26814
|
throwIfAborted2(options.signal);
|
|
26329
26815
|
options.transition("installing");
|
|
26330
|
-
await
|
|
26816
|
+
await requireSuccess4([
|
|
26331
26817
|
options.project.xcrun,
|
|
26332
26818
|
"devicectl",
|
|
26333
26819
|
"device",
|
|
@@ -26360,7 +26846,7 @@ var ensureIosDebugApp = async (options) => {
|
|
|
26360
26846
|
const appPath = await buildIosDebugApp(options.project, options.udid, options.fingerprint, options.run, options.signal);
|
|
26361
26847
|
throwIfAborted2(options.signal);
|
|
26362
26848
|
options.transition("installing");
|
|
26363
|
-
await
|
|
26849
|
+
await requireSuccess4([options.project.xcrun, "simctl", "install", options.udid, appPath], "iOS simulator app installation", options.run, { signal: options.signal });
|
|
26364
26850
|
const updated = installedAppIdentity(options.project, options.udid, options.capture);
|
|
26365
26851
|
if (updated) {
|
|
26366
26852
|
await writeNativeCache(options.project.projectRoot, {
|
|
@@ -26446,7 +26932,7 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
|
|
|
26446
26932
|
if (detectAbsoluteMobileHost() !== "macos")
|
|
26447
26933
|
throw new Error("iOS development requires macOS and Xcode.");
|
|
26448
26934
|
const target = options.target ?? "simulator";
|
|
26449
|
-
const projectRoot =
|
|
26935
|
+
const projectRoot = resolve7(options.projectRoot);
|
|
26450
26936
|
const checks = await inspectAbsoluteMobileToolchain({ host: "macos" });
|
|
26451
26937
|
const failed = checks.filter((check) => check.platform === "ios" && !(target === "device" && check.id === "ios.runtime") && (check.status === "fail" || check.status === "warn"));
|
|
26452
26938
|
if (failed.length > 0)
|
|
@@ -26455,20 +26941,20 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
|
|
|
26455
26941
|
const xcodebuild = checks.find((check) => check.id === "ios.xcodebuild")?.path;
|
|
26456
26942
|
if (!xcrun || !xcodebuild)
|
|
26457
26943
|
throw new Error("Xcode tools disappeared after readiness checks.");
|
|
26458
|
-
const cap =
|
|
26944
|
+
const cap = join9(projectRoot, "node_modules", ".bin", "cap");
|
|
26459
26945
|
if (!await pathExists5(cap))
|
|
26460
26946
|
throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
|
|
26461
26947
|
await writeAbsoluteCapacitorConfig(config, { projectRoot });
|
|
26462
|
-
await
|
|
26463
|
-
const placeholder =
|
|
26948
|
+
await mkdir7(config.bundleDirectory, { recursive: true });
|
|
26949
|
+
const placeholder = join9(config.bundleDirectory, "index.html");
|
|
26464
26950
|
if (!await pathExists5(placeholder))
|
|
26465
26951
|
await writeFile7(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
|
|
26466
26952
|
`);
|
|
26467
|
-
const nativeDirectory =
|
|
26953
|
+
const nativeDirectory = join9(config.nativeProjectDirectory, "ios");
|
|
26468
26954
|
if (!await pathExists5(nativeDirectory)) {
|
|
26469
26955
|
if (!options.createNativeProject)
|
|
26470
26956
|
throw new Error("iOS native project has not been created.");
|
|
26471
|
-
const run = options.run ??
|
|
26957
|
+
const run = options.run ?? defaultRun4;
|
|
26472
26958
|
if (await run([cap, "add", "ios"], { cwd: projectRoot }) !== 0)
|
|
26473
26959
|
throw new Error("Capacitor iOS project creation failed.");
|
|
26474
26960
|
}
|
|
@@ -26521,7 +27007,7 @@ var prepareIosSimulatorTarget = async (options) => {
|
|
|
26521
27007
|
]);
|
|
26522
27008
|
options.transition("connecting");
|
|
26523
27009
|
await waitForBootedSimulator(options.project, device.udid, options.capture, options.sleep, options.startOptions.signal);
|
|
26524
|
-
await
|
|
27010
|
+
await requireSuccess4([options.project.xcrun, "simctl", "bootstatus", device.udid, "-b"], "iOS simulator boot readiness", options.run, { signal: options.startOptions.signal });
|
|
26525
27011
|
await trustIosSimulatorDevelopmentCa(options.startOptions, device.udid, options.run, options.log);
|
|
26526
27012
|
return { caEnrollmentServer: null, startedSimulator, udid: device.udid };
|
|
26527
27013
|
};
|
|
@@ -26531,7 +27017,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
26531
27017
|
const targetKind = deviceIdentifier ? "device" : "simulator";
|
|
26532
27018
|
const serverHost = deviceIdentifier ? normalizeAbsoluteIosDeviceHost(options.serverHost ?? "") : "localhost";
|
|
26533
27019
|
const capture = options.capture ?? defaultCapture3;
|
|
26534
|
-
const run = options.run ??
|
|
27020
|
+
const run = options.run ?? defaultRun4;
|
|
26535
27021
|
const sleep = options.sleep ?? Bun.sleep;
|
|
26536
27022
|
const spawn2 = options.spawn ?? defaultSpawn;
|
|
26537
27023
|
const log = options.log ?? console.log;
|
|
@@ -26571,13 +27057,13 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
26571
27057
|
nativeLogs = attachNativeLogs(project, udid, options);
|
|
26572
27058
|
return;
|
|
26573
27059
|
}
|
|
26574
|
-
await
|
|
27060
|
+
await requireSuccess4(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app relaunch", run, { signal: options.signal });
|
|
26575
27061
|
};
|
|
26576
27062
|
try {
|
|
26577
27063
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
26578
27064
|
throwIfAborted2(options.signal);
|
|
26579
27065
|
transition("syncing");
|
|
26580
|
-
await
|
|
27066
|
+
await requireSuccess4([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
|
|
26581
27067
|
transition("configuring");
|
|
26582
27068
|
if (options.embeddedBundle !== true)
|
|
26583
27069
|
await writeDevProjection(project, options.port, options.https === true, serverHost);
|
|
@@ -26643,7 +27129,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
26643
27129
|
nativeLogs = attachNativeLogs(project, udid, options);
|
|
26644
27130
|
transition("launching");
|
|
26645
27131
|
if (!deviceIdentifier || !nativeLogs)
|
|
26646
|
-
await
|
|
27132
|
+
await requireSuccess4(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app launch", run, { signal: options.signal });
|
|
26647
27133
|
transition("ready");
|
|
26648
27134
|
timings.total = performance.now() - startedAt;
|
|
26649
27135
|
log(options.embeddedBundle === true ? `iOS ${targetKind} connected with the embedded bundle and backend on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).` : `iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
@@ -26692,11 +27178,11 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
26692
27178
|
screenshot: async (destination) => {
|
|
26693
27179
|
if (deviceIdentifier)
|
|
26694
27180
|
throw new Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");
|
|
26695
|
-
const resolved =
|
|
27181
|
+
const resolved = resolve7(project.projectRoot, destination);
|
|
26696
27182
|
if (!isInside(project.projectRoot, resolved))
|
|
26697
27183
|
throw new Error("iOS screenshot destination must remain inside the project.");
|
|
26698
|
-
await
|
|
26699
|
-
await
|
|
27184
|
+
await mkdir7(dirname6(resolved), { recursive: true });
|
|
27185
|
+
await requireSuccess4([
|
|
26700
27186
|
project.xcrun,
|
|
26701
27187
|
"simctl",
|
|
26702
27188
|
"io",
|
|
@@ -26722,7 +27208,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
26722
27208
|
};
|
|
26723
27209
|
// src/mobile/iosNativeWatcher.ts
|
|
26724
27210
|
import { watch } from "fs";
|
|
26725
|
-
import { basename as
|
|
27211
|
+
import { basename as basename3 } from "path";
|
|
26726
27212
|
var NATIVE_CHANGE_DEBOUNCE_MS = 500;
|
|
26727
27213
|
var ROOT_NATIVE_INPUTS = new Set([
|
|
26728
27214
|
"absolute.config.js",
|
|
@@ -26812,28 +27298,28 @@ var createAbsoluteIosNativeWatcher = async (options) => {
|
|
|
26812
27298
|
options.signal?.addEventListener("abort", close, { once: true });
|
|
26813
27299
|
return { close };
|
|
26814
27300
|
};
|
|
26815
|
-
var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(
|
|
27301
|
+
var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename3(path));
|
|
26816
27302
|
// src/mobile/remoteMacProtocol.ts
|
|
26817
|
-
import { createHash as
|
|
27303
|
+
import { createHash as createHash9, randomUUID as randomUUID4 } from "crypto";
|
|
26818
27304
|
import {
|
|
26819
27305
|
chmod,
|
|
26820
|
-
mkdir as
|
|
26821
|
-
mkdtemp as
|
|
26822
|
-
readFile as
|
|
27306
|
+
mkdir as mkdir8,
|
|
27307
|
+
mkdtemp as mkdtemp6,
|
|
27308
|
+
readFile as readFile11,
|
|
26823
27309
|
rename as rename8,
|
|
26824
|
-
rm as
|
|
27310
|
+
rm as rm8,
|
|
26825
27311
|
writeFile as writeFile8
|
|
26826
27312
|
} from "fs/promises";
|
|
26827
27313
|
import { homedir as homedir3 } from "os";
|
|
26828
27314
|
import { isIP as isIP3 } from "net";
|
|
26829
27315
|
import {
|
|
26830
|
-
dirname as
|
|
26831
|
-
isAbsolute as
|
|
26832
|
-
join as
|
|
27316
|
+
dirname as dirname7,
|
|
27317
|
+
isAbsolute as isAbsolute7,
|
|
27318
|
+
join as join10,
|
|
26833
27319
|
posix,
|
|
26834
|
-
relative as
|
|
27320
|
+
relative as relative8,
|
|
26835
27321
|
resolve as resolvePath3,
|
|
26836
|
-
sep as
|
|
27322
|
+
sep as sep7
|
|
26837
27323
|
} from "path";
|
|
26838
27324
|
|
|
26839
27325
|
// src/mobile/remoteMacWire.ts
|
|
@@ -26848,14 +27334,14 @@ var REMOTE_RELEASE_LEASE_HEARTBEAT_MS = 15000;
|
|
|
26848
27334
|
var REMOTE_RELEASE_LEASE_STALE_SECONDS = 120;
|
|
26849
27335
|
var PROFILE_NAME = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/u;
|
|
26850
27336
|
var SSH_DESTINATION = /^(?:[A-Za-z0-9._-]+@)?[A-Za-z0-9._:-]+$/u;
|
|
26851
|
-
var defaultProfilePath = () =>
|
|
27337
|
+
var defaultProfilePath = () => join10(homedir3(), ".absolutejs", "mobile", "remote-macs.json");
|
|
26852
27338
|
var emptyStore = () => ({
|
|
26853
27339
|
format: PROFILE_FORMAT,
|
|
26854
27340
|
profiles: {}
|
|
26855
27341
|
});
|
|
26856
27342
|
var loadStore = async (path = defaultProfilePath()) => {
|
|
26857
27343
|
try {
|
|
26858
|
-
const parsed = JSON.parse(await
|
|
27344
|
+
const parsed = JSON.parse(await readFile11(path, "utf8"));
|
|
26859
27345
|
if (parsed.format !== PROFILE_FORMAT || typeof parsed.profiles !== "object" || parsed.profiles === null || Array.isArray(parsed.profiles))
|
|
26860
27346
|
throw new Error("Unsupported remote Mac profile format.");
|
|
26861
27347
|
for (const [key, profile] of Object.entries(parsed.profiles)) {
|
|
@@ -26872,7 +27358,7 @@ var loadStore = async (path = defaultProfilePath()) => {
|
|
|
26872
27358
|
}
|
|
26873
27359
|
};
|
|
26874
27360
|
var saveStore = async (store, path = defaultProfilePath()) => {
|
|
26875
|
-
await
|
|
27361
|
+
await mkdir8(dirname7(path), { recursive: true });
|
|
26876
27362
|
const temporary = `${path}.${randomUUID4()}.tmp`;
|
|
26877
27363
|
await writeFile8(temporary, `${JSON.stringify(store, null, 2)}
|
|
26878
27364
|
`, {
|
|
@@ -27046,16 +27532,16 @@ var removeAbsoluteRemoteMacProfile = async (name, profilePath) => {
|
|
|
27046
27532
|
await saveStore(store, profilePath);
|
|
27047
27533
|
return true;
|
|
27048
27534
|
};
|
|
27049
|
-
var projectIdentity = (projectRoot, appId) =>
|
|
27535
|
+
var projectIdentity = (projectRoot, appId) => createHash9("sha256").update(`${resolvePath3(projectRoot)}\x00${appId}`).digest("hex").slice(0, 20);
|
|
27050
27536
|
var createAbsoluteRemoteExpoIosDevProject = (config, projectRoot, profile) => {
|
|
27051
27537
|
if (config.engine !== "expo")
|
|
27052
27538
|
throw new TypeError("Remote Expo execution requires mobile.engine: expo.");
|
|
27053
27539
|
return createAbsoluteRemoteIosDevProject(config, projectRoot, profile);
|
|
27054
27540
|
};
|
|
27055
27541
|
var createAbsoluteRemoteIosDevProject = (config, projectRoot, profile) => ({
|
|
27056
|
-
cap:
|
|
27542
|
+
cap: join10(resolvePath3(projectRoot), "node_modules", ".bin", "cap"),
|
|
27057
27543
|
config,
|
|
27058
|
-
nativeDirectory:
|
|
27544
|
+
nativeDirectory: join10(config.nativeProjectDirectory, "ios"),
|
|
27059
27545
|
profile,
|
|
27060
27546
|
projectRoot: resolvePath3(projectRoot),
|
|
27061
27547
|
remote: true,
|
|
@@ -27212,8 +27698,8 @@ var installAbsoluteRemoteMacAgent = async (project) => {
|
|
|
27212
27698
|
};
|
|
27213
27699
|
var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
|
|
27214
27700
|
const shippedCandidates = [
|
|
27215
|
-
|
|
27216
|
-
|
|
27701
|
+
join10(import.meta.dir, "remoteMacAgentEntry.js"),
|
|
27702
|
+
join10(import.meta.dir, "..", "mobile", "remoteMacAgentEntry.js")
|
|
27217
27703
|
];
|
|
27218
27704
|
let path;
|
|
27219
27705
|
for (const candidate of shippedCandidates) {
|
|
@@ -27224,14 +27710,14 @@ var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
|
|
|
27224
27710
|
}
|
|
27225
27711
|
if (!path) {
|
|
27226
27712
|
const sourceCandidates = [
|
|
27227
|
-
|
|
27228
|
-
|
|
27713
|
+
join10(import.meta.dir, "remoteMacAgentEntry.ts"),
|
|
27714
|
+
join10(import.meta.dir, "..", "..", "src", "mobile", "remoteMacAgentEntry.ts")
|
|
27229
27715
|
];
|
|
27230
27716
|
const source = await sourceCandidates.reduce(async (found, candidate) => await found ?? (await Bun.file(candidate).exists() ? candidate : undefined), Promise.resolve(undefined));
|
|
27231
27717
|
if (!source)
|
|
27232
27718
|
throw new Error("The AbsoluteJS installation does not contain its remote Mac agent artifact.");
|
|
27233
|
-
const outdir =
|
|
27234
|
-
await
|
|
27719
|
+
const outdir = join10(resolvePath3(projectRoot), ".absolutejs", "mobile", "remote-agent");
|
|
27720
|
+
await mkdir8(outdir, { recursive: true });
|
|
27235
27721
|
const result = await Bun.build({
|
|
27236
27722
|
entrypoints: [source],
|
|
27237
27723
|
minify: true,
|
|
@@ -27240,13 +27726,13 @@ var materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
|
|
|
27240
27726
|
});
|
|
27241
27727
|
if (!result.success)
|
|
27242
27728
|
throw new AggregateError(result.logs, "Failed to build the AbsoluteJS remote Mac agent.");
|
|
27243
|
-
path =
|
|
27729
|
+
path = join10(outdir, "remoteMacAgentEntry.js");
|
|
27244
27730
|
}
|
|
27245
27731
|
const bytes = await Bun.file(path).arrayBuffer();
|
|
27246
|
-
const
|
|
27247
|
-
return { bytes: bytes.byteLength, path, sha256:
|
|
27732
|
+
const sha2563 = createHash9("sha256").update(new Uint8Array(bytes)).digest("hex");
|
|
27733
|
+
return { bytes: bytes.byteLength, path, sha256: sha2563 };
|
|
27248
27734
|
};
|
|
27249
|
-
var portableRelativePath = (root, path) =>
|
|
27735
|
+
var portableRelativePath = (root, path) => relative8(root, path).split(sep7).join(posix.sep);
|
|
27250
27736
|
var portableMobileConfig = (project) => ({
|
|
27251
27737
|
appId: project.config.appId,
|
|
27252
27738
|
appName: project.config.appName,
|
|
@@ -27427,9 +27913,9 @@ var writeRemoteArtifact = async (path, stream) => {
|
|
|
27427
27913
|
};
|
|
27428
27914
|
var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory) => {
|
|
27429
27915
|
const releaseRoot = posix.join(project.remoteProjectRoot, ".absolutejs", "mobile", "releases", "ios", metadata.releaseId);
|
|
27430
|
-
const stagingParent =
|
|
27431
|
-
await
|
|
27432
|
-
const staging = await
|
|
27916
|
+
const stagingParent = join10(project.projectRoot, ".absolutejs", "mobile");
|
|
27917
|
+
await mkdir8(stagingParent, { recursive: true });
|
|
27918
|
+
const staging = await mkdtemp6(join10(stagingParent, ".remote-ios-"));
|
|
27433
27919
|
try {
|
|
27434
27920
|
const remoteMetadata = requireRemoteSuccess(await defaultTransport.capture([
|
|
27435
27921
|
...absoluteRemoteMacSshBase(project.profile),
|
|
@@ -27439,7 +27925,7 @@ var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory
|
|
|
27439
27925
|
const downloadedMetadata = JSON.parse(remoteMetadata);
|
|
27440
27926
|
if (JSON.stringify(requireAbsoluteIosReleaseMetadata(downloadedMetadata)) !== JSON.stringify(metadata))
|
|
27441
27927
|
throw new TypeError("Remote iOS release metadata changed during retrieval.");
|
|
27442
|
-
const artifactPath =
|
|
27928
|
+
const artifactPath = join10(staging, "App.ipa");
|
|
27443
27929
|
const download = Bun.spawn([
|
|
27444
27930
|
...absoluteRemoteMacSshBase(project.profile),
|
|
27445
27931
|
"/bin/sh -lc",
|
|
@@ -27459,7 +27945,7 @@ var retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory
|
|
|
27459
27945
|
projectRoot: project.projectRoot
|
|
27460
27946
|
});
|
|
27461
27947
|
} finally {
|
|
27462
|
-
await
|
|
27948
|
+
await rm8(staging, { force: true, recursive: true }).catch(() => {
|
|
27463
27949
|
return;
|
|
27464
27950
|
});
|
|
27465
27951
|
}
|
|
@@ -27701,7 +28187,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
|
|
|
27701
28187
|
await syncProject(options.project);
|
|
27702
28188
|
const syncDuration = performance.now() - syncStartedAt;
|
|
27703
28189
|
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
27704
|
-
const encodedCertificateAuthority = options.certificateAuthorityPath ? (await
|
|
28190
|
+
const encodedCertificateAuthority = options.certificateAuthorityPath ? (await readFile11(options.certificateAuthorityPath)).toString("base64url") : undefined;
|
|
27705
28191
|
const physicalDevice = options.deviceIdentifier !== undefined;
|
|
27706
28192
|
const expo = options.project.config.engine === "expo";
|
|
27707
28193
|
if (expo && options.metroPort === undefined)
|
|
@@ -27768,8 +28254,8 @@ var startAbsoluteRemoteDevSession = async (options) => {
|
|
|
27768
28254
|
const pending = new Map;
|
|
27769
28255
|
let resolveReady;
|
|
27770
28256
|
let rejectReady;
|
|
27771
|
-
const readyPromise = new Promise((
|
|
27772
|
-
resolveReady =
|
|
28257
|
+
const readyPromise = new Promise((resolve8, reject) => {
|
|
28258
|
+
resolveReady = resolve8;
|
|
27773
28259
|
rejectReady = reject;
|
|
27774
28260
|
});
|
|
27775
28261
|
const handleEvent = (event) => {
|
|
@@ -27872,7 +28358,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
|
|
|
27872
28358
|
options.log?.(`Remote Mac connected (${options.project.profile.name}); agent ${agent.uploaded ? "uploaded" : "cache hit"}, project synced, and ${expo ? "Expo " : ""}iOS ready in ${totalDuration.toFixed(2)}ms.`);
|
|
27873
28359
|
const request = (commandName) => {
|
|
27874
28360
|
const id = randomUUID4();
|
|
27875
|
-
const response = new Promise((
|
|
28361
|
+
const response = new Promise((resolve8, reject) => pending.set(id, { reject, resolve: resolve8 }));
|
|
27876
28362
|
process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
27877
28363
|
`);
|
|
27878
28364
|
const flush = async () => {
|
|
@@ -27892,7 +28378,7 @@ var startAbsoluteRemoteDevSession = async (options) => {
|
|
|
27892
28378
|
if (closed)
|
|
27893
28379
|
return;
|
|
27894
28380
|
closed = true;
|
|
27895
|
-
const timeout = () => new Promise((
|
|
28381
|
+
const timeout = () => new Promise((resolve8) => setTimeout(() => resolve8("timeout"), REMOTE_SESSION_CLOSE_TIMEOUT_MS));
|
|
27896
28382
|
const id = randomUUID4();
|
|
27897
28383
|
process2.stdin.write(`${JSON.stringify({ command: "close", id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
27898
28384
|
`);
|
|
@@ -27939,10 +28425,10 @@ var startAbsoluteRemoteDevSession = async (options) => {
|
|
|
27939
28425
|
screenshot: async (destination) => {
|
|
27940
28426
|
const result = await request("screenshot");
|
|
27941
28427
|
const target = resolvePath3(options.project.projectRoot, destination);
|
|
27942
|
-
const targetRelative =
|
|
27943
|
-
if (targetRelative.startsWith("..") ||
|
|
28428
|
+
const targetRelative = relative8(options.project.projectRoot, target);
|
|
28429
|
+
if (targetRelative.startsWith("..") || isAbsolute7(targetRelative))
|
|
27944
28430
|
throw new Error("iOS screenshot must remain inside the project.");
|
|
27945
|
-
await
|
|
28431
|
+
await mkdir8(dirname7(target), { recursive: true });
|
|
27946
28432
|
await writeFile8(target, Buffer.from(result.data, "base64"));
|
|
27947
28433
|
return target;
|
|
27948
28434
|
},
|
|
@@ -27970,20 +28456,20 @@ var absoluteIosDeviceAcceptanceCommands = (options) => {
|
|
|
27970
28456
|
]
|
|
27971
28457
|
};
|
|
27972
28458
|
};
|
|
27973
|
-
var
|
|
28459
|
+
var requireSuccess5 = (result, message) => {
|
|
27974
28460
|
if (result.exitCode !== 0)
|
|
27975
28461
|
throw new Error(message);
|
|
27976
28462
|
return result;
|
|
27977
28463
|
};
|
|
27978
28464
|
var testAbsoluteIosPhysicalDevice = async (options) => {
|
|
27979
28465
|
const commands = absoluteIosDeviceAcceptanceCommands(options);
|
|
27980
|
-
|
|
27981
|
-
const apps =
|
|
28466
|
+
requireSuccess5(await options.capture(commands.details), "The selected physical iOS device is unavailable. Pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode.");
|
|
28467
|
+
const apps = requireSuccess5(await options.capture(commands.apps), "AbsoluteJS could not inspect installed apps on the physical iOS device.");
|
|
27982
28468
|
if (!apps.stdout.includes(options.appId))
|
|
27983
28469
|
throw new Error("The AbsoluteJS app is not installed on the selected physical iOS device. Start bun dev with the same --ios-device value first.");
|
|
27984
28470
|
const now = options.now ?? performance.now.bind(performance);
|
|
27985
28471
|
const startedAt = now();
|
|
27986
|
-
|
|
28472
|
+
requireSuccess5(await options.capture(commands.launch), "AbsoluteJS could not relaunch the app on the physical iOS device.");
|
|
27987
28473
|
await options.waitForHmr();
|
|
27988
28474
|
return {
|
|
27989
28475
|
hmrConnected: true,
|
|
@@ -28023,32 +28509,32 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
|
|
|
28023
28509
|
};
|
|
28024
28510
|
};
|
|
28025
28511
|
// src/mobile/buildPipeline.ts
|
|
28026
|
-
import { readFile as
|
|
28027
|
-
import { join as
|
|
28512
|
+
import { readFile as readFile17 } from "fs/promises";
|
|
28513
|
+
import { join as join20, resolve as resolve15 } from "path";
|
|
28028
28514
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
28029
28515
|
|
|
28030
28516
|
// src/mobile/buildRelease.ts
|
|
28031
|
-
import { createHash as
|
|
28032
|
-
import { mkdir as
|
|
28033
|
-
import { basename as
|
|
28517
|
+
import { createHash as createHash11 } from "crypto";
|
|
28518
|
+
import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile10 } from "fs/promises";
|
|
28519
|
+
import { basename as basename4, dirname as dirname8, extname, join as join11, relative as relative9, resolve as resolve10 } from "path";
|
|
28034
28520
|
init_releaseArtifact();
|
|
28035
|
-
var
|
|
28521
|
+
var sha2563 = (bytes) => createHash11("sha256").update(bytes).digest("hex");
|
|
28036
28522
|
var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
|
|
28037
28523
|
var rewriteStaticScriptPaths = (source, manifest) => source.replace(STATIC_SCRIPT_PATTERN, (match, prefix, path, suffix) => {
|
|
28038
28524
|
if (path.endsWith("/htmx.min.js"))
|
|
28039
28525
|
return match;
|
|
28040
|
-
const key = toPascal(
|
|
28526
|
+
const key = toPascal(basename4(path, extname(path)));
|
|
28041
28527
|
const builtPath = manifest[key];
|
|
28042
28528
|
return builtPath ? `${prefix}${builtPath}${suffix}` : match;
|
|
28043
28529
|
});
|
|
28044
28530
|
var readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]);
|
|
28045
28531
|
var resolveAssetPath = (buildDirectory, assetPath) => {
|
|
28046
|
-
const resolvedBuildDirectory =
|
|
28047
|
-
const resolvedAsset =
|
|
28532
|
+
const resolvedBuildDirectory = resolve10(buildDirectory);
|
|
28533
|
+
const resolvedAsset = resolve10(assetPath);
|
|
28048
28534
|
if (resolvedAsset.startsWith(`${resolvedBuildDirectory}/`)) {
|
|
28049
28535
|
return resolvedAsset;
|
|
28050
28536
|
}
|
|
28051
|
-
return
|
|
28537
|
+
return join11(buildDirectory, assetPath.replace(/^\/+/, ""));
|
|
28052
28538
|
};
|
|
28053
28539
|
var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
28054
28540
|
const assetPath = manifest[metadata.bundleKey];
|
|
@@ -28057,11 +28543,11 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
28057
28543
|
}
|
|
28058
28544
|
let resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
|
|
28059
28545
|
if (metadata.framework === "html" || metadata.framework === "htmx") {
|
|
28060
|
-
const source = await
|
|
28546
|
+
const source = await readFile13(resolvedAssetPath, "utf8");
|
|
28061
28547
|
const rewritten = rewriteStaticScriptPaths(source, manifest);
|
|
28062
|
-
const documentHash =
|
|
28063
|
-
resolvedAssetPath =
|
|
28064
|
-
await
|
|
28548
|
+
const documentHash = sha2563(new TextEncoder().encode(rewritten));
|
|
28549
|
+
resolvedAssetPath = join11(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
|
|
28550
|
+
await mkdir10(dirname8(resolvedAssetPath), { recursive: true });
|
|
28065
28551
|
await writeFile10(resolvedAssetPath, rewritten);
|
|
28066
28552
|
}
|
|
28067
28553
|
const pageAssetKey = metadata.bundleKey.replace(/Index$/u, "");
|
|
@@ -28071,20 +28557,20 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
28071
28557
|
].map((key) => manifest[key]).find((path) => typeof path === "string");
|
|
28072
28558
|
const resolvedStylePath = styleAssetPath ? resolveAssetPath(buildDirectory, styleAssetPath) : undefined;
|
|
28073
28559
|
const [bytes, styleBytes] = await Promise.all([
|
|
28074
|
-
|
|
28075
|
-
resolvedStylePath ?
|
|
28560
|
+
readFile13(resolvedAssetPath),
|
|
28561
|
+
resolvedStylePath ? readFile13(resolvedStylePath) : undefined
|
|
28076
28562
|
]);
|
|
28077
|
-
const bundlePath = `/${
|
|
28078
|
-
const styleBundlePath = resolvedStylePath ? `/${
|
|
28563
|
+
const bundlePath = `/${relative9(resolve10(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
|
|
28564
|
+
const styleBundlePath = resolvedStylePath ? `/${relative9(resolve10(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
|
|
28079
28565
|
return {
|
|
28080
|
-
bundleHash:
|
|
28566
|
+
bundleHash: sha2563(bytes),
|
|
28081
28567
|
bundlePath,
|
|
28082
28568
|
contract: metadata.contract,
|
|
28083
28569
|
framework: metadata.framework,
|
|
28084
28570
|
pageId: metadata.pageId,
|
|
28085
28571
|
propsSchemaHash: metadata.propsSchemaHash,
|
|
28086
28572
|
...styleBytes && styleBundlePath ? {
|
|
28087
|
-
styleBundleHash:
|
|
28573
|
+
styleBundleHash: sha2563(styleBytes),
|
|
28088
28574
|
styleBundlePath
|
|
28089
28575
|
} : {}
|
|
28090
28576
|
};
|
|
@@ -28092,7 +28578,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
28092
28578
|
var buildAbsoluteMobileCompatibilityRelease = async (options) => {
|
|
28093
28579
|
const [captured, producerBytes] = await Promise.all([
|
|
28094
28580
|
captureAbsoluteMobileRouteGraph(options.app),
|
|
28095
|
-
|
|
28581
|
+
readFile13(options.producerPath)
|
|
28096
28582
|
]);
|
|
28097
28583
|
if (captured.length === 0) {
|
|
28098
28584
|
throw new TypeError("No instrumented AbsoluteJS mobile page routes were found in the finalized Elysia route graph.");
|
|
@@ -28106,8 +28592,8 @@ var buildAbsoluteMobileCompatibilityRelease = async (options) => {
|
|
|
28106
28592
|
metadataByPage.set(metadata.pageId, metadata);
|
|
28107
28593
|
}
|
|
28108
28594
|
const pages = await Promise.all([...metadataByPage.values()].map((metadata) => pageFor(metadata, options.manifest, options.buildDirectory)));
|
|
28109
|
-
const producerHash =
|
|
28110
|
-
const appBuild = `ambuild_${
|
|
28595
|
+
const producerHash = sha2563(producerBytes);
|
|
28596
|
+
const appBuild = `ambuild_${sha2563(new TextEncoder().encode(JSON.stringify({
|
|
28111
28597
|
pages: pages.map(({
|
|
28112
28598
|
bundleHash,
|
|
28113
28599
|
bundlePath,
|
|
@@ -28183,15 +28669,15 @@ init_routeMatcher();
|
|
|
28183
28669
|
import {
|
|
28184
28670
|
cp,
|
|
28185
28671
|
copyFile as copyFile5,
|
|
28186
|
-
mkdir as
|
|
28187
|
-
mkdtemp as
|
|
28188
|
-
readFile as
|
|
28672
|
+
mkdir as mkdir11,
|
|
28673
|
+
mkdtemp as mkdtemp7,
|
|
28674
|
+
readFile as readFile14,
|
|
28189
28675
|
rename as rename10,
|
|
28190
|
-
rm as
|
|
28676
|
+
rm as rm10,
|
|
28191
28677
|
writeFile as writeFile11
|
|
28192
28678
|
} from "fs/promises";
|
|
28193
28679
|
import { existsSync as existsSync2 } from "fs";
|
|
28194
|
-
import { basename as
|
|
28680
|
+
import { basename as basename5, dirname as dirname9, extname as extname2, join as join12, relative as relative10, resolve as resolve11 } from "path";
|
|
28195
28681
|
|
|
28196
28682
|
// src/mobile/client.ts
|
|
28197
28683
|
init_pageProtocol();
|
|
@@ -28402,53 +28888,59 @@ var CAPACITOR_CLIENT_FRAMEWORKS = new Set([
|
|
|
28402
28888
|
var CLIENT_ASSET_DIRECTORIES = ["assets", "html", "htmx", "indexes"];
|
|
28403
28889
|
var errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code;
|
|
28404
28890
|
var shellBootstrapModule = () => {
|
|
28405
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28891
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync2);
|
|
28406
28892
|
if (candidate)
|
|
28407
28893
|
return candidate;
|
|
28408
28894
|
throw new TypeError("AbsoluteJS mobile shell bootstrap module is missing.");
|
|
28409
28895
|
};
|
|
28410
28896
|
var shellAuthModule = () => {
|
|
28411
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28897
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellAuth.${extension}`)).find(existsSync2);
|
|
28412
28898
|
if (candidate)
|
|
28413
28899
|
return candidate;
|
|
28414
28900
|
throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
|
|
28415
28901
|
};
|
|
28416
28902
|
var shellExpoAuthModule = () => {
|
|
28417
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28903
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync2);
|
|
28418
28904
|
if (candidate)
|
|
28419
28905
|
return candidate;
|
|
28420
28906
|
throw new TypeError("AbsoluteJS Expo auth bridge module is missing.");
|
|
28421
28907
|
};
|
|
28422
28908
|
var shellSyncModule = () => {
|
|
28423
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28909
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellSync.${extension}`)).find(existsSync2);
|
|
28424
28910
|
if (candidate)
|
|
28425
28911
|
return candidate;
|
|
28426
28912
|
throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
|
|
28427
28913
|
};
|
|
28428
28914
|
var shellExpoSyncModule = () => {
|
|
28429
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28915
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellExpoSync.${extension}`)).find(existsSync2);
|
|
28430
28916
|
if (candidate)
|
|
28431
28917
|
return candidate;
|
|
28432
28918
|
throw new TypeError("AbsoluteJS Expo Sync bridge module is missing.");
|
|
28433
28919
|
};
|
|
28434
28920
|
var shellPushModule = () => {
|
|
28435
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28921
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellPush.${extension}`)).find(existsSync2);
|
|
28436
28922
|
if (candidate)
|
|
28437
28923
|
return candidate;
|
|
28438
28924
|
throw new TypeError("AbsoluteJS mobile push shell module is missing.");
|
|
28439
28925
|
};
|
|
28440
28926
|
var shellExpoDevicesModule = () => {
|
|
28441
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28927
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellExpoDevices.${extension}`)).find(existsSync2);
|
|
28442
28928
|
if (candidate)
|
|
28443
28929
|
return candidate;
|
|
28444
28930
|
throw new TypeError("AbsoluteJS Expo device bridge module is missing.");
|
|
28445
28931
|
};
|
|
28446
28932
|
var shellUpdateModule = () => {
|
|
28447
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
28933
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellUpdate.${extension}`)).find(existsSync2);
|
|
28448
28934
|
if (candidate)
|
|
28449
28935
|
return candidate;
|
|
28450
28936
|
throw new TypeError("AbsoluteJS mobile update shell module is missing.");
|
|
28451
28937
|
};
|
|
28938
|
+
var shellReleaseReadinessModule = () => {
|
|
28939
|
+
const candidate = ["js", "ts"].map((extension) => join12(import.meta.dir, `shellReleaseReadiness.${extension}`)).find(existsSync2);
|
|
28940
|
+
if (candidate)
|
|
28941
|
+
return candidate;
|
|
28942
|
+
throw new TypeError("AbsoluteJS mobile release-readiness module is missing.");
|
|
28943
|
+
};
|
|
28452
28944
|
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
28453
28945
|
var contentSecurityPolicy = (productionOrigin) => {
|
|
28454
28946
|
const backend = new URL(productionOrigin);
|
|
@@ -28479,8 +28971,8 @@ var indexHtml = (appName, productionOrigin) => `<!doctype html>
|
|
|
28479
28971
|
</html>
|
|
28480
28972
|
`;
|
|
28481
28973
|
var sourceAssetPath = (buildDirectory, bundlePath) => {
|
|
28482
|
-
const root =
|
|
28483
|
-
const asset =
|
|
28974
|
+
const root = resolve11(buildDirectory);
|
|
28975
|
+
const asset = resolve11(root, bundlePath.replace(/^\/+/, ""));
|
|
28484
28976
|
if (!asset.startsWith(`${root}/`)) {
|
|
28485
28977
|
throw new TypeError("Mobile page bundle escaped the build directory.");
|
|
28486
28978
|
}
|
|
@@ -28497,15 +28989,15 @@ var resolveProjectImport = async (projectRoot, specifier) => {
|
|
|
28497
28989
|
const segments = specifier.split("/");
|
|
28498
28990
|
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
|
|
28499
28991
|
const subpath = specifier.slice(packageName.length);
|
|
28500
|
-
const packageDirectory =
|
|
28501
|
-
const manifest = JSON.parse(await
|
|
28992
|
+
const packageDirectory = join12(resolve11(projectRoot), "node_modules", packageName);
|
|
28993
|
+
const manifest = JSON.parse(await readFile14(join12(packageDirectory, "package.json"), "utf8"));
|
|
28502
28994
|
const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
|
|
28503
28995
|
const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
|
|
28504
28996
|
const target = importEntryTarget(entry);
|
|
28505
28997
|
if (typeof target !== "string" || !target.startsWith("./"))
|
|
28506
28998
|
throw new TypeError(`${specifier} does not publish an import entry.`);
|
|
28507
|
-
const resolved =
|
|
28508
|
-
if (!resolved.startsWith(`${
|
|
28999
|
+
const resolved = resolve11(packageDirectory, target);
|
|
29000
|
+
if (!resolved.startsWith(`${resolve11(packageDirectory)}/`))
|
|
28509
29001
|
throw new TypeError(`${specifier} has an unsafe import entry.`);
|
|
28510
29002
|
return resolved;
|
|
28511
29003
|
};
|
|
@@ -28536,9 +29028,10 @@ var buildShellBootstrap = async (staging, auth, sync, storagePrefix, engine, upd
|
|
|
28536
29028
|
const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absoluteMobilePush.capabilityOptions);
|
|
28537
29029
|
` : "";
|
|
28538
29030
|
const capabilityOptions = shellCapabilities.map((name, index) => `${JSON.stringify(name)}: ${name === "pushNotifications" ? "absoluteMobilePushCapability" : `absoluteDeviceCapability${index}()`}`).join(", ");
|
|
28539
|
-
const entryPath =
|
|
29031
|
+
const entryPath = join12(staging, ".absolute-mobile-entry.ts");
|
|
28540
29032
|
const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
|
|
28541
29033
|
const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
|
|
29034
|
+
const readinessImport = capacitor ? `import { markAbsoluteMobileShellReady } from ${JSON.stringify(shellReleaseReadinessModule())};` : "";
|
|
28542
29035
|
const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : `installAbsoluteExpoWebDeviceAdapter(${JSON.stringify(deviceCapabilities.capabilities)});`;
|
|
28543
29036
|
const shellOptionProperties = [
|
|
28544
29037
|
`engine: ${JSON.stringify(engine)}`
|
|
@@ -28556,9 +29049,10 @@ const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absolu
|
|
|
28556
29049
|
const shellOptions = `{ ${shellOptionProperties.join(", ")} }`;
|
|
28557
29050
|
await writeFile11(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
|
|
28558
29051
|
${adapterImport}
|
|
29052
|
+
${readinessImport}
|
|
28559
29053
|
${authImport}${syncImport}${pushImport}${updateImport}${capabilityImports}
|
|
28560
29054
|
${pushSetup}${adapterInstall}
|
|
28561
|
-
void startAbsoluteMobileShell(${shellOptions});
|
|
29055
|
+
void startAbsoluteMobileShell(${shellOptions})${capacitor ? ".then(markAbsoluteMobileShellReady)" : ""};
|
|
28562
29056
|
`);
|
|
28563
29057
|
const build = await Bun.build({
|
|
28564
29058
|
entrypoints: [entryPath],
|
|
@@ -28570,13 +29064,13 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
28570
29064
|
if (!build.success || build.outputs.length !== 1) {
|
|
28571
29065
|
throw new AggregateError(build.logs, "Failed to build the AbsoluteJS Capacitor shell.");
|
|
28572
29066
|
}
|
|
28573
|
-
await rename10(build.outputs[0]?.path ?? "",
|
|
28574
|
-
await
|
|
29067
|
+
await rename10(build.outputs[0]?.path ?? "", join12(staging, BOOTSTRAP_FILE));
|
|
29068
|
+
await rm10(entryPath, { force: true });
|
|
28575
29069
|
};
|
|
28576
29070
|
var removePreviousBundle = async (backup, moved) => {
|
|
28577
29071
|
if (!moved)
|
|
28578
29072
|
return;
|
|
28579
|
-
await
|
|
29073
|
+
await rm10(backup, { force: true, recursive: true });
|
|
28580
29074
|
};
|
|
28581
29075
|
var restorePreviousBundle = async (backup, destination, moved) => {
|
|
28582
29076
|
if (!moved)
|
|
@@ -28608,17 +29102,17 @@ var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) =
|
|
|
28608
29102
|
const extension = extname2(page.bundlePath) || ".js";
|
|
28609
29103
|
const localBundlePath = `./pages/${page.bundleHash}${extension}`;
|
|
28610
29104
|
const source = sourceAssetPath(buildDirectory, page.bundlePath);
|
|
28611
|
-
await copyFile5(source,
|
|
29105
|
+
await copyFile5(source, join12(staging, localBundlePath));
|
|
28612
29106
|
await copyAbsoluteClientDependencies(source, buildDirectory, staging, copiedDependencies);
|
|
28613
29107
|
let localStylePath;
|
|
28614
29108
|
if (page.styleBundlePath && page.styleBundleHash) {
|
|
28615
29109
|
const styleExtension = extname2(page.styleBundlePath) || ".css";
|
|
28616
29110
|
localStylePath = `./styles/${page.styleBundleHash}${styleExtension}`;
|
|
28617
29111
|
const styleSource = sourceAssetPath(buildDirectory, page.styleBundlePath);
|
|
28618
|
-
await
|
|
29112
|
+
await mkdir11(dirname9(join12(staging, localStylePath)), {
|
|
28619
29113
|
recursive: true
|
|
28620
29114
|
});
|
|
28621
|
-
await copyFile5(styleSource,
|
|
29115
|
+
await copyFile5(styleSource, join12(staging, localStylePath));
|
|
28622
29116
|
await copyAbsoluteClientDependencies(styleSource, buildDirectory, staging, copiedDependencies);
|
|
28623
29117
|
}
|
|
28624
29118
|
return {
|
|
@@ -28634,26 +29128,26 @@ var materializeAbsoluteMobileSourcemaps = async (pages, appBuild, projectRoot) =
|
|
|
28634
29128
|
return value;
|
|
28635
29129
|
};
|
|
28636
29130
|
const release = safeLeaf(appBuild, "Mobile app build");
|
|
28637
|
-
const privateRoot =
|
|
28638
|
-
const releaseRoot =
|
|
29131
|
+
const privateRoot = join12(projectRoot, "sourcemaps");
|
|
29132
|
+
const releaseRoot = join12(privateRoot, "mobile", release);
|
|
28639
29133
|
const copied = [];
|
|
28640
29134
|
const available = pages.flatMap((page) => {
|
|
28641
|
-
const source =
|
|
29135
|
+
const source = join12(privateRoot, `${basename5(page.bundlePath)}.map`);
|
|
28642
29136
|
return existsSync2(source) ? [{ page, source }] : [];
|
|
28643
29137
|
});
|
|
28644
29138
|
if (available.length > 0)
|
|
28645
|
-
await
|
|
29139
|
+
await mkdir11(releaseRoot, { recursive: true });
|
|
28646
29140
|
await Promise.all(available.map(async ({ page, source }) => {
|
|
28647
29141
|
const extension = extname2(page.bundlePath) || ".js";
|
|
28648
29142
|
if (!/^\.[a-z0-9]+$/iu.test(extension))
|
|
28649
29143
|
throw new TypeError("Mobile page extension is not a safe source-map key.");
|
|
28650
29144
|
const bundleHash = safeLeaf(page.bundleHash, "Mobile page bundle hash");
|
|
28651
29145
|
const file = `${bundleHash}${extension}.map`;
|
|
28652
|
-
await copyFile5(source,
|
|
29146
|
+
await copyFile5(source, join12(releaseRoot, file));
|
|
28653
29147
|
copied.push({ bundleHash, file, pageId: page.pageId });
|
|
28654
29148
|
}));
|
|
28655
29149
|
if (copied.length > 0) {
|
|
28656
|
-
await writeFile11(
|
|
29150
|
+
await writeFile11(join12(releaseRoot, "manifest.json"), `${JSON.stringify({
|
|
28657
29151
|
appBuild,
|
|
28658
29152
|
format: 1,
|
|
28659
29153
|
pages: copied.sort((left, right) => left.pageId.localeCompare(right.pageId))
|
|
@@ -28663,7 +29157,7 @@ var materializeAbsoluteMobileSourcemaps = async (pages, appBuild, projectRoot) =
|
|
|
28663
29157
|
return copied.length;
|
|
28664
29158
|
};
|
|
28665
29159
|
var absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
28666
|
-
const source = await
|
|
29160
|
+
const source = await readFile14(sourcePath, "utf8");
|
|
28667
29161
|
const extension = extname2(sourcePath).toLowerCase();
|
|
28668
29162
|
let scriptLoader;
|
|
28669
29163
|
if (extension === ".tsx")
|
|
@@ -28686,9 +29180,9 @@ var absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
|
28686
29180
|
const clean = specifier.split(/[?#]/u, 1)[0] ?? specifier;
|
|
28687
29181
|
if (clean.startsWith("/"))
|
|
28688
29182
|
return [clean];
|
|
28689
|
-
const resolved =
|
|
28690
|
-
const root =
|
|
28691
|
-
const relativePath =
|
|
29183
|
+
const resolved = resolve11(dirname9(sourcePath), clean);
|
|
29184
|
+
const root = resolve11(buildDirectory);
|
|
29185
|
+
const relativePath = relative10(root, resolved).replaceAll("\\", "/");
|
|
28692
29186
|
if (relativePath === ".." || relativePath.startsWith("../")) {
|
|
28693
29187
|
throw new TypeError(`Mobile client dependency escaped the build directory: ${specifier}`);
|
|
28694
29188
|
}
|
|
@@ -28700,8 +29194,8 @@ var copyAbsoluteClientDependency = async (specifier, buildDirectory, staging, co
|
|
|
28700
29194
|
return;
|
|
28701
29195
|
copied.add(specifier);
|
|
28702
29196
|
const source = sourceAssetPath(buildDirectory, specifier);
|
|
28703
|
-
const destination =
|
|
28704
|
-
await
|
|
29197
|
+
const destination = join12(staging, specifier.replace(/^\/+/, ""));
|
|
29198
|
+
await mkdir11(dirname9(destination), { recursive: true });
|
|
28705
29199
|
await copyFile5(source, destination);
|
|
28706
29200
|
await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
|
|
28707
29201
|
};
|
|
@@ -28714,14 +29208,14 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
|
|
|
28714
29208
|
throw new TypeError(`mobile.entry ${options.config.entry} is not a captured mobile page route.`);
|
|
28715
29209
|
}
|
|
28716
29210
|
const destination = options.config.bundleDirectory;
|
|
28717
|
-
await
|
|
28718
|
-
const staging = await
|
|
29211
|
+
await mkdir11(dirname9(destination), { recursive: true });
|
|
29212
|
+
const staging = await mkdtemp7(join12(dirname9(destination), `.${basename5(destination)}.stage-`));
|
|
28719
29213
|
try {
|
|
28720
|
-
const pageDirectory =
|
|
28721
|
-
await
|
|
29214
|
+
const pageDirectory = join12(staging, "pages");
|
|
29215
|
+
await mkdir11(pageDirectory, { recursive: true });
|
|
28722
29216
|
await Promise.all(CLIENT_ASSET_DIRECTORIES.map((directory) => ({
|
|
28723
|
-
destination:
|
|
28724
|
-
source:
|
|
29217
|
+
destination: join12(staging, directory),
|
|
29218
|
+
source: join12(options.buildDirectory, directory)
|
|
28725
29219
|
})).filter(({ source }) => existsSync2(source)).map(({ destination: assetDestination, source }) => cp(source, assetDestination, { recursive: true })));
|
|
28726
29220
|
const copiedDependencies = new Set;
|
|
28727
29221
|
const pages = await Promise.all(options.artifact.pages.map((page) => copyClientPage(page, options.buildDirectory, staging, copiedDependencies)));
|
|
@@ -28758,16 +29252,16 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
|
|
|
28758
29252
|
} : {}
|
|
28759
29253
|
};
|
|
28760
29254
|
await Promise.all([
|
|
28761
|
-
writeFile11(
|
|
29255
|
+
writeFile11(join12(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
28762
29256
|
`),
|
|
28763
|
-
writeFile11(
|
|
29257
|
+
writeFile11(join12(staging, INDEX_FILE), indexHtml(options.config.appName, options.config.productionOrigin)),
|
|
28764
29258
|
buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true, `absolutejs.${options.auth?.clientId ?? options.config.appId}.`, options.config.engine, options.config.engine === "capacitor" && options.config.updates !== undefined, options.deviceCapabilities, options.projectRoot)
|
|
28765
29259
|
]);
|
|
28766
29260
|
await installBundle(staging, destination);
|
|
28767
29261
|
await materializeAbsoluteMobileSourcemaps(options.artifact.pages, options.artifact.appBuild, options.projectRoot);
|
|
28768
29262
|
return manifest;
|
|
28769
29263
|
} catch (error) {
|
|
28770
|
-
await
|
|
29264
|
+
await rm10(staging, { force: true, recursive: true });
|
|
28771
29265
|
throw error;
|
|
28772
29266
|
}
|
|
28773
29267
|
};
|
|
@@ -28784,22 +29278,22 @@ init_nativeAuth();
|
|
|
28784
29278
|
init_syncSchema();
|
|
28785
29279
|
init_deviceCapabilities();
|
|
28786
29280
|
import {
|
|
28787
|
-
access as
|
|
28788
|
-
mkdir as
|
|
28789
|
-
mkdtemp as
|
|
28790
|
-
readdir as
|
|
28791
|
-
readFile as
|
|
29281
|
+
access as access12,
|
|
29282
|
+
mkdir as mkdir13,
|
|
29283
|
+
mkdtemp as mkdtemp9,
|
|
29284
|
+
readdir as readdir5,
|
|
29285
|
+
readFile as readFile16,
|
|
28792
29286
|
rename as rename12,
|
|
28793
|
-
rm as
|
|
29287
|
+
rm as rm12,
|
|
28794
29288
|
writeFile as writeFile13
|
|
28795
29289
|
} from "fs/promises";
|
|
28796
|
-
import { createHash as
|
|
28797
|
-
import { basename as
|
|
29290
|
+
import { createHash as createHash14 } from "crypto";
|
|
29291
|
+
import { basename as basename6, dirname as dirname12, join as join19, relative as relative12, resolve as resolve14, sep as sep8 } from "path";
|
|
28798
29292
|
|
|
28799
29293
|
// src/mobile/updateRuntime.ts
|
|
28800
29294
|
init_deviceCapabilities();
|
|
28801
29295
|
init_nativeAuth();
|
|
28802
|
-
import { createHash as
|
|
29296
|
+
import { createHash as createHash13 } from "crypto";
|
|
28803
29297
|
|
|
28804
29298
|
// src/mobile/updateProtocol.ts
|
|
28805
29299
|
var ABSOLUTE_MOBILE_UPDATE_FORMAT = 1;
|
|
@@ -28940,7 +29434,7 @@ var createAbsoluteMobileUpdateRuntimeDescriptor = (options) => ({
|
|
|
28940
29434
|
syncSchema: options.syncSchema ?? null,
|
|
28941
29435
|
updates: options.config.updates ?? null
|
|
28942
29436
|
});
|
|
28943
|
-
var fingerprintAbsoluteMobileUpdateRuntime = (descriptor) =>
|
|
29437
|
+
var fingerprintAbsoluteMobileUpdateRuntime = (descriptor) => createHash13("sha256").update(canonicalizeAbsoluteMobileUpdate(descriptor)).digest("hex");
|
|
28944
29438
|
var resolveAbsoluteMobileUpdateRuntime = (config, projectRoot) => {
|
|
28945
29439
|
const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
|
|
28946
29440
|
const sync = auth !== undefined && projectUsesAbsoluteSync(projectRoot);
|
|
@@ -28963,7 +29457,7 @@ var resolveAbsoluteMobileUpdateRuntime = (config, projectRoot) => {
|
|
|
28963
29457
|
};
|
|
28964
29458
|
|
|
28965
29459
|
// src/mobile/expoNativeObservability.ts
|
|
28966
|
-
import { join as
|
|
29460
|
+
import { join as join17 } from "path";
|
|
28967
29461
|
var HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
28968
29462
|
`;
|
|
28969
29463
|
var XML_HEADER = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
|
|
@@ -29405,31 +29899,31 @@ export const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: s
|
|
|
29405
29899
|
`;
|
|
29406
29900
|
var absoluteExpoNativeObservabilityFiles = (project) => new Map([
|
|
29407
29901
|
[
|
|
29408
|
-
|
|
29902
|
+
join17(project, "modules/absolute-mobile-observability/expo-module.config.json"),
|
|
29409
29903
|
moduleConfig
|
|
29410
29904
|
],
|
|
29411
29905
|
[
|
|
29412
|
-
|
|
29906
|
+
join17(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservability.podspec"),
|
|
29413
29907
|
podspec
|
|
29414
29908
|
],
|
|
29415
29909
|
[
|
|
29416
|
-
|
|
29910
|
+
join17(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservabilityModule.swift"),
|
|
29417
29911
|
iosModule
|
|
29418
29912
|
],
|
|
29419
29913
|
[
|
|
29420
|
-
|
|
29914
|
+
join17(project, "modules/absolute-mobile-observability/android/build.gradle"),
|
|
29421
29915
|
androidBuild
|
|
29422
29916
|
],
|
|
29423
29917
|
[
|
|
29424
|
-
|
|
29918
|
+
join17(project, "modules/absolute-mobile-observability/android/src/main/AndroidManifest.xml"),
|
|
29425
29919
|
androidManifest
|
|
29426
29920
|
],
|
|
29427
29921
|
[
|
|
29428
|
-
|
|
29922
|
+
join17(project, "modules/absolute-mobile-observability/android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"),
|
|
29429
29923
|
androidModule
|
|
29430
29924
|
],
|
|
29431
29925
|
[
|
|
29432
|
-
|
|
29926
|
+
join17(project, "src/generated/AbsoluteNativeObservability.ts"),
|
|
29433
29927
|
expoNativeObservabilityRuntimeSource
|
|
29434
29928
|
]
|
|
29435
29929
|
]);
|
|
@@ -29438,7 +29932,7 @@ var absoluteExpoNativeObservabilityPaths = (project) => [
|
|
|
29438
29932
|
];
|
|
29439
29933
|
|
|
29440
29934
|
// src/mobile/expoActivityResultRecovery.ts
|
|
29441
|
-
import { join as
|
|
29935
|
+
import { join as join18 } from "path";
|
|
29442
29936
|
var HEADER2 = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
29443
29937
|
`;
|
|
29444
29938
|
var XML_HEADER2 = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
|
|
@@ -29449,9 +29943,59 @@ var moduleConfig2 = `${JSON.stringify({
|
|
|
29449
29943
|
"expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryModule"
|
|
29450
29944
|
]
|
|
29451
29945
|
},
|
|
29452
|
-
|
|
29946
|
+
apple: { modules: ["AbsoluteActivityResultRecoveryModule"] },
|
|
29947
|
+
platforms: ["apple", "android"]
|
|
29453
29948
|
}, null, 2)}
|
|
29454
29949
|
`;
|
|
29950
|
+
var podspec2 = `${HEADER2}Pod::Spec.new do |s|
|
|
29951
|
+
s.name = 'AbsoluteActivityResultRecovery'
|
|
29952
|
+
s.version = '0.0.1'
|
|
29953
|
+
s.summary = 'AbsoluteJS native runtime readiness bridge'
|
|
29954
|
+
s.description = 'Generated lifecycle and embedded-content readiness bridge for an AbsoluteJS Expo application.'
|
|
29955
|
+
s.author = 'AbsoluteJS'
|
|
29956
|
+
s.homepage = 'https://absolutejs.com'
|
|
29957
|
+
s.platforms = { :ios => '16.4' }
|
|
29958
|
+
s.source = { git: '' }
|
|
29959
|
+
s.static_framework = true
|
|
29960
|
+
s.dependency 'ExpoModulesCore'
|
|
29961
|
+
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
|
29962
|
+
s.source_files = '**/*.{h,m,mm,swift,hpp,cpp}'
|
|
29963
|
+
end
|
|
29964
|
+
`;
|
|
29965
|
+
var iosModule2 = `${HEADER2}import ExpoModulesCore
|
|
29966
|
+
|
|
29967
|
+
public final class AbsoluteActivityResultRecoveryModule: Module {
|
|
29968
|
+
public func definition() -> ModuleDefinition {
|
|
29969
|
+
Name("AbsoluteActivityResultRecovery")
|
|
29970
|
+
|
|
29971
|
+
Function("markApplicationRuntimeReady") { }
|
|
29972
|
+
|
|
29973
|
+
Function("markEmbeddedWebReady") {
|
|
29974
|
+
let info = Bundle.main.infoDictionary ?? [:]
|
|
29975
|
+
let version = info["CFBundleShortVersionString"] as? String ?? "unknown"
|
|
29976
|
+
let build = info["CFBundleVersion"] as? String ?? "unknown"
|
|
29977
|
+
NSLog("AbsoluteJS: Expo embedded web content ready; version=%@; build=%@", version, build)
|
|
29978
|
+
}
|
|
29979
|
+
|
|
29980
|
+
Function("markEmbeddedWebPhase") { (phase: String) in
|
|
29981
|
+
let allowed = [
|
|
29982
|
+
"assets-start", "assets-ready", "assets-root-failed",
|
|
29983
|
+
"assets-directory-failed", "assets-destination-failed",
|
|
29984
|
+
"assets-module-failed", "assets-source-failed",
|
|
29985
|
+
"assets-download-failed", "assets-copy-failed",
|
|
29986
|
+
"assets-read-failed", "assets-write-failed",
|
|
29987
|
+
"assets-finalize-failed", "assets-unexpected-failed",
|
|
29988
|
+
"devices-start", "devices-ready", "devices-failed"
|
|
29989
|
+
]
|
|
29990
|
+
if allowed.contains(phase) {
|
|
29991
|
+
NSLog("AbsoluteJS: Expo embedded web phase: %@", phase)
|
|
29992
|
+
}
|
|
29993
|
+
}
|
|
29994
|
+
|
|
29995
|
+
Function("takePendingCancellation") { false }
|
|
29996
|
+
}
|
|
29997
|
+
}
|
|
29998
|
+
`;
|
|
29455
29999
|
var androidBuild2 = `${HEADER2}plugins {
|
|
29456
30000
|
id 'com.android.library'
|
|
29457
30001
|
id 'expo-module-gradle-plugin'
|
|
@@ -29625,23 +30169,31 @@ export const takeAbsoluteActivityResultCancellation = () =>
|
|
|
29625
30169
|
`;
|
|
29626
30170
|
var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
|
|
29627
30171
|
[
|
|
29628
|
-
|
|
30172
|
+
join18(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
|
|
29629
30173
|
moduleConfig2
|
|
29630
30174
|
],
|
|
29631
30175
|
[
|
|
29632
|
-
|
|
30176
|
+
join18(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecovery.podspec"),
|
|
30177
|
+
podspec2
|
|
30178
|
+
],
|
|
30179
|
+
[
|
|
30180
|
+
join18(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecoveryModule.swift"),
|
|
30181
|
+
iosModule2
|
|
30182
|
+
],
|
|
30183
|
+
[
|
|
30184
|
+
join18(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
|
|
29633
30185
|
androidBuild2
|
|
29634
30186
|
],
|
|
29635
30187
|
[
|
|
29636
|
-
|
|
30188
|
+
join18(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
|
|
29637
30189
|
androidManifest2
|
|
29638
30190
|
],
|
|
29639
30191
|
[
|
|
29640
|
-
|
|
30192
|
+
join18(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
|
|
29641
30193
|
androidModule2
|
|
29642
30194
|
],
|
|
29643
30195
|
[
|
|
29644
|
-
|
|
30196
|
+
join18(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
|
|
29645
30197
|
runtime
|
|
29646
30198
|
]
|
|
29647
30199
|
]);
|
|
@@ -29651,9 +30203,9 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
29651
30203
|
`;
|
|
29652
30204
|
var EXPO_ASSET_EXTENSION = ".absasset";
|
|
29653
30205
|
var EXPO_PROJECT_MARKER = ".absolutejs-expo-project";
|
|
29654
|
-
var
|
|
30206
|
+
var exists5 = async (path) => {
|
|
29655
30207
|
try {
|
|
29656
|
-
await
|
|
30208
|
+
await access12(path);
|
|
29657
30209
|
return true;
|
|
29658
30210
|
} catch {
|
|
29659
30211
|
return false;
|
|
@@ -29710,7 +30262,7 @@ var expoNativeDataManifest = (value) => {
|
|
|
29710
30262
|
};
|
|
29711
30263
|
};
|
|
29712
30264
|
var portableRelative2 = (from, destination) => {
|
|
29713
|
-
const value =
|
|
30265
|
+
const value = relative12(from, destination).replaceAll("\\", "/");
|
|
29714
30266
|
return value.startsWith(".") ? value : `./${value}`;
|
|
29715
30267
|
};
|
|
29716
30268
|
var routeSegments = (route) => {
|
|
@@ -29726,7 +30278,7 @@ var routeSegments = (route) => {
|
|
|
29726
30278
|
return segment;
|
|
29727
30279
|
});
|
|
29728
30280
|
};
|
|
29729
|
-
var routeFile = (project, route) =>
|
|
30281
|
+
var routeFile = (project, route) => join19(project, "app", ...routeSegments(route), "index.tsx");
|
|
29730
30282
|
var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
|
|
29731
30283
|
const separator = spec.lastIndexOf("@");
|
|
29732
30284
|
return [spec.slice(0, separator), spec.slice(separator + 1)];
|
|
@@ -30280,7 +30832,7 @@ ${push ? `absoluteExpoAuth.onPrincipalChange(principal => {
|
|
|
30280
30832
|
`;
|
|
30281
30833
|
};
|
|
30282
30834
|
var authRuntimeSource = (auth, appId) => {
|
|
30283
|
-
const storageIdentity =
|
|
30835
|
+
const storageIdentity = createHash14("sha256").update(appId).digest("hex").slice(0, 24);
|
|
30284
30836
|
return `${EXPO_GENERATED_HEADER}import { createAbsoluteExpoAuthClient } from '@absolutejs/auth-expo';
|
|
30285
30837
|
import { createMobileAuthTransport, installAuthClientRuntimeTransport } from '@absolutejs/auth/client/mobile';
|
|
30286
30838
|
|
|
@@ -30312,7 +30864,7 @@ export const startAbsoluteExpoAuth = () => {
|
|
|
30312
30864
|
`;
|
|
30313
30865
|
};
|
|
30314
30866
|
var syncRuntimeSource = (config, schema) => {
|
|
30315
|
-
const storageIdentity =
|
|
30867
|
+
const storageIdentity = createHash14("sha256").update(config.appId).digest("hex").slice(0, 24);
|
|
30316
30868
|
const backgroundEndpoint = new URL("/__absolute/sync/background", config.productionOrigin).href;
|
|
30317
30869
|
const backgroundTask = `${config.appId}.absolutejs.sync`;
|
|
30318
30870
|
return `${EXPO_GENERATED_HEADER}import { runHeadlessSync } from '@absolutejs/sync/client/headless';
|
|
@@ -30971,8 +31523,8 @@ const styles = StyleSheet.create({
|
|
|
30971
31523
|
error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
|
|
30972
31524
|
});
|
|
30973
31525
|
`;
|
|
30974
|
-
var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(
|
|
30975
|
-
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(
|
|
31526
|
+
var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname12(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
31527
|
+
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname12(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
30976
31528
|
|
|
30977
31529
|
export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
|
|
30978
31530
|
export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
|
|
@@ -31014,9 +31566,9 @@ var expoTsConfig = (projectRoot, project, auth, sync) => ({
|
|
|
31014
31566
|
extends: "expo/tsconfig.base"
|
|
31015
31567
|
});
|
|
31016
31568
|
var writeManagedFile = async (path, source, force) => {
|
|
31017
|
-
await
|
|
31018
|
-
if (await
|
|
31019
|
-
const current = await
|
|
31569
|
+
await mkdir13(dirname12(path), { recursive: true });
|
|
31570
|
+
if (await exists5(path)) {
|
|
31571
|
+
const current = await readFile16(path, "utf8");
|
|
31020
31572
|
if (current === source)
|
|
31021
31573
|
return false;
|
|
31022
31574
|
if (!force && !current.startsWith(EXPO_GENERATED_HEADER)) {
|
|
@@ -31030,26 +31582,26 @@ var writeManagedFile = async (path, source, force) => {
|
|
|
31030
31582
|
};
|
|
31031
31583
|
var pruneManagedFiles = async (paths) => {
|
|
31032
31584
|
const removed = await Promise.all(paths.map(async (path) => {
|
|
31033
|
-
if (!await
|
|
31585
|
+
if (!await exists5(path))
|
|
31034
31586
|
return false;
|
|
31035
|
-
const source = await
|
|
31587
|
+
const source = await readFile16(path, "utf8");
|
|
31036
31588
|
if (!source.startsWith(EXPO_GENERATED_HEADER) && !path.endsWith("expo-module.config.json"))
|
|
31037
31589
|
return false;
|
|
31038
|
-
await
|
|
31590
|
+
await rm12(path, { force: true });
|
|
31039
31591
|
return true;
|
|
31040
31592
|
}));
|
|
31041
31593
|
return removed.filter(Boolean).length;
|
|
31042
31594
|
};
|
|
31043
31595
|
var pruneStaleManagedExpoRoutes = async (project, expected) => {
|
|
31044
|
-
const appDirectory =
|
|
31045
|
-
if (!await
|
|
31596
|
+
const appDirectory = join19(project, "app");
|
|
31597
|
+
if (!await exists5(appDirectory))
|
|
31046
31598
|
return 0;
|
|
31047
31599
|
const files = await walkFiles(appDirectory);
|
|
31048
31600
|
const stale = (await Promise.all(files.map(async (path) => ({
|
|
31049
|
-
managed: path.endsWith(".tsx") && (await
|
|
31601
|
+
managed: path.endsWith(".tsx") && (await readFile16(path, "utf8")).startsWith(EXPO_GENERATED_HEADER),
|
|
31050
31602
|
path
|
|
31051
31603
|
})))).filter(({ managed, path }) => managed && !expected.has(path));
|
|
31052
|
-
await Promise.all(stale.map(({ path }) =>
|
|
31604
|
+
await Promise.all(stale.map(({ path }) => rm12(path, { force: true })));
|
|
31053
31605
|
return stale.length;
|
|
31054
31606
|
};
|
|
31055
31607
|
var jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
|
|
@@ -31072,7 +31624,7 @@ export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest | undefined = unde
|
|
|
31072
31624
|
var writeAbsoluteExpoProject = async (config, options) => {
|
|
31073
31625
|
if (config.engine !== "expo")
|
|
31074
31626
|
throw new TypeError("Expo project generation requires mobile.engine: expo.");
|
|
31075
|
-
const projectRoot =
|
|
31627
|
+
const projectRoot = resolve14(options.projectRoot);
|
|
31076
31628
|
const project = config.nativeProjectDirectory;
|
|
31077
31629
|
const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
|
|
31078
31630
|
const devices = resolveAbsoluteDeviceCapabilityPlan(projectRoot, "expo");
|
|
@@ -31081,7 +31633,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
|
|
|
31081
31633
|
const runtimeFingerprint = resolveAbsoluteMobileUpdateRuntime(config, projectRoot).fingerprint;
|
|
31082
31634
|
const routeModules = Object.entries(config.expoNativeRoutes);
|
|
31083
31635
|
const moduleChecks = await Promise.all(routeModules.map(async ([route, module]) => ({
|
|
31084
|
-
exists: await
|
|
31636
|
+
exists: await exists5(module),
|
|
31085
31637
|
module,
|
|
31086
31638
|
route
|
|
31087
31639
|
})));
|
|
@@ -31089,20 +31641,20 @@ var writeAbsoluteExpoProject = async (config, options) => {
|
|
|
31089
31641
|
if (missing) {
|
|
31090
31642
|
throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
|
|
31091
31643
|
}
|
|
31092
|
-
const marker =
|
|
31093
|
-
if (await
|
|
31094
|
-
const entries = await
|
|
31644
|
+
const marker = join19(project, EXPO_PROJECT_MARKER);
|
|
31645
|
+
if (await exists5(project) && !await exists5(marker)) {
|
|
31646
|
+
const entries = await readdir5(project);
|
|
31095
31647
|
if (entries.length > 0 && !options.force) {
|
|
31096
31648
|
throw new TypeError(`Expo project directory ${project} is not AbsoluteJS-managed; rerun with --force only after reviewing it.`);
|
|
31097
31649
|
}
|
|
31098
31650
|
}
|
|
31099
|
-
await
|
|
31651
|
+
await mkdir13(project, { recursive: true });
|
|
31100
31652
|
await writeFile13(marker, `format=1
|
|
31101
31653
|
`);
|
|
31102
31654
|
const authEnabled = Boolean(auth);
|
|
31103
31655
|
const files = new Map([
|
|
31104
31656
|
[
|
|
31105
|
-
|
|
31657
|
+
join19(project, ".gitignore"),
|
|
31106
31658
|
`.expo/
|
|
31107
31659
|
android/
|
|
31108
31660
|
ios/
|
|
@@ -31110,45 +31662,45 @@ node_modules/
|
|
|
31110
31662
|
`
|
|
31111
31663
|
],
|
|
31112
31664
|
[
|
|
31113
|
-
|
|
31665
|
+
join19(project, "app.json"),
|
|
31114
31666
|
jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
|
|
31115
31667
|
],
|
|
31116
|
-
[
|
|
31668
|
+
[join19(project, "app.config.js"), expoDynamicAppConfig],
|
|
31117
31669
|
[
|
|
31118
|
-
|
|
31670
|
+
join19(project, "package.json"),
|
|
31119
31671
|
jsonSource(expoPackage(authEnabled, syncEnabled, devices, config.updates !== undefined))
|
|
31120
31672
|
],
|
|
31121
|
-
[
|
|
31673
|
+
[join19(project, "metro.config.js"), metroConfig(projectRoot)],
|
|
31122
31674
|
[
|
|
31123
|
-
|
|
31675
|
+
join19(project, "plugins", "withAbsoluteDevelopmentCa.js"),
|
|
31124
31676
|
expoDevelopmentCaPlugin
|
|
31125
31677
|
],
|
|
31126
31678
|
[
|
|
31127
|
-
|
|
31679
|
+
join19(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
|
|
31128
31680
|
expoActivityResultRecoveryPlugin
|
|
31129
31681
|
],
|
|
31130
31682
|
[
|
|
31131
|
-
|
|
31683
|
+
join19(project, "tsconfig.json"),
|
|
31132
31684
|
jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
|
|
31133
31685
|
],
|
|
31134
31686
|
[
|
|
31135
|
-
|
|
31687
|
+
join19(project, "app", "_layout.tsx"),
|
|
31136
31688
|
layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
|
|
31137
31689
|
],
|
|
31138
31690
|
[
|
|
31139
|
-
|
|
31691
|
+
join19(project, "app", "__absolute", "native", "index.tsx"),
|
|
31140
31692
|
nativeDiagnosticSource
|
|
31141
31693
|
],
|
|
31142
31694
|
[
|
|
31143
|
-
|
|
31695
|
+
join19(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
31144
31696
|
devicesRuntimeSource(config, devices, authEnabled)
|
|
31145
31697
|
],
|
|
31146
31698
|
[
|
|
31147
|
-
|
|
31699
|
+
join19(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
|
|
31148
31700
|
nativeRouteRuntimeSource(authEnabled)
|
|
31149
31701
|
],
|
|
31150
31702
|
[
|
|
31151
|
-
|
|
31703
|
+
join19(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
31152
31704
|
webHostSource(config, auth, syncEnabled)
|
|
31153
31705
|
]
|
|
31154
31706
|
]);
|
|
@@ -31159,40 +31711,40 @@ node_modules/
|
|
|
31159
31711
|
files.set(path, source);
|
|
31160
31712
|
}
|
|
31161
31713
|
if (config.updates) {
|
|
31162
|
-
files.set(
|
|
31714
|
+
files.set(join19(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
|
|
31163
31715
|
}
|
|
31164
31716
|
const expoCodeSigning = config.updates?.expoCodeSigning;
|
|
31165
31717
|
if (expoCodeSigning)
|
|
31166
|
-
files.set(
|
|
31718
|
+
files.set(join19(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
|
|
31167
31719
|
if (auth) {
|
|
31168
|
-
files.set(
|
|
31720
|
+
files.set(join19(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
|
|
31169
31721
|
}
|
|
31170
31722
|
if (syncSchema) {
|
|
31171
|
-
files.set(
|
|
31723
|
+
files.set(join19(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
|
|
31172
31724
|
}
|
|
31173
|
-
const webAssetsPath =
|
|
31174
|
-
if (!await
|
|
31725
|
+
const webAssetsPath = join19(project, "src", "generated", "webAssets.ts");
|
|
31726
|
+
if (!await exists5(webAssetsPath)) {
|
|
31175
31727
|
files.set(webAssetsPath, emptyWebAssetsSource);
|
|
31176
31728
|
}
|
|
31177
31729
|
if (!config.expoNativeRoutes["/"]) {
|
|
31178
|
-
files.set(
|
|
31730
|
+
files.set(join19(project, "app", "index.tsx"), webRouteSource);
|
|
31179
31731
|
}
|
|
31180
|
-
files.set(
|
|
31181
|
-
const nativeRouteRuntime =
|
|
31732
|
+
files.set(join19(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
31733
|
+
const nativeRouteRuntime = join19(project, "src", "generated", "AbsoluteNativeRoute.tsx");
|
|
31182
31734
|
for (const [route, module] of routeModules) {
|
|
31183
|
-
const wrapper = route === "/" ?
|
|
31735
|
+
const wrapper = route === "/" ? join19(project, "app", "index.tsx") : routeFile(project, route);
|
|
31184
31736
|
files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
|
|
31185
31737
|
}
|
|
31186
|
-
const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${
|
|
31738
|
+
const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join19(project, "app")}${sep8}`))));
|
|
31187
31739
|
const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
|
|
31188
31740
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
31189
31741
|
const changed = removedRoutes + removedObservability + changes.filter(Boolean).length;
|
|
31190
31742
|
return { changed, path: project, written: [...files.keys()] };
|
|
31191
31743
|
};
|
|
31192
31744
|
var walkFiles = async (root, directory = root) => {
|
|
31193
|
-
const entries = await
|
|
31745
|
+
const entries = await readdir5(directory, { withFileTypes: true });
|
|
31194
31746
|
const nested = await Promise.all(entries.map((entry) => {
|
|
31195
|
-
const path =
|
|
31747
|
+
const path = join19(directory, entry.name);
|
|
31196
31748
|
if (entry.isDirectory())
|
|
31197
31749
|
return walkFiles(root, path);
|
|
31198
31750
|
if (entry.isFile())
|
|
@@ -31218,7 +31770,7 @@ var installStagedDirectory = async (staging, destination) => {
|
|
|
31218
31770
|
try {
|
|
31219
31771
|
await rename12(staging, destination);
|
|
31220
31772
|
if (moved)
|
|
31221
|
-
await
|
|
31773
|
+
await rm12(backup, { force: true, recursive: true });
|
|
31222
31774
|
} catch (error) {
|
|
31223
31775
|
if (moved)
|
|
31224
31776
|
await rename12(backup, destination);
|
|
@@ -31296,27 +31848,27 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
31296
31848
|
var syncAbsoluteExpoWebAssets = async (config) => {
|
|
31297
31849
|
if (config.engine !== "expo")
|
|
31298
31850
|
throw new TypeError("Expo asset sync requires mobile.engine: expo.");
|
|
31299
|
-
const marker =
|
|
31300
|
-
if (!await
|
|
31851
|
+
const marker = join19(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
|
|
31852
|
+
if (!await exists5(marker)) {
|
|
31301
31853
|
throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
|
|
31302
31854
|
}
|
|
31303
|
-
const manifestPath =
|
|
31304
|
-
const manifest = JSON.parse(await
|
|
31855
|
+
const manifestPath = join19(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
31856
|
+
const manifest = JSON.parse(await readFile16(manifestPath, "utf8"));
|
|
31305
31857
|
const nativeDataManifest = expoNativeDataManifest(manifest);
|
|
31306
31858
|
const { appBuild } = nativeDataManifest;
|
|
31307
31859
|
const files = await walkFiles(config.bundleDirectory);
|
|
31308
|
-
const bundleHash =
|
|
31309
|
-
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await
|
|
31860
|
+
const bundleHash = createHash14("sha256");
|
|
31861
|
+
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile16(file), file })));
|
|
31310
31862
|
filesWithContents.forEach(({ contents, file }) => {
|
|
31311
|
-
bundleHash.update(
|
|
31863
|
+
bundleHash.update(relative12(config.bundleDirectory, file).replaceAll("\\", "/"));
|
|
31312
31864
|
bundleHash.update("\x00");
|
|
31313
31865
|
bundleHash.update(contents);
|
|
31314
31866
|
bundleHash.update("\x00");
|
|
31315
31867
|
});
|
|
31316
31868
|
const bundleId = `amexpo_${bundleHash.digest("hex")}`;
|
|
31317
|
-
const destination =
|
|
31318
|
-
await
|
|
31319
|
-
const staging = await
|
|
31869
|
+
const destination = join19(config.nativeProjectDirectory, "assets", "absolute");
|
|
31870
|
+
await mkdir13(dirname12(destination), { recursive: true });
|
|
31871
|
+
const staging = await mkdtemp9(join19(dirname12(destination), `.${basename6(destination)}.stage-`));
|
|
31320
31872
|
let assets;
|
|
31321
31873
|
let archiveAsset;
|
|
31322
31874
|
try {
|
|
@@ -31325,20 +31877,20 @@ var syncAbsoluteExpoWebAssets = async (config) => {
|
|
|
31325
31877
|
const entry = {
|
|
31326
31878
|
length: contents.byteLength,
|
|
31327
31879
|
offset,
|
|
31328
|
-
path:
|
|
31880
|
+
path: relative12(config.bundleDirectory, file).replaceAll("\\", "/")
|
|
31329
31881
|
};
|
|
31330
31882
|
offset += contents.byteLength;
|
|
31331
31883
|
return entry;
|
|
31332
31884
|
});
|
|
31333
31885
|
const name = `bundle${EXPO_ASSET_EXTENSION}`;
|
|
31334
|
-
await writeFile13(
|
|
31335
|
-
archiveAsset = portableRelative2(
|
|
31886
|
+
await writeFile13(join19(staging, name), Buffer.concat(filesWithContents.map(({ contents }) => contents)));
|
|
31887
|
+
archiveAsset = portableRelative2(join19(config.nativeProjectDirectory, "src", "generated"), join19(destination, name));
|
|
31336
31888
|
await installStagedDirectory(staging, destination);
|
|
31337
31889
|
} catch (error) {
|
|
31338
|
-
await
|
|
31890
|
+
await rm12(staging, { force: true, recursive: true });
|
|
31339
31891
|
throw error;
|
|
31340
31892
|
}
|
|
31341
|
-
const generated =
|
|
31893
|
+
const generated = join19(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
31342
31894
|
await writeManagedFile(generated, assetModuleSource(assets, archiveAsset, bundleId, nativeDataManifest), true);
|
|
31343
31895
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
31344
31896
|
};
|
|
@@ -31377,11 +31929,11 @@ var loadServerApp = async (producerPath) => {
|
|
|
31377
31929
|
return { app, exportName };
|
|
31378
31930
|
};
|
|
31379
31931
|
var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
31380
|
-
const buildDirectory =
|
|
31932
|
+
const buildDirectory = resolve15(options.buildDirectory);
|
|
31381
31933
|
const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
|
|
31382
|
-
const root =
|
|
31934
|
+
const root = join20(buildDirectory, ".absolutejs", "mobile-compatibility");
|
|
31383
31935
|
const [manifestSource, previous] = await Promise.all([
|
|
31384
|
-
|
|
31936
|
+
readFile17(join20(buildDirectory, "manifest.json"), "utf8"),
|
|
31385
31937
|
readAbsoluteMobileMaterializedReleases(root)
|
|
31386
31938
|
]);
|
|
31387
31939
|
const manifest = JSON.parse(manifestSource);
|
|
@@ -31394,11 +31946,11 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
|
31394
31946
|
process.env.ABSOLUTE_BUILD_DIR = buildDirectory;
|
|
31395
31947
|
process.env.ABSOLUTE_COMPILED_RUNTIME = "1";
|
|
31396
31948
|
if (options.configPath) {
|
|
31397
|
-
process.env.ABSOLUTE_CONFIG =
|
|
31949
|
+
process.env.ABSOLUTE_CONFIG = resolve15(options.projectRoot, options.configPath);
|
|
31398
31950
|
}
|
|
31399
31951
|
let loaded;
|
|
31400
31952
|
try {
|
|
31401
|
-
loaded = await loadServerApp(
|
|
31953
|
+
loaded = await loadServerApp(resolve15(options.producerPath));
|
|
31402
31954
|
} finally {
|
|
31403
31955
|
restoreEnvironmentVariable("ABSOLUTE_BUILD_DIR", previousBuildDirectory);
|
|
31404
31956
|
restoreEnvironmentVariable("ABSOLUTE_COMPILED_RUNTIME", previousCompiledRuntime);
|
|
@@ -31411,7 +31963,7 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
|
31411
31963
|
manifest,
|
|
31412
31964
|
previousArtifacts: previous.map(({ artifact }) => artifact),
|
|
31413
31965
|
producerExport: loaded.exportName,
|
|
31414
|
-
producerPath:
|
|
31966
|
+
producerPath: resolve15(options.producerPath),
|
|
31415
31967
|
runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
|
|
31416
31968
|
});
|
|
31417
31969
|
const {
|
|
@@ -31810,21 +32362,21 @@ var parseAbsoluteExpoBridgeMessage = (source) => {
|
|
|
31810
32362
|
};
|
|
31811
32363
|
// src/mobile/expoCodeSigning.ts
|
|
31812
32364
|
var import_code_signing_certificates = __toESM(require_main(), 1);
|
|
31813
|
-
import { access as
|
|
31814
|
-
import { dirname as
|
|
31815
|
-
var
|
|
31816
|
-
var
|
|
31817
|
-
const location2 =
|
|
31818
|
-
return location2 === "" || location2 !== ".." && !location2.startsWith(`..${
|
|
32365
|
+
import { access as access13, mkdir as mkdir14, writeFile as writeFile14 } from "fs/promises";
|
|
32366
|
+
import { dirname as dirname13, isAbsolute as isAbsolute8, relative as relative13, resolve as resolve16, sep as sep9 } from "path";
|
|
32367
|
+
var exists6 = async (path) => access13(path).then(() => true).catch(() => false);
|
|
32368
|
+
var inside3 = (root, path) => {
|
|
32369
|
+
const location2 = relative13(root, path);
|
|
32370
|
+
return location2 === "" || location2 !== ".." && !location2.startsWith(`..${sep9}`) && !isAbsolute8(location2);
|
|
31819
32371
|
};
|
|
31820
32372
|
var generateAbsoluteExpoCodeSigning = async (options) => {
|
|
31821
|
-
const root =
|
|
31822
|
-
const certificatePath =
|
|
31823
|
-
const privateKeyPath =
|
|
31824
|
-
const publicKeyPath =
|
|
31825
|
-
if (!
|
|
32373
|
+
const root = resolve16(options.projectRoot);
|
|
32374
|
+
const certificatePath = resolve16(root, options.certificatePath);
|
|
32375
|
+
const privateKeyPath = resolve16(root, options.privateKeyPath);
|
|
32376
|
+
const publicKeyPath = resolve16(root, options.publicKeyPath ?? resolve16(dirname13(privateKeyPath), "public-key.pem"));
|
|
32377
|
+
if (!inside3(root, certificatePath))
|
|
31826
32378
|
throw new TypeError("Expo code-signing certificate must be written inside the project so store builds can embed it.");
|
|
31827
|
-
if (
|
|
32379
|
+
if (inside3(root, privateKeyPath) || inside3(root, publicKeyPath))
|
|
31828
32380
|
throw new TypeError("Expo code-signing private/public key output must remain outside the project and source control.");
|
|
31829
32381
|
const commonName = options.commonName.trim();
|
|
31830
32382
|
if (!commonName || commonName.length > 64)
|
|
@@ -31833,7 +32385,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
|
|
|
31833
32385
|
if (!Number.isSafeInteger(validityYears) || validityYears < 1 || validityYears > 20)
|
|
31834
32386
|
throw new TypeError("Expo code-signing validity must be an integer from 1 through 20 years.");
|
|
31835
32387
|
const collisions = (await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map(async (path) => ({
|
|
31836
|
-
exists: await
|
|
32388
|
+
exists: await exists6(path),
|
|
31837
32389
|
path
|
|
31838
32390
|
})))).filter((entry) => entry.exists);
|
|
31839
32391
|
if (collisions.length > 0)
|
|
@@ -31851,7 +32403,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
|
|
|
31851
32403
|
import_code_signing_certificates.validateSelfSignedCertificate(certificate, keyPair);
|
|
31852
32404
|
const { privateKeyPEM, publicKeyPEM } = import_code_signing_certificates.convertKeyPairToPEM(keyPair);
|
|
31853
32405
|
const certificatePem = import_code_signing_certificates.convertCertificateToCertificatePEM(certificate);
|
|
31854
|
-
await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map((path) =>
|
|
32406
|
+
await Promise.all([certificatePath, privateKeyPath, publicKeyPath].map((path) => mkdir14(dirname13(path), { recursive: true })));
|
|
31855
32407
|
await Promise.all([
|
|
31856
32408
|
writeFile14(certificatePath, certificatePem, { flag: "wx", mode: 420 }),
|
|
31857
32409
|
writeFile14(privateKeyPath, privateKeyPEM, { flag: "wx", mode: 384 }),
|
|
@@ -31957,9 +32509,9 @@ var parseAbsoluteAndroidAccessibilityHierarchy = (source) => [...source.matchAll
|
|
|
31957
32509
|
});
|
|
31958
32510
|
// src/mobile/expoNativeWatcher.ts
|
|
31959
32511
|
import { watch as watch2 } from "fs";
|
|
31960
|
-
import { access as
|
|
31961
|
-
import { basename as
|
|
31962
|
-
import { createHash as
|
|
32512
|
+
import { access as access14, readdir as readdir6, readFile as readFile18 } from "fs/promises";
|
|
32513
|
+
import { basename as basename7, join as join21, relative as relative14 } from "path";
|
|
32514
|
+
import { createHash as createHash15 } from "crypto";
|
|
31963
32515
|
var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
|
|
31964
32516
|
var ROOT_NATIVE_INPUTS2 = new Set([
|
|
31965
32517
|
"absolute.config.js",
|
|
@@ -31973,13 +32525,13 @@ var ROOT_NATIVE_INPUTS2 = new Set([
|
|
|
31973
32525
|
"package.json"
|
|
31974
32526
|
]);
|
|
31975
32527
|
var EXPO_NATIVE_DIRECTORIES = ["modules", "plugins"];
|
|
31976
|
-
var
|
|
32528
|
+
var exists7 = async (path) => access14(path).then(() => true, () => false);
|
|
31977
32529
|
var filesIn = async (directory, prefix) => {
|
|
31978
|
-
if (!await
|
|
32530
|
+
if (!await exists7(directory))
|
|
31979
32531
|
return [];
|
|
31980
|
-
const entries = await
|
|
32532
|
+
const entries = await readdir6(directory, { withFileTypes: true });
|
|
31981
32533
|
const nested = await Promise.all(entries.map((entry) => {
|
|
31982
|
-
const path =
|
|
32534
|
+
const path = join21(directory, entry.name);
|
|
31983
32535
|
const name = `${prefix}/${entry.name}`;
|
|
31984
32536
|
if (entry.isDirectory())
|
|
31985
32537
|
return filesIn(path, name);
|
|
@@ -31988,21 +32540,21 @@ var filesIn = async (directory, prefix) => {
|
|
|
31988
32540
|
return nested.flat().sort((left, right) => left.name.localeCompare(right.name));
|
|
31989
32541
|
};
|
|
31990
32542
|
var fingerprintAbsoluteExpoNativeInputs = async (options) => {
|
|
31991
|
-
const hash =
|
|
32543
|
+
const hash = createHash15("sha256");
|
|
31992
32544
|
const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
|
|
31993
|
-
const path =
|
|
31994
|
-
return await
|
|
32545
|
+
const path = join21(options.projectRoot, name);
|
|
32546
|
+
return await exists7(path) ? [{ name: `root/${name}`, path }] : [];
|
|
31995
32547
|
}));
|
|
31996
|
-
const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(
|
|
32548
|
+
const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join21(options.expoProjectDirectory, name), name)));
|
|
31997
32549
|
const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
|
|
31998
|
-
const contents = await Promise.all(files.map(({ path }) =>
|
|
32550
|
+
const contents = await Promise.all(files.map(({ path }) => readFile18(path)));
|
|
31999
32551
|
files.forEach(({ name }, index) => {
|
|
32000
32552
|
hash.update(name);
|
|
32001
32553
|
hash.update(contents[index] ?? Buffer.alloc(0));
|
|
32002
32554
|
});
|
|
32003
32555
|
return hash.digest("hex");
|
|
32004
32556
|
};
|
|
32005
|
-
var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(
|
|
32557
|
+
var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename7(path));
|
|
32006
32558
|
var createAbsoluteExpoNativeWatcher = async (options) => {
|
|
32007
32559
|
let fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
32008
32560
|
let closed = false;
|
|
@@ -32064,14 +32616,14 @@ var createAbsoluteExpoNativeWatcher = async (options) => {
|
|
|
32064
32616
|
}
|
|
32065
32617
|
};
|
|
32066
32618
|
const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
|
|
32067
|
-
const directory =
|
|
32068
|
-
return await
|
|
32619
|
+
const directory = join21(options.expoProjectDirectory, name);
|
|
32620
|
+
return await exists7(directory) ? [directory] : [];
|
|
32069
32621
|
}))).flat();
|
|
32070
32622
|
nativeDirectories.forEach((directory) => {
|
|
32071
32623
|
watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
|
|
32072
32624
|
if (!filename)
|
|
32073
32625
|
return;
|
|
32074
|
-
record(
|
|
32626
|
+
record(relative14(options.expoProjectDirectory, join21(directory, String(filename))), false);
|
|
32075
32627
|
}));
|
|
32076
32628
|
});
|
|
32077
32629
|
watchers.push(watch2(options.projectRoot, (_event, filename) => {
|
|
@@ -32086,8 +32638,8 @@ var createAbsoluteExpoNativeWatcher = async (options) => {
|
|
|
32086
32638
|
return { close };
|
|
32087
32639
|
};
|
|
32088
32640
|
// src/mobile/expoUpdate.ts
|
|
32089
|
-
import { access as
|
|
32090
|
-
import { dirname as
|
|
32641
|
+
import { access as access15, mkdir as mkdir15, readFile as readFile19, writeFile as writeFile15 } from "fs/promises";
|
|
32642
|
+
import { dirname as dirname14, extname as extname4, join as join22 } from "path";
|
|
32091
32643
|
var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
|
|
32092
32644
|
var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
|
|
32093
32645
|
var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -32153,7 +32705,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
|
|
|
32153
32705
|
};
|
|
32154
32706
|
};
|
|
32155
32707
|
var finalizeAbsoluteExpoUpdateExport = async (options) => {
|
|
32156
|
-
const metadata = JSON.parse(await
|
|
32708
|
+
const metadata = JSON.parse(await readFile19(join22(options.exportDirectory, "metadata.json"), "utf8"));
|
|
32157
32709
|
if (!object4(metadata) || !object4(metadata.fileMetadata))
|
|
32158
32710
|
throw new TypeError("Expo export metadata.json is invalid.");
|
|
32159
32711
|
const descriptor = parseAbsoluteExpoUpdateDescriptor({
|
|
@@ -32164,11 +32716,11 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
|
|
|
32164
32716
|
runtimeVersion: options.runtimeVersion
|
|
32165
32717
|
});
|
|
32166
32718
|
const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
|
|
32167
|
-
await Promise.all(referenced.map(({ path }) =>
|
|
32719
|
+
await Promise.all(referenced.map(({ path }) => access15(join22(options.exportDirectory, path)).catch(() => {
|
|
32168
32720
|
throw new TypeError(`Expo export metadata references missing asset ${path}.`);
|
|
32169
32721
|
})));
|
|
32170
|
-
const destination =
|
|
32171
|
-
await
|
|
32722
|
+
const destination = join22(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
|
|
32723
|
+
await mkdir15(dirname14(destination), { recursive: true });
|
|
32172
32724
|
await writeFile15(destination, `${JSON.stringify(descriptor, null, "\t")}
|
|
32173
32725
|
`);
|
|
32174
32726
|
return { descriptor, path: destination };
|
|
@@ -32179,8 +32731,8 @@ init_config();
|
|
|
32179
32731
|
|
|
32180
32732
|
// src/mobile/ciWorkflow.ts
|
|
32181
32733
|
import { existsSync as existsSync4 } from "fs";
|
|
32182
|
-
import { access as
|
|
32183
|
-
import { dirname as
|
|
32734
|
+
import { access as access16, mkdir as mkdir16, readFile as readFile20, writeFile as writeFile16 } from "fs/promises";
|
|
32735
|
+
import { dirname as dirname15, extname as extname5, relative as relative15, resolve as resolve17, sep as sep10 } from "path";
|
|
32184
32736
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
|
|
32185
32737
|
var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
|
|
32186
32738
|
var CI_ENV_INDENTATION = 6;
|
|
@@ -32199,9 +32751,9 @@ var RESERVED_SECRET_NAMES = new Set([
|
|
|
32199
32751
|
"APP_STORE_CONNECT_KEY_ID",
|
|
32200
32752
|
"APP_STORE_CONNECT_PRIVATE_KEY_BASE64"
|
|
32201
32753
|
]);
|
|
32202
|
-
var
|
|
32754
|
+
var exists8 = async (path) => {
|
|
32203
32755
|
try {
|
|
32204
|
-
await
|
|
32756
|
+
await access16(path);
|
|
32205
32757
|
return true;
|
|
32206
32758
|
} catch {
|
|
32207
32759
|
return false;
|
|
@@ -32209,10 +32761,10 @@ var exists7 = async (path) => {
|
|
|
32209
32761
|
};
|
|
32210
32762
|
var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
|
|
32211
32763
|
var projectPath = (projectRoot, value, field2, options = {}) => {
|
|
32212
|
-
const root =
|
|
32213
|
-
const path =
|
|
32214
|
-
const portable =
|
|
32215
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
32764
|
+
const root = resolve17(projectRoot);
|
|
32765
|
+
const path = resolve17(root, value);
|
|
32766
|
+
const portable = relative15(root, path).replaceAll("\\", "/");
|
|
32767
|
+
if (portable === ".." || portable.startsWith(`..${sep10}`) || portable.startsWith("../") || portable === "") {
|
|
32216
32768
|
throw new TypeError(`${field2} must remain inside the project root.`);
|
|
32217
32769
|
}
|
|
32218
32770
|
if (/\r|\n/u.test(portable) || portable.startsWith("-"))
|
|
@@ -32222,11 +32774,11 @@ var projectPath = (projectRoot, value, field2, options = {}) => {
|
|
|
32222
32774
|
return portable;
|
|
32223
32775
|
};
|
|
32224
32776
|
var workflowOutputPath = (projectRoot, value) => {
|
|
32225
|
-
const root =
|
|
32226
|
-
const workflows =
|
|
32227
|
-
const path =
|
|
32228
|
-
const portable =
|
|
32229
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
32777
|
+
const root = resolve17(projectRoot);
|
|
32778
|
+
const workflows = resolve17(root, ".github/workflows");
|
|
32779
|
+
const path = resolve17(root, value ?? ".github/workflows/absolute-mobile.yml");
|
|
32780
|
+
const portable = relative15(workflows, path);
|
|
32781
|
+
if (portable === ".." || portable.startsWith(`..${sep10}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
|
|
32230
32782
|
throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
|
|
32231
32783
|
}
|
|
32232
32784
|
return path;
|
|
@@ -32655,11 +33207,11 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
|
|
|
32655
33207
|
var writeAbsoluteMobileGithubWorkflow = async (options) => {
|
|
32656
33208
|
const path = workflowOutputPath(options.projectRoot, options.outputPath);
|
|
32657
33209
|
const generated = createAbsoluteMobileGithubWorkflow(options);
|
|
32658
|
-
const previous = await
|
|
33210
|
+
const previous = await exists8(path) ? await readFile20(path, "utf8") : undefined;
|
|
32659
33211
|
if (previous !== undefined && previous !== generated.workflow && !options.force)
|
|
32660
|
-
throw new TypeError(`${
|
|
33212
|
+
throw new TypeError(`${relative15(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
|
|
32661
33213
|
if (previous !== generated.workflow) {
|
|
32662
|
-
await
|
|
33214
|
+
await mkdir16(dirname15(path), { recursive: true });
|
|
32663
33215
|
await writeFile16(path, generated.workflow);
|
|
32664
33216
|
}
|
|
32665
33217
|
return {
|
|
@@ -32678,15 +33230,15 @@ init_materializedBundle();
|
|
|
32678
33230
|
init_mobilePreview();
|
|
32679
33231
|
|
|
32680
33232
|
// src/mobile/nativeDeepLinks.ts
|
|
32681
|
-
import { readFile as
|
|
32682
|
-
import { join as
|
|
33233
|
+
import { readFile as readFile21, rename as rename13, writeFile as writeFile17 } from "fs/promises";
|
|
33234
|
+
import { join as join25 } from "path";
|
|
32683
33235
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
32684
33236
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
32685
33237
|
var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
32686
33238
|
var NOT_FOUND = -1;
|
|
32687
33239
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
32688
33240
|
var writeChangedFile = async (path, source) => {
|
|
32689
|
-
const current = await
|
|
33241
|
+
const current = await readFile21(path, "utf8");
|
|
32690
33242
|
if (current === source)
|
|
32691
33243
|
return false;
|
|
32692
33244
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -32736,8 +33288,8 @@ ${hosts}
|
|
|
32736
33288
|
`;
|
|
32737
33289
|
};
|
|
32738
33290
|
var configureAndroid = async (config) => {
|
|
32739
|
-
const path =
|
|
32740
|
-
const source = await
|
|
33291
|
+
const path = join25(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
33292
|
+
const source = await readFile21(path, "utf8");
|
|
32741
33293
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
32742
33294
|
if (mainActivity === NOT_FOUND) {
|
|
32743
33295
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -32762,8 +33314,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
32762
33314
|
${END_MARKER}
|
|
32763
33315
|
`;
|
|
32764
33316
|
var configureIosInfo = async (config) => {
|
|
32765
|
-
const path =
|
|
32766
|
-
const source = await
|
|
33317
|
+
const path = join25(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
33318
|
+
const source = await readFile21(path, "utf8");
|
|
32767
33319
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
32768
33320
|
${END_MARKER}
|
|
32769
33321
|
`;
|
|
@@ -32786,10 +33338,10 @@ ${domains}
|
|
|
32786
33338
|
`;
|
|
32787
33339
|
};
|
|
32788
33340
|
var configureIosEntitlements = async (config) => {
|
|
32789
|
-
const path =
|
|
33341
|
+
const path = join25(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
32790
33342
|
let current = "";
|
|
32791
33343
|
try {
|
|
32792
|
-
current = await
|
|
33344
|
+
current = await readFile21(path, "utf8");
|
|
32793
33345
|
} catch (error) {
|
|
32794
33346
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
32795
33347
|
throw error;
|
|
@@ -32804,8 +33356,8 @@ var configureIosEntitlements = async (config) => {
|
|
|
32804
33356
|
return true;
|
|
32805
33357
|
};
|
|
32806
33358
|
var configureIosProject = async (config) => {
|
|
32807
|
-
const path =
|
|
32808
|
-
const source = await
|
|
33359
|
+
const path = join25(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
33360
|
+
const source = await readFile21(path, "utf8");
|
|
32809
33361
|
const declarations = [
|
|
32810
33362
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
32811
33363
|
].map((match) => match[1]);
|
|
@@ -32844,8 +33396,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
32844
33396
|
};
|
|
32845
33397
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
32846
33398
|
init_deviceCapabilities();
|
|
32847
|
-
import { readFile as
|
|
32848
|
-
import { join as
|
|
33399
|
+
import { readFile as readFile22, rename as rename14, writeFile as writeFile18 } from "fs/promises";
|
|
33400
|
+
import { join as join26 } from "path";
|
|
32849
33401
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
32850
33402
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
32851
33403
|
var NOT_FOUND2 = -1;
|
|
@@ -32855,7 +33407,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
32855
33407
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
32856
33408
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
32857
33409
|
var writeChangedFile2 = async (path, source) => {
|
|
32858
|
-
const current = await
|
|
33410
|
+
const current = await readFile22(path, "utf8");
|
|
32859
33411
|
if (current === source)
|
|
32860
33412
|
return false;
|
|
32861
33413
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -32875,7 +33427,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
32875
33427
|
};
|
|
32876
33428
|
var optionalSource = async (path) => {
|
|
32877
33429
|
try {
|
|
32878
|
-
return await
|
|
33430
|
+
return await readFile22(path, "utf8");
|
|
32879
33431
|
} catch (error) {
|
|
32880
33432
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32881
33433
|
return null;
|
|
@@ -32995,8 +33547,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
|
|
|
32995
33547
|
var configureIosPrivacyProject = async (config, requirements) => {
|
|
32996
33548
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
32997
33549
|
return false;
|
|
32998
|
-
const projectPath2 =
|
|
32999
|
-
const project = await
|
|
33550
|
+
const projectPath2 = join26(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
33551
|
+
const project = await readFile22(projectPath2, "utf8");
|
|
33000
33552
|
return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
|
|
33001
33553
|
};
|
|
33002
33554
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -33048,8 +33600,8 @@ ${next.slice(index)}`;
|
|
|
33048
33600
|
return next;
|
|
33049
33601
|
};
|
|
33050
33602
|
var configureIos2 = async (config, plan) => {
|
|
33051
|
-
const path =
|
|
33052
|
-
const source = await
|
|
33603
|
+
const path = join26(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
33604
|
+
const source = await readFile22(path, "utf8");
|
|
33053
33605
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
33054
33606
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
33055
33607
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -33069,7 +33621,7 @@ ${content}
|
|
|
33069
33621
|
${END_MARKER2}
|
|
33070
33622
|
` : "";
|
|
33071
33623
|
const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
|
|
33072
|
-
const privacyPath =
|
|
33624
|
+
const privacyPath = join26(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
33073
33625
|
const privacyCurrent = await optionalSource(privacyPath);
|
|
33074
33626
|
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
33075
33627
|
const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
|
|
@@ -33080,7 +33632,7 @@ ${content}
|
|
|
33080
33632
|
return infoChanged || privacyChanged || projectChanged || pushChanged;
|
|
33081
33633
|
};
|
|
33082
33634
|
var configureIosPushNotifications = async (config, enabled) => {
|
|
33083
|
-
const entitlementsPath =
|
|
33635
|
+
const entitlementsPath = join26(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
33084
33636
|
const entitlements = await optionalSource(entitlementsPath);
|
|
33085
33637
|
if (entitlements === null && !enabled)
|
|
33086
33638
|
return false;
|
|
@@ -33092,7 +33644,7 @@ var configureIosPushNotifications = async (config, enabled) => {
|
|
|
33092
33644
|
<!-- ${PUSH_END_MARKER} -->
|
|
33093
33645
|
` : "";
|
|
33094
33646
|
const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
|
|
33095
|
-
const delegatePath =
|
|
33647
|
+
const delegatePath = join26(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
33096
33648
|
const delegate = await optionalSource(delegatePath);
|
|
33097
33649
|
if (delegate === null && !enabled)
|
|
33098
33650
|
return false;
|
|
@@ -33141,8 +33693,8 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
33141
33693
|
return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
|
|
33142
33694
|
};
|
|
33143
33695
|
var configureAndroid2 = async (config, plan) => {
|
|
33144
|
-
const path =
|
|
33145
|
-
const source = await
|
|
33696
|
+
const path = join26(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
33697
|
+
const source = await readFile22(path, "utf8");
|
|
33146
33698
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
33147
33699
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
33148
33700
|
`);
|
|
@@ -33177,7 +33729,7 @@ ${content}
|
|
|
33177
33729
|
throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
|
|
33178
33730
|
const [manifestChanged, firebaseChanged] = await Promise.all([
|
|
33179
33731
|
writeChangedFile2(path, nextManifest),
|
|
33180
|
-
writeOptionalChangedFile(
|
|
33732
|
+
writeOptionalChangedFile(join26(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
|
|
33181
33733
|
]);
|
|
33182
33734
|
return manifestChanged || firebaseChanged;
|
|
33183
33735
|
};
|
|
@@ -33196,14 +33748,14 @@ init_nativeAuth();
|
|
|
33196
33748
|
|
|
33197
33749
|
// src/mobile/nativeUpdates.ts
|
|
33198
33750
|
import {
|
|
33199
|
-
mkdir as
|
|
33200
|
-
readFile as
|
|
33201
|
-
readdir as
|
|
33751
|
+
mkdir as mkdir17,
|
|
33752
|
+
readFile as readFile23,
|
|
33753
|
+
readdir as readdir7,
|
|
33202
33754
|
rename as rename15,
|
|
33203
|
-
rm as
|
|
33755
|
+
rm as rm13,
|
|
33204
33756
|
writeFile as writeFile19
|
|
33205
33757
|
} from "fs/promises";
|
|
33206
|
-
import { dirname as
|
|
33758
|
+
import { dirname as dirname17, join as join27 } from "path";
|
|
33207
33759
|
var START = "// absolutejs:mobile-updates:start";
|
|
33208
33760
|
var END = "// absolutejs:mobile-updates:end";
|
|
33209
33761
|
var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
|
|
@@ -33211,7 +33763,7 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
|
|
|
33211
33763
|
var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
|
|
33212
33764
|
var optionalSource2 = async (path) => {
|
|
33213
33765
|
try {
|
|
33214
|
-
return await
|
|
33766
|
+
return await readFile23(path, "utf8");
|
|
33215
33767
|
} catch (error) {
|
|
33216
33768
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
33217
33769
|
return null;
|
|
@@ -33223,7 +33775,7 @@ var writeChanged = async (path, source) => {
|
|
|
33223
33775
|
const current = await optionalSource2(path);
|
|
33224
33776
|
if (current === source)
|
|
33225
33777
|
return false;
|
|
33226
|
-
await
|
|
33778
|
+
await mkdir17(dirname17(path), { recursive: true });
|
|
33227
33779
|
if (current === null) {
|
|
33228
33780
|
await writeFile19(path, source, { flag: "wx" });
|
|
33229
33781
|
return true;
|
|
@@ -33236,7 +33788,7 @@ var writeChanged = async (path, source) => {
|
|
|
33236
33788
|
var removeOwnedFile = async (path) => {
|
|
33237
33789
|
if (await optionalSource2(path) === null)
|
|
33238
33790
|
return false;
|
|
33239
|
-
await
|
|
33791
|
+
await rm13(path);
|
|
33240
33792
|
return true;
|
|
33241
33793
|
};
|
|
33242
33794
|
var replaceMarkedRegion = (source, start, end, region, insertion, error) => {
|
|
@@ -33373,9 +33925,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
|
|
|
33373
33925
|
${PLUGIN_END}
|
|
33374
33926
|
`;
|
|
33375
33927
|
var configureIos3 = async (config, enabled) => {
|
|
33376
|
-
const path =
|
|
33377
|
-
const capacitorConfigPath =
|
|
33378
|
-
let source = await
|
|
33928
|
+
const path = join27(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
33929
|
+
const capacitorConfigPath = join27(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
33930
|
+
let source = await readFile23(path, "utf8");
|
|
33379
33931
|
const launch2 = source.indexOf("didFinishLaunchingWithOptions");
|
|
33380
33932
|
const brace = launch2 < 0 ? -1 : source.indexOf("{", launch2);
|
|
33381
33933
|
const launchRegion = enabled ? ` ${START}
|
|
@@ -33386,7 +33938,7 @@ var configureIos3 = async (config, enabled) => {
|
|
|
33386
33938
|
`, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
|
|
33387
33939
|
const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
|
|
33388
33940
|
source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
|
|
33389
|
-
const capacitorConfigSource2 = await
|
|
33941
|
+
const capacitorConfigSource2 = await readFile23(capacitorConfigPath, "utf8");
|
|
33390
33942
|
let capacitorConfig;
|
|
33391
33943
|
try {
|
|
33392
33944
|
const value = JSON.parse(capacitorConfigSource2);
|
|
@@ -33559,19 +34111,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
|
|
|
33559
34111
|
var androidActivityInRoot = async (root) => {
|
|
33560
34112
|
let entries;
|
|
33561
34113
|
try {
|
|
33562
|
-
entries = await
|
|
34114
|
+
entries = await readdir7(root, { recursive: true });
|
|
33563
34115
|
} catch (error) {
|
|
33564
34116
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
33565
34117
|
return;
|
|
33566
34118
|
throw error;
|
|
33567
34119
|
}
|
|
33568
34120
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
33569
|
-
return candidate ?
|
|
34121
|
+
return candidate ? join27(root, candidate) : undefined;
|
|
33570
34122
|
};
|
|
33571
34123
|
var androidActivity = async (config) => {
|
|
33572
34124
|
const roots = [
|
|
33573
|
-
|
|
33574
|
-
|
|
34125
|
+
join27(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
34126
|
+
join27(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
33575
34127
|
];
|
|
33576
34128
|
const candidates = await Promise.all(roots.map(androidActivityInRoot));
|
|
33577
34129
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -33670,12 +34222,12 @@ var injectAndroidActivity = (source, enabled) => {
|
|
|
33670
34222
|
};
|
|
33671
34223
|
var configureAndroid3 = async (config, enabled) => {
|
|
33672
34224
|
const activityPath = await androidActivity(config);
|
|
33673
|
-
const activity = await
|
|
34225
|
+
const activity = await readFile23(activityPath, "utf8");
|
|
33674
34226
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
33675
34227
|
if (!packageName)
|
|
33676
34228
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
33677
34229
|
const packagePath = packageName.replaceAll(".", "/");
|
|
33678
|
-
const pluginPath =
|
|
34230
|
+
const pluginPath = join27(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
|
|
33679
34231
|
const changed = await Promise.all([
|
|
33680
34232
|
writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
|
|
33681
34233
|
enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
|
|
@@ -33695,14 +34247,14 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
|
|
|
33695
34247
|
};
|
|
33696
34248
|
// src/mobile/nativeObservability.ts
|
|
33697
34249
|
import {
|
|
33698
|
-
mkdir as
|
|
33699
|
-
readFile as
|
|
33700
|
-
readdir as
|
|
34250
|
+
mkdir as mkdir18,
|
|
34251
|
+
readFile as readFile24,
|
|
34252
|
+
readdir as readdir8,
|
|
33701
34253
|
rename as rename16,
|
|
33702
|
-
rm as
|
|
34254
|
+
rm as rm14,
|
|
33703
34255
|
writeFile as writeFile20
|
|
33704
34256
|
} from "fs/promises";
|
|
33705
|
-
import { dirname as
|
|
34257
|
+
import { dirname as dirname18, join as join28 } from "path";
|
|
33706
34258
|
var START2 = "// absolutejs:native-observability:start";
|
|
33707
34259
|
var END2 = "// absolutejs:native-observability:end";
|
|
33708
34260
|
var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
|
|
@@ -33710,7 +34262,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
|
|
|
33710
34262
|
var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
|
|
33711
34263
|
var optionalSource3 = async (path) => {
|
|
33712
34264
|
try {
|
|
33713
|
-
return await
|
|
34265
|
+
return await readFile24(path, "utf8");
|
|
33714
34266
|
} catch (error) {
|
|
33715
34267
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
33716
34268
|
return null;
|
|
@@ -33721,7 +34273,7 @@ var writeChanged2 = async (path, source) => {
|
|
|
33721
34273
|
const current = await optionalSource3(path);
|
|
33722
34274
|
if (current === source)
|
|
33723
34275
|
return false;
|
|
33724
|
-
await
|
|
34276
|
+
await mkdir18(dirname18(path), { recursive: true });
|
|
33725
34277
|
if (current === null) {
|
|
33726
34278
|
await writeFile20(path, source, { flag: "wx" });
|
|
33727
34279
|
return true;
|
|
@@ -33734,7 +34286,7 @@ var writeChanged2 = async (path, source) => {
|
|
|
33734
34286
|
var removeOwnedFile2 = async (path) => {
|
|
33735
34287
|
if (await optionalSource3(path) === null)
|
|
33736
34288
|
return false;
|
|
33737
|
-
await
|
|
34289
|
+
await rm14(path);
|
|
33738
34290
|
return true;
|
|
33739
34291
|
};
|
|
33740
34292
|
var isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -33870,9 +34422,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
|
|
|
33870
34422
|
${PLUGIN_END2}
|
|
33871
34423
|
`;
|
|
33872
34424
|
var configureIos4 = async (config, enabled) => {
|
|
33873
|
-
const path =
|
|
33874
|
-
const capacitorConfigPath =
|
|
33875
|
-
let source = await
|
|
34425
|
+
const path = join28(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
34426
|
+
const capacitorConfigPath = join28(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
34427
|
+
let source = await readFile24(path, "utf8");
|
|
33876
34428
|
if (enabled && !source.includes("import MetricKit")) {
|
|
33877
34429
|
const capacitorImport = source.lastIndexOf("import Capacitor");
|
|
33878
34430
|
if (capacitorImport < 0)
|
|
@@ -33886,7 +34438,7 @@ ${source.slice(newline + 1)}`;
|
|
|
33886
34438
|
source = source.replace(`import MetricKit
|
|
33887
34439
|
`, "");
|
|
33888
34440
|
source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
|
|
33889
|
-
const capacitorConfigSource2 = await
|
|
34441
|
+
const capacitorConfigSource2 = await readFile24(capacitorConfigPath, "utf8");
|
|
33890
34442
|
let capacitorConfig;
|
|
33891
34443
|
try {
|
|
33892
34444
|
const value = JSON.parse(capacitorConfigSource2);
|
|
@@ -34124,19 +34676,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
|
|
|
34124
34676
|
var androidActivityInRoot2 = async (root) => {
|
|
34125
34677
|
let entries;
|
|
34126
34678
|
try {
|
|
34127
|
-
entries = await
|
|
34679
|
+
entries = await readdir8(root, { recursive: true });
|
|
34128
34680
|
} catch (error) {
|
|
34129
34681
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
34130
34682
|
return;
|
|
34131
34683
|
throw error;
|
|
34132
34684
|
}
|
|
34133
34685
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
34134
|
-
return candidate ?
|
|
34686
|
+
return candidate ? join28(root, candidate) : undefined;
|
|
34135
34687
|
};
|
|
34136
34688
|
var androidActivity2 = async (config) => {
|
|
34137
34689
|
const roots = [
|
|
34138
|
-
|
|
34139
|
-
|
|
34690
|
+
join28(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
34691
|
+
join28(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
34140
34692
|
];
|
|
34141
34693
|
const candidates = await Promise.all(roots.map(androidActivityInRoot2));
|
|
34142
34694
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -34204,11 +34756,11 @@ var injectAndroidActivity2 = (source, enabled) => {
|
|
|
34204
34756
|
};
|
|
34205
34757
|
var configureAndroid4 = async (config, enabled) => {
|
|
34206
34758
|
const activityPath = await androidActivity2(config);
|
|
34207
|
-
const activity = await
|
|
34759
|
+
const activity = await readFile24(activityPath, "utf8");
|
|
34208
34760
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
34209
34761
|
if (!packageName)
|
|
34210
34762
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
34211
|
-
const pluginPath =
|
|
34763
|
+
const pluginPath = join28(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
|
|
34212
34764
|
const changed = await Promise.all([
|
|
34213
34765
|
writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
|
|
34214
34766
|
enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
|
|
@@ -34226,6 +34778,219 @@ var applyAbsoluteNativeObservability = async (config, platforms = config.platfor
|
|
|
34226
34778
|
changed.push(await configureAndroid4(config, enabled));
|
|
34227
34779
|
return { changed: changed.some(Boolean) };
|
|
34228
34780
|
};
|
|
34781
|
+
// src/mobile/nativeReleaseReadiness.ts
|
|
34782
|
+
import { mkdir as mkdir19, readFile as readFile25, readdir as readdir9, rename as rename17, writeFile as writeFile21 } from "fs/promises";
|
|
34783
|
+
import { dirname as dirname19, join as join29 } from "path";
|
|
34784
|
+
var START3 = "// absolutejs:release-readiness:start";
|
|
34785
|
+
var END3 = "// absolutejs:release-readiness:end";
|
|
34786
|
+
var IOS_PLUGIN_START = "// absolutejs:release-readiness-plugin:start";
|
|
34787
|
+
var IOS_PLUGIN_END = "// absolutejs:release-readiness-plugin:end";
|
|
34788
|
+
var ANDROID_PLUGIN3 = "AbsoluteReleaseReadinessPlugin.java";
|
|
34789
|
+
var optionalSource4 = async (path) => {
|
|
34790
|
+
try {
|
|
34791
|
+
return await readFile25(path, "utf8");
|
|
34792
|
+
} catch (error) {
|
|
34793
|
+
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
34794
|
+
return null;
|
|
34795
|
+
throw error;
|
|
34796
|
+
}
|
|
34797
|
+
};
|
|
34798
|
+
var writeChanged3 = async (path, source) => {
|
|
34799
|
+
const current = await optionalSource4(path);
|
|
34800
|
+
if (current === source)
|
|
34801
|
+
return false;
|
|
34802
|
+
await mkdir19(dirname19(path), { recursive: true });
|
|
34803
|
+
if (current === null) {
|
|
34804
|
+
await writeFile21(path, source, { flag: "wx" });
|
|
34805
|
+
return true;
|
|
34806
|
+
}
|
|
34807
|
+
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
34808
|
+
await writeFile21(temporary, source, { flag: "wx" });
|
|
34809
|
+
await rename17(temporary, path);
|
|
34810
|
+
return true;
|
|
34811
|
+
};
|
|
34812
|
+
var activityInRoot = async (root) => {
|
|
34813
|
+
let entries;
|
|
34814
|
+
try {
|
|
34815
|
+
entries = await readdir9(root, { recursive: true });
|
|
34816
|
+
} catch (error) {
|
|
34817
|
+
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
34818
|
+
return;
|
|
34819
|
+
throw error;
|
|
34820
|
+
}
|
|
34821
|
+
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
34822
|
+
return candidate ? join29(root, candidate) : undefined;
|
|
34823
|
+
};
|
|
34824
|
+
var activityPath = async (config) => {
|
|
34825
|
+
const roots = [
|
|
34826
|
+
join29(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
34827
|
+
join29(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
34828
|
+
];
|
|
34829
|
+
const candidates = await Promise.all(roots.map(activityInRoot));
|
|
34830
|
+
const candidate = candidates.find((value) => value !== undefined);
|
|
34831
|
+
if (candidate)
|
|
34832
|
+
return candidate;
|
|
34833
|
+
throw new TypeError("Android MainActivity.java or MainActivity.kt was not found.");
|
|
34834
|
+
};
|
|
34835
|
+
var registrationRegion = (kotlin, generatedMethod) => {
|
|
34836
|
+
if (generatedMethod)
|
|
34837
|
+
return kotlin ? ` ${START3}
|
|
34838
|
+
override fun onCreate(savedInstanceState: android.os.Bundle?) {
|
|
34839
|
+
registerPlugin(AbsoluteReleaseReadinessPlugin::class.java)
|
|
34840
|
+
super.onCreate(savedInstanceState)
|
|
34841
|
+
}
|
|
34842
|
+
${END3}
|
|
34843
|
+
` : ` ${START3}
|
|
34844
|
+
@Override
|
|
34845
|
+
public void onCreate(android.os.Bundle savedInstanceState) {
|
|
34846
|
+
registerPlugin(AbsoluteReleaseReadinessPlugin.class);
|
|
34847
|
+
super.onCreate(savedInstanceState);
|
|
34848
|
+
}
|
|
34849
|
+
${END3}
|
|
34850
|
+
`;
|
|
34851
|
+
return kotlin ? ` ${START3}
|
|
34852
|
+
registerPlugin(AbsoluteReleaseReadinessPlugin::class.java)
|
|
34853
|
+
${END3}
|
|
34854
|
+
` : ` ${START3}
|
|
34855
|
+
registerPlugin(AbsoluteReleaseReadinessPlugin.class);
|
|
34856
|
+
${END3}
|
|
34857
|
+
`;
|
|
34858
|
+
};
|
|
34859
|
+
var injectRegistration = (source) => {
|
|
34860
|
+
const kotlin = /\bfun\s+onCreate\s*\(/u.test(source) || source.includes("BridgeActivity()");
|
|
34861
|
+
const existingStart = source.indexOf(START3);
|
|
34862
|
+
const existingEnd = source.indexOf(END3);
|
|
34863
|
+
if (existingStart < 0 !== existingEnd < 0 || existingStart >= 0 && existingEnd < existingStart)
|
|
34864
|
+
throw new TypeError("AbsoluteJS release-readiness markers are malformed.");
|
|
34865
|
+
if (existingStart >= 0) {
|
|
34866
|
+
const from = source.lastIndexOf(`
|
|
34867
|
+
`, existingStart) + 1;
|
|
34868
|
+
const newline = source.indexOf(`
|
|
34869
|
+
`, existingEnd + END3.length);
|
|
34870
|
+
const through = newline < 0 ? source.length : newline + 1;
|
|
34871
|
+
const generatedMethod = source.slice(from, through).includes("onCreate(");
|
|
34872
|
+
return `${source.slice(0, from)}${registrationRegion(kotlin, generatedMethod)}${source.slice(through)}`;
|
|
34873
|
+
}
|
|
34874
|
+
const onCreate = kotlin ? source.search(/\boverride\s+fun\s+onCreate\s*\([^)]*\)\s*\{/u) : source.search(/\b(?:public|protected)\s+void\s+onCreate\s*\([^)]*\)\s*\{/u);
|
|
34875
|
+
if (onCreate >= 0) {
|
|
34876
|
+
const brace = source.indexOf("{", onCreate);
|
|
34877
|
+
const insert = source.indexOf(`
|
|
34878
|
+
`, brace) + 1;
|
|
34879
|
+
if (insert <= 0)
|
|
34880
|
+
throw new TypeError("Could not inject Android release readiness into MainActivity.");
|
|
34881
|
+
return `${source.slice(0, insert)}${registrationRegion(kotlin, false)}${source.slice(insert)}`;
|
|
34882
|
+
}
|
|
34883
|
+
const close = source.lastIndexOf("}");
|
|
34884
|
+
if (close < 0)
|
|
34885
|
+
throw new TypeError("Could not find the Android MainActivity class body.");
|
|
34886
|
+
const separator = source[close - 1] === `
|
|
34887
|
+
` ? "" : `
|
|
34888
|
+
`;
|
|
34889
|
+
return `${source.slice(0, close)}${separator}${registrationRegion(kotlin, true)}${source.slice(close)}`;
|
|
34890
|
+
};
|
|
34891
|
+
var pluginSource = (packageName) => `package ${packageName};
|
|
34892
|
+
|
|
34893
|
+
import android.util.Log;
|
|
34894
|
+
import com.getcapacitor.JSObject;
|
|
34895
|
+
import com.getcapacitor.Plugin;
|
|
34896
|
+
import com.getcapacitor.PluginCall;
|
|
34897
|
+
import com.getcapacitor.PluginMethod;
|
|
34898
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
34899
|
+
|
|
34900
|
+
@CapacitorPlugin(name = "AbsoluteReleaseReadiness")
|
|
34901
|
+
public final class AbsoluteReleaseReadinessPlugin extends Plugin {
|
|
34902
|
+
@PluginMethod
|
|
34903
|
+
public void ready(PluginCall call) {
|
|
34904
|
+
Log.i("AbsoluteJS", "Capacitor embedded web content ready");
|
|
34905
|
+
call.resolve(new JSObject().put("ready", true));
|
|
34906
|
+
}
|
|
34907
|
+
}
|
|
34908
|
+
`;
|
|
34909
|
+
var iosPluginRegion3 = `${IOS_PLUGIN_START}
|
|
34910
|
+
@objc(AbsoluteReleaseReadinessPlugin)
|
|
34911
|
+
public final class AbsoluteReleaseReadinessPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
34912
|
+
public let identifier = "AbsoluteReleaseReadinessPlugin"
|
|
34913
|
+
public let jsName = "AbsoluteReleaseReadiness"
|
|
34914
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
34915
|
+
CAPPluginMethod(name: "ready", returnType: CAPPluginReturnPromise)
|
|
34916
|
+
]
|
|
34917
|
+
|
|
34918
|
+
@objc public func ready(_ call: CAPPluginCall) {
|
|
34919
|
+
let info = Bundle.main.infoDictionary ?? [:]
|
|
34920
|
+
let version = info["CFBundleShortVersionString"] as? String ?? "unknown"
|
|
34921
|
+
let build = info["CFBundleVersion"] as? String ?? "unknown"
|
|
34922
|
+
NSLog("AbsoluteJS: Capacitor embedded web content ready; version=%@; build=%@", version, build)
|
|
34923
|
+
call.resolve(["ready": true])
|
|
34924
|
+
}
|
|
34925
|
+
}
|
|
34926
|
+
${IOS_PLUGIN_END}
|
|
34927
|
+
`;
|
|
34928
|
+
var replaceIosPluginRegion = (appDelegate, existingStart, existingEnd) => {
|
|
34929
|
+
const from = appDelegate.lastIndexOf(`
|
|
34930
|
+
`, existingStart) + 1;
|
|
34931
|
+
const newline = appDelegate.indexOf(`
|
|
34932
|
+
`, existingEnd + IOS_PLUGIN_END.length);
|
|
34933
|
+
const through = newline < 0 ? appDelegate.length : newline + 1;
|
|
34934
|
+
return `${appDelegate.slice(0, from)}${iosPluginRegion3}${appDelegate.slice(through)}`;
|
|
34935
|
+
};
|
|
34936
|
+
var configureIos5 = async (config) => {
|
|
34937
|
+
const appDelegatePath = join29(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
34938
|
+
const capacitorConfigPath = join29(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
34939
|
+
const appDelegate = await readFile25(appDelegatePath, "utf8");
|
|
34940
|
+
const existingStart = appDelegate.indexOf(IOS_PLUGIN_START);
|
|
34941
|
+
const existingEnd = appDelegate.indexOf(IOS_PLUGIN_END);
|
|
34942
|
+
if (existingStart < 0 !== existingEnd < 0 || existingStart >= 0 && existingEnd < existingStart)
|
|
34943
|
+
throw new TypeError("AbsoluteJS iOS release-readiness markers are malformed.");
|
|
34944
|
+
const source = existingStart < 0 ? `${appDelegate.trimEnd()}
|
|
34945
|
+
|
|
34946
|
+
${iosPluginRegion3}` : replaceIosPluginRegion(appDelegate, existingStart, existingEnd);
|
|
34947
|
+
let capacitorConfig;
|
|
34948
|
+
try {
|
|
34949
|
+
capacitorConfig = JSON.parse(await readFile25(capacitorConfigPath, "utf8"));
|
|
34950
|
+
} catch {
|
|
34951
|
+
throw new TypeError("iOS capacitor.config.json is invalid; run Capacitor sync before projecting release readiness.");
|
|
34952
|
+
}
|
|
34953
|
+
if (typeof capacitorConfig !== "object" || capacitorConfig === null)
|
|
34954
|
+
throw new TypeError("iOS capacitor.config.json must contain an object.");
|
|
34955
|
+
const packageClassList = Reflect.get(capacitorConfig, "packageClassList");
|
|
34956
|
+
if (!Array.isArray(packageClassList))
|
|
34957
|
+
throw new TypeError("iOS capacitor.config.json has no packageClassList; run Capacitor sync before projecting release readiness.");
|
|
34958
|
+
const classes = packageClassList.filter((value) => typeof value === "string");
|
|
34959
|
+
const nextConfig = `${JSON.stringify({
|
|
34960
|
+
...capacitorConfig,
|
|
34961
|
+
packageClassList: [
|
|
34962
|
+
...new Set([...classes, "AbsoluteReleaseReadinessPlugin"])
|
|
34963
|
+
]
|
|
34964
|
+
}, null, "\t")}
|
|
34965
|
+
`;
|
|
34966
|
+
const changed = await Promise.all([
|
|
34967
|
+
writeChanged3(appDelegatePath, source),
|
|
34968
|
+
writeChanged3(capacitorConfigPath, nextConfig)
|
|
34969
|
+
]);
|
|
34970
|
+
return changed.some(Boolean);
|
|
34971
|
+
};
|
|
34972
|
+
var configureAndroid5 = async (config) => {
|
|
34973
|
+
const mainActivityPath = await activityPath(config);
|
|
34974
|
+
const activity = await readFile25(mainActivityPath, "utf8");
|
|
34975
|
+
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
34976
|
+
if (!packageName)
|
|
34977
|
+
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
34978
|
+
const pluginPath = join29(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN3);
|
|
34979
|
+
const changed = await Promise.all([
|
|
34980
|
+
writeChanged3(mainActivityPath, injectRegistration(activity)),
|
|
34981
|
+
writeChanged3(pluginPath, pluginSource(packageName))
|
|
34982
|
+
]);
|
|
34983
|
+
return changed.some(Boolean);
|
|
34984
|
+
};
|
|
34985
|
+
var applyAbsoluteNativeReleaseReadiness = async (config, platforms = config.platforms) => {
|
|
34986
|
+
if (config.engine !== "capacitor")
|
|
34987
|
+
return { changed: false };
|
|
34988
|
+
const changed = await Promise.all([
|
|
34989
|
+
platforms.includes("android") ? configureAndroid5(config) : false,
|
|
34990
|
+
platforms.includes("ios") ? configureIos5(config) : false
|
|
34991
|
+
]);
|
|
34992
|
+
return { changed: changed.some(Boolean) };
|
|
34993
|
+
};
|
|
34229
34994
|
|
|
34230
34995
|
// src/mobile/index.ts
|
|
34231
34996
|
init_pageProtocol();
|
|
@@ -34233,8 +34998,8 @@ init_producerContext();
|
|
|
34233
34998
|
init_releaseArtifact();
|
|
34234
34999
|
|
|
34235
35000
|
// src/mobile/releasePublisher.ts
|
|
34236
|
-
import { access as
|
|
34237
|
-
import { isAbsolute as
|
|
35001
|
+
import { access as access17 } from "fs/promises";
|
|
35002
|
+
import { isAbsolute as isAbsolute9, relative as relative16, resolve as resolve18, sep as sep11 } from "path";
|
|
34238
35003
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
34239
35004
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
34240
35005
|
if (typeof publisher.prepareIosRelease !== "function") {
|
|
@@ -34260,17 +35025,17 @@ var prepareAbsoluteAndroidRelease = async (publisher, options) => {
|
|
|
34260
35025
|
var isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34261
35026
|
var isPublisher = (value) => isRecord14(value) && typeof value.publish === "function";
|
|
34262
35027
|
var publisherModulePath = (projectRoot, requested) => {
|
|
34263
|
-
const root =
|
|
34264
|
-
const path =
|
|
34265
|
-
const projectRelative =
|
|
34266
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
35028
|
+
const root = resolve18(projectRoot);
|
|
35029
|
+
const path = resolve18(root, requested);
|
|
35030
|
+
const projectRelative = relative16(root, path);
|
|
35031
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep11}`) || isAbsolute9(projectRelative)) {
|
|
34267
35032
|
throw new TypeError("mobile publish --registry must remain inside the project.");
|
|
34268
35033
|
}
|
|
34269
35034
|
return path;
|
|
34270
35035
|
};
|
|
34271
35036
|
var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
|
|
34272
35037
|
const modulePath = publisherModulePath(projectRoot, requestedModulePath);
|
|
34273
|
-
await
|
|
35038
|
+
await access17(modulePath).catch(() => {
|
|
34274
35039
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
34275
35040
|
});
|
|
34276
35041
|
const loaded = await import(pathToFileURL3(modulePath).href);
|
|
@@ -34334,7 +35099,7 @@ var publishAbsoluteIosRelease = async (options) => {
|
|
|
34334
35099
|
init_pageProtocol();
|
|
34335
35100
|
init_releaseArtifact();
|
|
34336
35101
|
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
34337
|
-
import { dirname as
|
|
35102
|
+
import { dirname as dirname20, extname as extname6, relative as relative17, resolve as resolve19 } from "path";
|
|
34338
35103
|
import ts2 from "typescript";
|
|
34339
35104
|
var ROUTE_METHODS = new Set(["get", "head"]);
|
|
34340
35105
|
var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
|
|
@@ -34385,7 +35150,7 @@ var PAGE_HANDLERS = new Map([
|
|
|
34385
35150
|
]
|
|
34386
35151
|
]);
|
|
34387
35152
|
var posixPath = (value) => value.replace(/\\/g, "/");
|
|
34388
|
-
var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(
|
|
35153
|
+
var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(dirname20(entry), existsSync7, "tsconfig.json") ?? ts2.findConfigFile(projectRoot, existsSync7, "tsconfig.json");
|
|
34389
35154
|
var createProgram = (entry, projectRoot) => {
|
|
34390
35155
|
const configPath2 = findTsconfig(entry, projectRoot);
|
|
34391
35156
|
if (!configPath2) {
|
|
@@ -34397,7 +35162,7 @@ var createProgram = (entry, projectRoot) => {
|
|
|
34397
35162
|
target: ts2.ScriptTarget.ESNext
|
|
34398
35163
|
});
|
|
34399
35164
|
}
|
|
34400
|
-
const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath2, (path) => readFileSync8(path, "utf8")).config, ts2.sys,
|
|
35165
|
+
const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath2, (path) => readFileSync8(path, "utf8")).config, ts2.sys, dirname20(configPath2));
|
|
34401
35166
|
if (!parsed.fileNames.includes(entry))
|
|
34402
35167
|
parsed.fileNames.push(entry);
|
|
34403
35168
|
return ts2.createProgram(parsed.fileNames, parsed.options);
|
|
@@ -34503,7 +35268,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
|
|
|
34503
35268
|
const declaration = symbol?.declarations?.[0];
|
|
34504
35269
|
const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
|
|
34505
35270
|
const exportedName = symbol?.name ?? expression.getText(sourceFile);
|
|
34506
|
-
const source = posixPath(
|
|
35271
|
+
const source = posixPath(relative17(projectRoot, file));
|
|
34507
35272
|
return `${source}#${exportedName}`;
|
|
34508
35273
|
};
|
|
34509
35274
|
var resolveAlias = (symbol, checker) => {
|
|
@@ -34742,7 +35507,7 @@ var analyzeProgram = (program, projectRoot) => {
|
|
|
34742
35507
|
const checker = program.getTypeChecker();
|
|
34743
35508
|
const analyzed = new Map;
|
|
34744
35509
|
for (const sourceFile of program.getSourceFiles()) {
|
|
34745
|
-
const resolvedFile =
|
|
35510
|
+
const resolvedFile = resolve19(sourceFile.fileName);
|
|
34746
35511
|
if (!isProjectSource(sourceFile, resolvedFile, projectRoot))
|
|
34747
35512
|
continue;
|
|
34748
35513
|
const analysis = analyzeSourceFile(sourceFile, checker, projectRoot);
|
|
@@ -34835,14 +35600,14 @@ var transformFile = (source, fileName, analysis) => {
|
|
|
34835
35600
|
};
|
|
34836
35601
|
var ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL = ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION;
|
|
34837
35602
|
var createAbsoluteMobileRouteMetadataPlugin = (options) => {
|
|
34838
|
-
const projectRoot =
|
|
34839
|
-
const entry =
|
|
35603
|
+
const projectRoot = resolve19(options.projectRoot ?? process.cwd());
|
|
35604
|
+
const entry = resolve19(options.entry);
|
|
34840
35605
|
const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
|
|
34841
35606
|
return {
|
|
34842
35607
|
name: "absolute-mobile-route-metadata",
|
|
34843
35608
|
setup(build) {
|
|
34844
35609
|
build.onLoad({ filter: SOURCE_FILTER }, async ({ path }) => {
|
|
34845
|
-
const analysis = analyzed.get(
|
|
35610
|
+
const analysis = analyzed.get(resolve19(path));
|
|
34846
35611
|
if (!analysis)
|
|
34847
35612
|
return;
|
|
34848
35613
|
const source = await Bun.file(path).text();
|
|
@@ -34855,11 +35620,11 @@ var createAbsoluteMobileRouteMetadataPlugin = (options) => {
|
|
|
34855
35620
|
};
|
|
34856
35621
|
};
|
|
34857
35622
|
var inspectAbsoluteMobileRouteMetadata = (options) => {
|
|
34858
|
-
const projectRoot =
|
|
34859
|
-
const entry =
|
|
35623
|
+
const projectRoot = resolve19(options.projectRoot ?? process.cwd());
|
|
35624
|
+
const entry = resolve19(options.entry);
|
|
34860
35625
|
const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
|
|
34861
35626
|
return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
|
|
34862
|
-
file: posixPath(
|
|
35627
|
+
file: posixPath(relative17(projectRoot, file)),
|
|
34863
35628
|
metadata
|
|
34864
35629
|
})));
|
|
34865
35630
|
};
|
|
@@ -35193,7 +35958,7 @@ var createCapacitor = (win) => {
|
|
|
35193
35958
|
callbackId
|
|
35194
35959
|
}, callback);
|
|
35195
35960
|
};
|
|
35196
|
-
const p = new Promise((
|
|
35961
|
+
const p = new Promise((resolve20) => call.then(() => resolve20({ remove })));
|
|
35197
35962
|
p.remove = async () => {
|
|
35198
35963
|
console.warn(`Using addListener() without 'await' is deprecated.`);
|
|
35199
35964
|
await remove();
|
|
@@ -35398,11 +36163,11 @@ class CapacitorCookiesPluginWeb extends WebPlugin {
|
|
|
35398
36163
|
var CapacitorCookies = registerPlugin("CapacitorCookies", {
|
|
35399
36164
|
web: () => new CapacitorCookiesPluginWeb
|
|
35400
36165
|
});
|
|
35401
|
-
var readBlobAsBase64 = async (blob) => new Promise((
|
|
36166
|
+
var readBlobAsBase64 = async (blob) => new Promise((resolve20, reject) => {
|
|
35402
36167
|
const reader = new FileReader;
|
|
35403
36168
|
reader.onload = () => {
|
|
35404
36169
|
const base64String = reader.result;
|
|
35405
|
-
|
|
36170
|
+
resolve20(base64String.indexOf(",") >= 0 ? base64String.split(",")[1] : base64String);
|
|
35406
36171
|
};
|
|
35407
36172
|
reader.onerror = (error) => reject(error);
|
|
35408
36173
|
reader.readAsDataURL(blob);
|
|
@@ -40062,8 +40827,8 @@ var createBeacon = (options) => {
|
|
|
40062
40827
|
if (await fontAvailable(element))
|
|
40063
40828
|
return;
|
|
40064
40829
|
if (confirmationMs > 0) {
|
|
40065
|
-
await new Promise((
|
|
40066
|
-
const timer2 = window.setTimeout(
|
|
40830
|
+
await new Promise((resolve20) => {
|
|
40831
|
+
const timer2 = window.setTimeout(resolve20, confirmationMs);
|
|
40067
40832
|
cleanups.push(() => window.clearTimeout(timer2));
|
|
40068
40833
|
});
|
|
40069
40834
|
if (document.visibilityState === "hidden")
|
|
@@ -41051,51 +41816,51 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
41051
41816
|
};
|
|
41052
41817
|
};
|
|
41053
41818
|
// src/mobile/updatePublisher.ts
|
|
41054
|
-
import { access as
|
|
41055
|
-
import { isAbsolute as
|
|
41819
|
+
import { access as access18 } from "fs/promises";
|
|
41820
|
+
import { isAbsolute as isAbsolute10, relative as relative19, resolve as resolve21, sep as sep12 } from "path";
|
|
41056
41821
|
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
41057
41822
|
|
|
41058
41823
|
// src/mobile/updateSigning.ts
|
|
41059
|
-
import { createHash as
|
|
41824
|
+
import { createHash as createHash16, sign, verify } from "crypto";
|
|
41060
41825
|
import {
|
|
41061
41826
|
cp as cp2,
|
|
41062
|
-
mkdir as
|
|
41063
|
-
mkdtemp as
|
|
41064
|
-
readdir as
|
|
41065
|
-
readFile as
|
|
41066
|
-
rename as
|
|
41067
|
-
rm as
|
|
41068
|
-
stat as
|
|
41069
|
-
writeFile as
|
|
41827
|
+
mkdir as mkdir20,
|
|
41828
|
+
mkdtemp as mkdtemp10,
|
|
41829
|
+
readdir as readdir10,
|
|
41830
|
+
readFile as readFile26,
|
|
41831
|
+
rename as rename18,
|
|
41832
|
+
rm as rm15,
|
|
41833
|
+
stat as stat6,
|
|
41834
|
+
writeFile as writeFile22
|
|
41070
41835
|
} from "fs/promises";
|
|
41071
|
-
import { dirname as
|
|
41836
|
+
import { dirname as dirname21, join as join30, relative as relative18, resolve as resolve20 } from "path";
|
|
41072
41837
|
var UPDATE_MANIFEST_FILE = "update.json";
|
|
41073
41838
|
var UPDATE_FILES_DIRECTORY = "files";
|
|
41074
|
-
var
|
|
41839
|
+
var sha2564 = (value) => createHash16("sha256").update(value).digest("hex");
|
|
41075
41840
|
var listFiles = async (root, directory = root) => {
|
|
41076
|
-
const entries = await
|
|
41841
|
+
const entries = await readdir10(directory, { withFileTypes: true });
|
|
41077
41842
|
const paths = await Promise.all(entries.map(async (entry) => {
|
|
41078
|
-
const path =
|
|
41843
|
+
const path = join30(directory, entry.name);
|
|
41079
41844
|
if (entry.isDirectory())
|
|
41080
41845
|
return listFiles(root, path);
|
|
41081
41846
|
if (!entry.isFile())
|
|
41082
41847
|
throw new TypeError("Mobile updates cannot contain links or special files.");
|
|
41083
|
-
return [
|
|
41848
|
+
return [relative18(root, path).replaceAll("\\", "/")];
|
|
41084
41849
|
}));
|
|
41085
41850
|
return paths.flat().sort((left, right) => left.localeCompare(right));
|
|
41086
41851
|
};
|
|
41087
41852
|
var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
|
|
41088
|
-
const source =
|
|
41853
|
+
const source = join30(root, path);
|
|
41089
41854
|
const [metadata, contents] = await Promise.all([
|
|
41090
|
-
|
|
41091
|
-
|
|
41855
|
+
stat6(source),
|
|
41856
|
+
readFile26(source)
|
|
41092
41857
|
]);
|
|
41093
|
-
return { bytes: metadata.size, path, sha256:
|
|
41858
|
+
return { bytes: metadata.size, path, sha256: sha2564(contents) };
|
|
41094
41859
|
}));
|
|
41095
|
-
var releaseIdFor = (value) => `amu_${
|
|
41860
|
+
var releaseIdFor = (value) => `amu_${sha2564(canonicalizeAbsoluteMobileUpdate(value))}`;
|
|
41096
41861
|
var buildAbsoluteMobileUpdate = async (options) => {
|
|
41097
|
-
const bundleDirectory =
|
|
41098
|
-
const outputRoot =
|
|
41862
|
+
const bundleDirectory = resolve20(options.bundleDirectory);
|
|
41863
|
+
const outputRoot = resolve20(options.outputDirectory);
|
|
41099
41864
|
if (outputRoot === bundleDirectory || outputRoot.startsWith(`${bundleDirectory}/`))
|
|
41100
41865
|
throw new TypeError("Mobile update output must be outside the embedded bundle.");
|
|
41101
41866
|
const paths = await listFiles(bundleDirectory);
|
|
@@ -41123,38 +41888,38 @@ var buildAbsoluteMobileUpdate = async (options) => {
|
|
|
41123
41888
|
value: signature.toString("base64")
|
|
41124
41889
|
}
|
|
41125
41890
|
});
|
|
41126
|
-
await
|
|
41127
|
-
const outputDirectory =
|
|
41128
|
-
const staging = await
|
|
41891
|
+
await mkdir20(outputRoot, { recursive: true });
|
|
41892
|
+
const outputDirectory = join30(outputRoot, manifest.releaseId);
|
|
41893
|
+
const staging = await mkdtemp10(join30(outputRoot, ".stage-"));
|
|
41129
41894
|
try {
|
|
41130
|
-
await cp2(bundleDirectory,
|
|
41895
|
+
await cp2(bundleDirectory, join30(staging, UPDATE_FILES_DIRECTORY), {
|
|
41131
41896
|
force: true,
|
|
41132
41897
|
recursive: true
|
|
41133
41898
|
});
|
|
41134
|
-
await
|
|
41899
|
+
await writeFile22(join30(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
41135
41900
|
`);
|
|
41136
|
-
await
|
|
41901
|
+
await rename18(staging, outputDirectory);
|
|
41137
41902
|
} catch (error) {
|
|
41138
|
-
await
|
|
41903
|
+
await rm15(staging, { force: true, recursive: true });
|
|
41139
41904
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "EEXIST")
|
|
41140
41905
|
throw new TypeError(`Mobile update ${manifest.releaseId} already exists.`, { cause: error });
|
|
41141
41906
|
throw error;
|
|
41142
41907
|
}
|
|
41143
41908
|
return {
|
|
41144
41909
|
manifest,
|
|
41145
|
-
manifestPath:
|
|
41910
|
+
manifestPath: join30(outputDirectory, UPDATE_MANIFEST_FILE),
|
|
41146
41911
|
outputDirectory
|
|
41147
41912
|
};
|
|
41148
41913
|
};
|
|
41149
41914
|
var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) => {
|
|
41150
|
-
const source =
|
|
41151
|
-
const root =
|
|
41915
|
+
const source = resolve20(updateDirectory, UPDATE_FILES_DIRECTORY, path);
|
|
41916
|
+
const root = resolve20(updateDirectory, UPDATE_FILES_DIRECTORY);
|
|
41152
41917
|
if (!source.startsWith(`${root}/`))
|
|
41153
41918
|
throw new TypeError("Update file escaped its release.");
|
|
41154
|
-
await
|
|
41919
|
+
await mkdir20(dirname21(destination), { recursive: true });
|
|
41155
41920
|
await cp2(source, destination, { force: true });
|
|
41156
41921
|
};
|
|
41157
|
-
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await
|
|
41922
|
+
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile26(join30(resolve20(directory), UPDATE_MANIFEST_FILE), "utf8")));
|
|
41158
41923
|
var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
|
|
41159
41924
|
const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
|
|
41160
41925
|
const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
|
|
@@ -41271,16 +42036,16 @@ var pruneAbsoluteMobileUpdates = async (options) => {
|
|
|
41271
42036
|
var object5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41272
42037
|
var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "function" && typeof value.promoteUpdate === "function" && typeof value.rollbackUpdate === "function";
|
|
41273
42038
|
var projectPath2 = (projectRoot, requested, label) => {
|
|
41274
|
-
const root =
|
|
41275
|
-
const path =
|
|
41276
|
-
const projectRelative =
|
|
41277
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
42039
|
+
const root = resolve21(projectRoot);
|
|
42040
|
+
const path = resolve21(root, requested);
|
|
42041
|
+
const projectRelative = relative19(root, path);
|
|
42042
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep12}`) || isAbsolute10(projectRelative))
|
|
41278
42043
|
throw new TypeError(`${label} must remain inside the project.`);
|
|
41279
42044
|
return path;
|
|
41280
42045
|
};
|
|
41281
42046
|
var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
|
|
41282
42047
|
const modulePath = projectPath2(projectRoot, requestedModulePath, "mobile update registry");
|
|
41283
|
-
await
|
|
42048
|
+
await access18(modulePath).catch(() => {
|
|
41284
42049
|
throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
|
|
41285
42050
|
});
|
|
41286
42051
|
const loaded = await import(pathToFileURL4(modulePath).href);
|
|
@@ -41331,7 +42096,7 @@ var rollbackAbsoluteMobileUpdate = async (options) => {
|
|
|
41331
42096
|
return result;
|
|
41332
42097
|
};
|
|
41333
42098
|
// src/mobile/updateRollout.ts
|
|
41334
|
-
import { createHash as
|
|
42099
|
+
import { createHash as createHash17 } from "crypto";
|
|
41335
42100
|
var UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[1-8][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u;
|
|
41336
42101
|
var requireHeader = (headers, name) => {
|
|
41337
42102
|
const value = headers.get(name);
|
|
@@ -41346,7 +42111,7 @@ var isAbsoluteMobileUpdateRolloutMember = (options) => {
|
|
|
41346
42111
|
return false;
|
|
41347
42112
|
if (options.rollout === 1)
|
|
41348
42113
|
return true;
|
|
41349
|
-
const digest =
|
|
42114
|
+
const digest = createHash17("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
|
|
41350
42115
|
const bucket = digest.readUInt32BE(0) / 4294967296;
|
|
41351
42116
|
return bucket < options.rollout;
|
|
41352
42117
|
};
|
|
@@ -41443,6 +42208,7 @@ export {
|
|
|
41443
42208
|
applyAbsoluteNativeDeepLinks,
|
|
41444
42209
|
applyAbsoluteNativeDeviceCapabilities,
|
|
41445
42210
|
applyAbsoluteNativeObservability,
|
|
42211
|
+
applyAbsoluteNativeReleaseReadiness,
|
|
41446
42212
|
applyAbsoluteNativeUpdates,
|
|
41447
42213
|
assertAbsoluteAndroidInstalledAppUpgrade,
|
|
41448
42214
|
assertAbsoluteDeviceCapabilityPackages,
|
|
@@ -41583,6 +42349,7 @@ export {
|
|
|
41583
42349
|
publishAbsoluteIosRelease,
|
|
41584
42350
|
publishAbsoluteMobileUpdate,
|
|
41585
42351
|
readAbsoluteAndroidRelease,
|
|
42352
|
+
readAbsoluteIosRelease,
|
|
41586
42353
|
readAbsoluteMobileLinkIntent,
|
|
41587
42354
|
readAbsoluteMobileMaterializedReleases,
|
|
41588
42355
|
readAbsoluteMobileUpdate,
|
|
@@ -41607,6 +42374,8 @@ export {
|
|
|
41607
42374
|
rollbackAbsoluteMobileUpdate,
|
|
41608
42375
|
runAbsoluteAndroidReleaseAcceptance,
|
|
41609
42376
|
runAbsoluteAndroidUpgradeConformance,
|
|
42377
|
+
runAbsoluteIosDeviceReleaseAcceptance,
|
|
42378
|
+
runAbsoluteIosSimulatorReleaseAcceptance,
|
|
41610
42379
|
runWithAbsoluteMobileProducer,
|
|
41611
42380
|
serializeAbsoluteMobileAuthEnvironment,
|
|
41612
42381
|
startAbsoluteExpoDevSession,
|
|
@@ -41632,5 +42401,5 @@ export {
|
|
|
41632
42401
|
writeAbsoluteMobileUpdateRegistry
|
|
41633
42402
|
};
|
|
41634
42403
|
|
|
41635
|
-
//# debugId=
|
|
42404
|
+
//# debugId=E34FAEF09492010764756E2164756E21
|
|
41636
42405
|
//# sourceMappingURL=index.js.map
|