@absolutejs/absolute 0.20.0-beta.91 → 0.20.0-beta.93
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 +18 -0
- package/changelog.json +41 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build/buildWorker.js +10 -1
- package/dist/build.js +16 -7
- package/dist/build.js.map +9 -8
- package/dist/cli/{compile-5hchbcbd.js → compile-wkfd88w7.js} +5 -5
- package/dist/cli/{dev-aykeaa7b.js → dev-01zcxngn.js} +83 -11
- package/dist/cli/{expoDevController-tr63cg78.js → expoDevController-k15hftqn.js} +25 -1
- package/dist/cli/expoNativeWatcher-rmc95bak.js +138 -0
- package/dist/cli/{expoProject-dac8fqhq.js → expoProject-mmm3s62b.js} +1 -1
- package/dist/cli/{index-fn44wefq.js → index-3sdvzrv2.js} +37 -28
- package/dist/cli/index-bw4ktfnz.js +11 -0
- package/dist/cli/{index-jqdt7841.js → index-kh44yx23.js} +1 -1
- package/dist/cli/{index-39j0dhq7.js → index-v5knwk7v.js} +1 -1
- package/dist/cli/{index-tame6e2c.js → index-wqhbxtyp.js} +49 -12
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-bg1jy34n.js → mobile-pbe1a667.js} +20 -12
- package/dist/cli/{remoteMacProtocol-vw931n0a.js → remoteMacProtocol-kqvkp0qd.js} +2 -1
- package/dist/cli/{start-7jg0csqy.js → start-dw5crgp7.js} +3 -3
- package/dist/dev/client/handlers/svelte.ts +11 -15
- package/dist/dev/serverBootstrap.js +10 -1
- package/dist/index.js +17 -8
- package/dist/index.js.map +11 -10
- package/dist/mobile/index.js +371 -162
- package/dist/mobile/index.js.map +10 -8
- package/dist/mobile/mobilePreviewClient.ts +1 -1
- package/dist/mobile/remoteMacAgentEntry.js +105 -68
- package/dist/src/dev/clientManager.d.ts +2 -2
- package/dist/src/mobile/androidConformance.d.ts +4 -1
- package/dist/src/mobile/expoDevController.d.ts +2 -6
- package/dist/src/mobile/expoNativeObservability.d.ts +1 -1
- package/dist/src/mobile/expoNativeWatcher.d.ts +21 -0
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/remoteMacProtocol.d.ts +1 -4
- package/dist/src/utils/unrefTimer.d.ts +5 -0
- package/package.json +5 -2
package/dist/mobile/index.js
CHANGED
|
@@ -596,6 +596,15 @@ var init_startupBanner = __esm(() => {
|
|
|
596
596
|
];
|
|
597
597
|
});
|
|
598
598
|
|
|
599
|
+
// src/utils/unrefTimer.ts
|
|
600
|
+
var unrefTimer = (timer) => {
|
|
601
|
+
if (timer === null || typeof timer !== "object" && typeof timer !== "function")
|
|
602
|
+
return;
|
|
603
|
+
const unref = Reflect.get(timer, "unref");
|
|
604
|
+
if (typeof unref === "function")
|
|
605
|
+
Reflect.apply(unref, timer, []);
|
|
606
|
+
};
|
|
607
|
+
|
|
599
608
|
// src/mobile/config.ts
|
|
600
609
|
var exports_config = {};
|
|
601
610
|
__export(exports_config, {
|
|
@@ -19342,7 +19351,7 @@ var init_compatibilityDispatcher = __esm(() => {
|
|
|
19342
19351
|
// src/cli/scripts/telemetry.ts
|
|
19343
19352
|
import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
|
|
19344
19353
|
import { homedir as homedir3 } from "os";
|
|
19345
|
-
import { join as
|
|
19354
|
+
import { join as join20 } from "path";
|
|
19346
19355
|
var configDir, configPath, getTelemetryConfig = () => {
|
|
19347
19356
|
try {
|
|
19348
19357
|
if (!existsSync5(configPath))
|
|
@@ -19355,14 +19364,14 @@ var configDir, configPath, getTelemetryConfig = () => {
|
|
|
19355
19364
|
}
|
|
19356
19365
|
};
|
|
19357
19366
|
var init_telemetry = __esm(() => {
|
|
19358
|
-
configDir =
|
|
19359
|
-
configPath =
|
|
19367
|
+
configDir = join20(homedir3(), ".absolutejs");
|
|
19368
|
+
configPath = join20(configDir, "telemetry.json");
|
|
19360
19369
|
});
|
|
19361
19370
|
|
|
19362
19371
|
// src/cli/telemetryEvent.ts
|
|
19363
19372
|
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
19364
19373
|
import { arch, platform as platform3 } from "os";
|
|
19365
|
-
import { dirname as dirname14, join as
|
|
19374
|
+
import { dirname as dirname14, join as join21, parse } from "path";
|
|
19366
19375
|
var checkCandidate = (candidate) => {
|
|
19367
19376
|
if (!existsSync6(candidate)) {
|
|
19368
19377
|
return null;
|
|
@@ -19382,7 +19391,7 @@ var checkCandidate = (candidate) => {
|
|
|
19382
19391
|
}, findPackageVersion = () => {
|
|
19383
19392
|
let { dir } = import.meta;
|
|
19384
19393
|
while (dir !== parse(dir).root) {
|
|
19385
|
-
const candidate =
|
|
19394
|
+
const candidate = join21(dir, "package.json");
|
|
19386
19395
|
const version = checkCandidate(candidate);
|
|
19387
19396
|
if (version) {
|
|
19388
19397
|
return version;
|
|
@@ -20023,7 +20032,7 @@ __export(exports_mobileUpdate, {
|
|
|
20023
20032
|
parseMobileUpdateManifest: () => parseMobileUpdateManifest
|
|
20024
20033
|
});
|
|
20025
20034
|
import {
|
|
20026
|
-
createHash as
|
|
20035
|
+
createHash as createHash16,
|
|
20027
20036
|
createHmac,
|
|
20028
20037
|
createPrivateKey,
|
|
20029
20038
|
createPublicKey as createPublicKey2,
|
|
@@ -20033,7 +20042,7 @@ import {
|
|
|
20033
20042
|
verify as verify2,
|
|
20034
20043
|
X509Certificate as X509Certificate3
|
|
20035
20044
|
} from "crypto";
|
|
20036
|
-
import { readFile as
|
|
20045
|
+
import { readFile as readFile24, stat as stat5 } from "fs/promises";
|
|
20037
20046
|
import path from "path";
|
|
20038
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) => {
|
|
20039
20048
|
if (typeof value !== "string" || value.length === 0)
|
|
@@ -20183,7 +20192,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20183
20192
|
if (!prefix || prefix.split("/").some((segment) => segment === "." || segment === ".."))
|
|
20184
20193
|
throw new MobileUpdateRegistryError("Mobile update prefix is invalid");
|
|
20185
20194
|
return prefix;
|
|
20186
|
-
}, appHash = (appId) =>
|
|
20195
|
+
}, appHash = (appId) => createHash16("sha256").update(appId).digest("hex"), digest = (bytes) => createHash16("sha256").update(bytes).digest("hex"), json = (value) => new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
|
|
20187
20196
|
`), decode2 = (value) => JSON.parse(new TextDecoder().decode(value)), fileDigest = async (file) => {
|
|
20188
20197
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
20189
20198
|
for await (const chunk of file.stream())
|
|
@@ -20194,7 +20203,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20194
20203
|
return false;
|
|
20195
20204
|
if (input.rollout === 1)
|
|
20196
20205
|
return true;
|
|
20197
|
-
const value =
|
|
20206
|
+
const value = createHash16("sha256").update(`${input.appId}\x00${input.channel}\x00${input.releaseId}\x00${input.installationId}`).digest().readUInt32BE(0);
|
|
20198
20207
|
return value / 4294967296 < input.rollout;
|
|
20199
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) => {
|
|
20200
20209
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
|
|
@@ -21066,7 +21075,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21066
21075
|
verifyManifestSignature(manifest, options.publicKeys);
|
|
21067
21076
|
await assertNotMarked(manifest.appId, manifest.releaseId);
|
|
21068
21077
|
const localRoot = path.resolve(input.releaseDirectory);
|
|
21069
|
-
const localManifest = parseMobileUpdateManifest(JSON.parse(await
|
|
21078
|
+
const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile24(path.join(localRoot, "update.json"), "utf8")));
|
|
21070
21079
|
if (JSON.stringify(localManifest) !== JSON.stringify(manifest))
|
|
21071
21080
|
throw new MobileUpdateRegistryError("Local mobile update manifest changed");
|
|
21072
21081
|
const existing = await readManifest(manifest.appId, manifest.releaseId);
|
|
@@ -21199,7 +21208,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21199
21208
|
}
|
|
21200
21209
|
};
|
|
21201
21210
|
}, expoUpdateId = (releaseId) => {
|
|
21202
|
-
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) : createHash16("sha256").update(releaseId).digest("hex").slice(0, 32);
|
|
21203
21212
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20)}`;
|
|
21204
21213
|
}, expoContentType = (extension2, launch) => {
|
|
21205
21214
|
if (launch)
|
|
@@ -21352,8 +21361,8 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21352
21361
|
});
|
|
21353
21362
|
}
|
|
21354
21363
|
const pathname = new URL(request.url).pathname.replace(/^\/+/, "");
|
|
21355
|
-
const
|
|
21356
|
-
if (request.method === "POST" &&
|
|
21364
|
+
const relative18 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
|
|
21365
|
+
if (request.method === "POST" && relative18 === "health") {
|
|
21357
21366
|
if (!options.registry.recordUpdateHealth)
|
|
21358
21367
|
return new Response(null, { status: 404 });
|
|
21359
21368
|
const appId = request.headers.get("x-absolute-mobile-app");
|
|
@@ -21396,7 +21405,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21396
21405
|
}
|
|
21397
21406
|
if (request.method !== "GET")
|
|
21398
21407
|
return new Response(null, { status: 405 });
|
|
21399
|
-
if (
|
|
21408
|
+
if (relative18 === "update.json") {
|
|
21400
21409
|
const expoProtocolVersion = request.headers.get("expo-protocol-version");
|
|
21401
21410
|
const expoProtocol = expoProtocolVersion !== null;
|
|
21402
21411
|
if (expoProtocol && expoProtocolVersion !== "1")
|
|
@@ -21514,7 +21523,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21514
21523
|
}
|
|
21515
21524
|
});
|
|
21516
21525
|
}
|
|
21517
|
-
const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(
|
|
21526
|
+
const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative18);
|
|
21518
21527
|
if (!match?.[1] || !match[2])
|
|
21519
21528
|
return new Response(null, { status: 404 });
|
|
21520
21529
|
const file = await options.registry.readUpdateFile({
|
|
@@ -21607,14 +21616,14 @@ import {
|
|
|
21607
21616
|
createPublicKey as createPublicKey3,
|
|
21608
21617
|
X509Certificate as X509Certificate4
|
|
21609
21618
|
} from "crypto";
|
|
21610
|
-
import { access as
|
|
21611
|
-
import { dirname as dirname19, isAbsolute as isAbsolute9, relative as
|
|
21619
|
+
import { access as access17, mkdir as mkdir18 } from "fs/promises";
|
|
21620
|
+
import { dirname as dirname19, isAbsolute as isAbsolute9, relative as relative18, resolve as resolve20, sep as sep11 } from "path";
|
|
21612
21621
|
import { pathToFileURL as pathToFileURL5 } from "url";
|
|
21613
21622
|
import { Elysia as Elysia4 } from "elysia";
|
|
21614
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) => {
|
|
21615
21624
|
const root = resolve20(projectRoot);
|
|
21616
21625
|
const path2 = resolve20(root, requested);
|
|
21617
|
-
const projectRelative =
|
|
21626
|
+
const projectRelative = relative18(root, path2);
|
|
21618
21627
|
if (projectRelative === ".." || projectRelative.startsWith(`..${sep11}`) || isAbsolute9(projectRelative))
|
|
21619
21628
|
throw new TypeError("mobile.updates.server.registry must remain inside the project.");
|
|
21620
21629
|
return path2;
|
|
@@ -21638,7 +21647,7 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
|
|
|
21638
21647
|
return metadata;
|
|
21639
21648
|
}, loadAbsoluteMobileUpdateServerModule = async (projectRoot, requestedModulePath = DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE) => {
|
|
21640
21649
|
const modulePath = projectPath3(projectRoot, requestedModulePath);
|
|
21641
|
-
await
|
|
21650
|
+
await access17(modulePath).catch(() => {
|
|
21642
21651
|
throw new TypeError(`Mobile update server registry does not exist: ${modulePath}. Run \`absolute mobile update provision\`.`);
|
|
21643
21652
|
});
|
|
21644
21653
|
const loaded = await import(pathToFileURL5(modulePath).href);
|
|
@@ -21827,7 +21836,7 @@ ${generated}`);
|
|
|
21827
21836
|
}, writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
21828
21837
|
const path2 = projectPath3(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
|
|
21829
21838
|
if (!options.force) {
|
|
21830
|
-
await
|
|
21839
|
+
await access17(path2).then(() => {
|
|
21831
21840
|
throw new TypeError(`Mobile update registry already exists: ${path2}. Pass --force to replace it.`);
|
|
21832
21841
|
}, () => {
|
|
21833
21842
|
return;
|
|
@@ -25938,6 +25947,29 @@ var acquireAbsoluteRemoteMacReleaseLease = async (project, options = {}) => {
|
|
|
25938
25947
|
release: () => runOwned(`rm -rf ${shellQuote(path)}`)
|
|
25939
25948
|
};
|
|
25940
25949
|
};
|
|
25950
|
+
var cleanAbsoluteRemoteMacWorkspace = async (profile, transport) => {
|
|
25951
|
+
const root = profile.workspaceRoot;
|
|
25952
|
+
const projects = posix.join(root, "projects");
|
|
25953
|
+
const script = [
|
|
25954
|
+
"set -eu",
|
|
25955
|
+
`mkdir -p ${shellQuote(root)}`,
|
|
25956
|
+
`project_staging=$(find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
|
|
25957
|
+
`mobile_staging=$(find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
|
|
25958
|
+
`count=$((project_staging+mobile_staging))`,
|
|
25959
|
+
`find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
|
|
25960
|
+
`find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
|
|
25961
|
+
`printf '%s\\n' "$count"`
|
|
25962
|
+
].join("; ");
|
|
25963
|
+
const result = await (transport?.capture ?? defaultTransport.capture)([
|
|
25964
|
+
...absoluteRemoteMacSshBase(profile),
|
|
25965
|
+
"/bin/sh -lc",
|
|
25966
|
+
shellQuote(script)
|
|
25967
|
+
]);
|
|
25968
|
+
const removed = Number(requireRemoteSuccess(result, "Remote Mac workspace cleanup"));
|
|
25969
|
+
if (!Number.isSafeInteger(removed) || removed < 0)
|
|
25970
|
+
throw new TypeError("Remote Mac returned an invalid cleanup result.");
|
|
25971
|
+
return { profile: profile.name, removed, workspaceRoot: root };
|
|
25972
|
+
};
|
|
25941
25973
|
var inspectAbsoluteRemoteMacWorkspace = async (profile, transport) => {
|
|
25942
25974
|
const root = profile.workspaceRoot;
|
|
25943
25975
|
const script = [
|
|
@@ -25966,29 +25998,6 @@ var inspectAbsoluteRemoteMacWorkspace = async (profile, transport) => {
|
|
|
25966
25998
|
workspaceRoot: root
|
|
25967
25999
|
};
|
|
25968
26000
|
};
|
|
25969
|
-
var cleanAbsoluteRemoteMacWorkspace = async (profile, transport) => {
|
|
25970
|
-
const root = profile.workspaceRoot;
|
|
25971
|
-
const projects = posix.join(root, "projects");
|
|
25972
|
-
const script = [
|
|
25973
|
-
"set -eu",
|
|
25974
|
-
`mkdir -p ${shellQuote(root)}`,
|
|
25975
|
-
`project_staging=$(find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
|
|
25976
|
-
`mobile_staging=$(find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
|
|
25977
|
-
`count=$((project_staging+mobile_staging))`,
|
|
25978
|
-
`find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
|
|
25979
|
-
`find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
|
|
25980
|
-
`printf '%s\\n' "$count"`
|
|
25981
|
-
].join("; ");
|
|
25982
|
-
const result = await (transport?.capture ?? defaultTransport.capture)([
|
|
25983
|
-
...absoluteRemoteMacSshBase(profile),
|
|
25984
|
-
"/bin/sh -lc",
|
|
25985
|
-
shellQuote(script)
|
|
25986
|
-
]);
|
|
25987
|
-
const removed = Number(requireRemoteSuccess(result, "Remote Mac workspace cleanup"));
|
|
25988
|
-
if (!Number.isSafeInteger(removed) || removed < 0)
|
|
25989
|
-
throw new TypeError("Remote Mac returned an invalid cleanup result.");
|
|
25990
|
-
return { profile: profile.name, removed, workspaceRoot: root };
|
|
25991
|
-
};
|
|
25992
26001
|
var installAbsoluteRemoteMacAgent = async (project) => {
|
|
25993
26002
|
const artifact = await materializeAbsoluteRemoteMacAgent(project.projectRoot);
|
|
25994
26003
|
const directory = posix.join(project.profile.workspaceRoot, "agents", `protocol-${ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION}`, artifact.sha256);
|
|
@@ -26334,7 +26343,7 @@ var buildAbsoluteRemoteIosRelease = async (options) => {
|
|
|
26334
26343
|
heartbeat = undefined;
|
|
26335
26344
|
});
|
|
26336
26345
|
}, REMOTE_RELEASE_LEASE_HEARTBEAT_MS);
|
|
26337
|
-
heartbeatTimer
|
|
26346
|
+
unrefTimer(heartbeatTimer);
|
|
26338
26347
|
try {
|
|
26339
26348
|
const syncStartedAt = performance.now();
|
|
26340
26349
|
if (options.syncProject)
|
|
@@ -26477,7 +26486,7 @@ var buildAbsoluteRemoteIosRelease = async (options) => {
|
|
|
26477
26486
|
}
|
|
26478
26487
|
};
|
|
26479
26488
|
var startAbsoluteRemoteExpoIosDevSession = async (options) => {
|
|
26480
|
-
|
|
26489
|
+
let session = await startAbsoluteRemoteDevSession({
|
|
26481
26490
|
certificateAuthorityPath: options.certificateAuthorityPath,
|
|
26482
26491
|
deviceIdentifier: options.deviceIdentifier,
|
|
26483
26492
|
https: options.https,
|
|
@@ -26493,12 +26502,18 @@ var startAbsoluteRemoteExpoIosDevSession = async (options) => {
|
|
|
26493
26502
|
syncProject: options.syncProject,
|
|
26494
26503
|
transport: options.transport
|
|
26495
26504
|
});
|
|
26496
|
-
|
|
26505
|
+
const expoSession = {
|
|
26497
26506
|
close: session.close,
|
|
26498
26507
|
metroPort: options.metroPort,
|
|
26499
26508
|
platforms: ["ios"],
|
|
26500
|
-
timings: session.timings
|
|
26509
|
+
timings: session.timings,
|
|
26510
|
+
rebuild: async () => {
|
|
26511
|
+
session = await session.rebuild();
|
|
26512
|
+
expoSession.timings = session.timings;
|
|
26513
|
+
return expoSession;
|
|
26514
|
+
}
|
|
26501
26515
|
};
|
|
26516
|
+
return expoSession;
|
|
26502
26517
|
};
|
|
26503
26518
|
var startAbsoluteRemoteIosDevSession = (options) => startAbsoluteRemoteDevSession(options);
|
|
26504
26519
|
var startAbsoluteRemoteDevSession = async (options) => {
|
|
@@ -27843,6 +27858,27 @@ public final class AbsoluteMobileObservabilityModule: Module, MXMetricManagerSub
|
|
|
27843
27858
|
}
|
|
27844
27859
|
}
|
|
27845
27860
|
}
|
|
27861
|
+
|
|
27862
|
+
#if DEBUG
|
|
27863
|
+
AsyncFunction("enqueueForTesting") { (options: [String: String]) -> Bool in
|
|
27864
|
+
guard let testId = options["testId"],
|
|
27865
|
+
testId.range(of: "^[A-Za-z0-9._:-]{1,128}$", options: .regularExpression) != nil else { return false }
|
|
27866
|
+
let key = "absolute-native-observability-test-id"
|
|
27867
|
+
guard UserDefaults.standard.string(forKey: key) != testId else { return false }
|
|
27868
|
+
UserDefaults.standard.set(testId, forKey: key)
|
|
27869
|
+
Self.queue.sync {
|
|
27870
|
+
Self.enqueue(
|
|
27871
|
+
kind: "crash",
|
|
27872
|
+
occurredAt: Date().timeIntervalSince1970 * 1000,
|
|
27873
|
+
details: [
|
|
27874
|
+
"message": "token=mobile-observability-secret",
|
|
27875
|
+
"source": "absolutejs-conformance"
|
|
27876
|
+
]
|
|
27877
|
+
)
|
|
27878
|
+
}
|
|
27879
|
+
return true
|
|
27880
|
+
}
|
|
27881
|
+
#endif
|
|
27846
27882
|
}
|
|
27847
27883
|
|
|
27848
27884
|
private static func root() -> URL? {
|
|
@@ -28126,6 +28162,7 @@ import { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';
|
|
|
28126
28162
|
type NativeObservabilityModule = {
|
|
28127
28163
|
acknowledge(options: { ids: string[] }): Promise<void>;
|
|
28128
28164
|
crashForTesting(options: { testId: string }): Promise<boolean>;
|
|
28165
|
+
enqueueForTesting(options: { testId: string }): Promise<boolean>;
|
|
28129
28166
|
pending(): Promise<{ reports: unknown[] }>;
|
|
28130
28167
|
};
|
|
28131
28168
|
type NativeReport = { details: Record<string, unknown>; id: string; kind: string; occurredAt: number; platform: 'android' | 'ios' };
|
|
@@ -28187,6 +28224,12 @@ export const startAbsoluteExpoNativeObservability = () => {
|
|
|
28187
28224
|
return drain();
|
|
28188
28225
|
};
|
|
28189
28226
|
export const crashAbsoluteExpoNativeObservabilityForTesting = (testId: string) => native.crashForTesting({ testId });
|
|
28227
|
+
export const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: string) => {
|
|
28228
|
+
await drain();
|
|
28229
|
+
const enqueued = await native.enqueueForTesting({ testId });
|
|
28230
|
+
await drain();
|
|
28231
|
+
return enqueued;
|
|
28232
|
+
};
|
|
28190
28233
|
`;
|
|
28191
28234
|
var absoluteExpoNativeObservabilityFiles = (project) => new Map([
|
|
28192
28235
|
[
|
|
@@ -28310,7 +28353,7 @@ var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map
|
|
|
28310
28353
|
var expoPackage = (auth, sync, devices, updates) => ({
|
|
28311
28354
|
dependencies: {
|
|
28312
28355
|
"@absolutejs/devices": "0.7.0",
|
|
28313
|
-
"@absolutejs/devices-expo": "0.0.
|
|
28356
|
+
"@absolutejs/devices-expo": "0.0.3",
|
|
28314
28357
|
...auth ? {
|
|
28315
28358
|
"@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
|
|
28316
28359
|
[ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
|
|
@@ -28917,7 +28960,7 @@ var webHostSource = (config, auth, sync) => {
|
|
|
28917
28960
|
const nativeRoutePatterns = nativeRoutes.map((route) => route.split("/").filter(Boolean));
|
|
28918
28961
|
return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
|
|
28919
28962
|
import { router, usePathname } from 'expo-router';
|
|
28920
|
-
import { useEffect, useRef, useState } from 'react';
|
|
28963
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
28921
28964
|
import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
|
|
28922
28965
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
28923
28966
|
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
|
|
@@ -29072,17 +29115,21 @@ const authStatus = async () => {
|
|
|
29072
29115
|
return { principal: principal ? { namespace: principal.namespace } : null, user };` : "throw new Error('Expo Auth is not configured.');"}
|
|
29073
29116
|
};
|
|
29074
29117
|
|
|
29075
|
-
export
|
|
29076
|
-
|
|
29118
|
+
export type AbsoluteWebHostProps = { path?: string };
|
|
29119
|
+
|
|
29120
|
+
export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
|
|
29121
|
+
const routerPathname = usePathname() || '/';
|
|
29122
|
+
const pathname = path?.startsWith('/') && !path.startsWith('//') ? path : routerPathname;
|
|
29077
29123
|
const safeAreaInsets = useSafeAreaInsets();
|
|
29078
29124
|
const webView = useRef<WebView>(null);
|
|
29079
29125
|
const devicesBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
29080
29126
|
const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
29081
29127
|
const [indexUri, setIndexUri] = useState<string>();
|
|
29082
|
-
const
|
|
29128
|
+
const canGoBack = useRef(false);
|
|
29083
29129
|
const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
|
|
29084
29130
|
const [devicesReady, setDevicesReady] = useState(false);
|
|
29085
29131
|
const activeWebPath = useRef(pathname);
|
|
29132
|
+
const webSource = useMemo(() => indexUri ? { uri: indexUri } : undefined, [indexUri]);
|
|
29086
29133
|
|
|
29087
29134
|
useEffect(() => {
|
|
29088
29135
|
if (!AUTH_ENABLED && !SYNC_ENABLED) return;
|
|
@@ -29140,7 +29187,7 @@ export function AbsoluteWebHost() {
|
|
|
29140
29187
|
if (!active) return;
|
|
29141
29188
|
respond({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
|
|
29142
29189
|
}).then(host => {
|
|
29143
|
-
if (!active) return void host.close();
|
|
29190
|
+
if (!active) return void Promise.resolve(host.close()).catch(() => undefined);
|
|
29144
29191
|
devicesBridge.current = host;
|
|
29145
29192
|
setDevicesReady(true);
|
|
29146
29193
|
});
|
|
@@ -29148,7 +29195,7 @@ export function AbsoluteWebHost() {
|
|
|
29148
29195
|
active = false;
|
|
29149
29196
|
const host = devicesBridge.current;
|
|
29150
29197
|
devicesBridge.current = undefined;
|
|
29151
|
-
void host
|
|
29198
|
+
if (host) void Promise.resolve(host.close()).catch(() => undefined);
|
|
29152
29199
|
};
|
|
29153
29200
|
}, []);
|
|
29154
29201
|
const hasOrigin = (source: string, origin: string) => {
|
|
@@ -29168,7 +29215,7 @@ export function AbsoluteWebHost() {
|
|
|
29168
29215
|
return;
|
|
29169
29216
|
}
|
|
29170
29217
|
if (message.kind === 'event' && message.event === 'back-unhandled') {
|
|
29171
|
-
if (canGoBack) webView.current?.goBack();
|
|
29218
|
+
if (canGoBack.current) webView.current?.goBack();
|
|
29172
29219
|
else BackHandler.exitApp();
|
|
29173
29220
|
return;
|
|
29174
29221
|
}
|
|
@@ -29202,22 +29249,27 @@ export function AbsoluteWebHost() {
|
|
|
29202
29249
|
}
|
|
29203
29250
|
};
|
|
29204
29251
|
|
|
29205
|
-
if (!
|
|
29252
|
+
if (!webSource || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
|
|
29206
29253
|
return <WebView
|
|
29207
29254
|
allowFileAccess
|
|
29208
29255
|
allowFileAccessFromFileURLs
|
|
29209
29256
|
allowUniversalAccessFromFileURLs={false}
|
|
29210
|
-
allowingReadAccessToURL={
|
|
29257
|
+
allowingReadAccessToURL={webSource.uri.slice(0, webSource.uri.lastIndexOf('/') + 1)}
|
|
29211
29258
|
injectedJavaScriptBeforeContentLoaded={bridgeBootstrap(pathname, safeAreaInsets)}
|
|
29212
29259
|
onMessage={onMessage}
|
|
29213
|
-
onNavigationStateChange={state =>
|
|
29260
|
+
onNavigationStateChange={state => {
|
|
29261
|
+
canGoBack.current = state.canGoBack;
|
|
29262
|
+
if (!DEV_ORIGIN || !hasOrigin(state.url, DEV_ORIGIN)) return;
|
|
29263
|
+
const route = new URL(state.url);
|
|
29264
|
+
activeWebPath.current = route.pathname + route.search + route.hash;
|
|
29265
|
+
}}
|
|
29214
29266
|
onShouldStartLoadWithRequest={request => {
|
|
29215
29267
|
if (request.url.startsWith('file:') || hasOrigin(request.url, PRODUCTION_ORIGIN) || DEV_ORIGIN && hasOrigin(request.url, DEV_ORIGIN)) return true;
|
|
29216
29268
|
void Linking.openURL(request.url);
|
|
29217
29269
|
return false;
|
|
29218
29270
|
}}
|
|
29219
29271
|
ref={webView}
|
|
29220
|
-
source={
|
|
29272
|
+
source={webSource}
|
|
29221
29273
|
style={styles.web}
|
|
29222
29274
|
/>;
|
|
29223
29275
|
}
|
|
@@ -30964,18 +31016,42 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
30964
31016
|
publishTiming("starting-metro", performance.now() - metroStarted);
|
|
30965
31017
|
await runNativeCommands(nativeCommands);
|
|
30966
31018
|
setState("ready");
|
|
30967
|
-
|
|
31019
|
+
let closed = false;
|
|
31020
|
+
let rebuildQueue = Promise.resolve();
|
|
31021
|
+
const session = {
|
|
30968
31022
|
metroPort: plan.metroPort,
|
|
30969
31023
|
platforms: options.platforms,
|
|
30970
31024
|
timings,
|
|
30971
31025
|
close: async () => {
|
|
31026
|
+
if (closed)
|
|
31027
|
+
return;
|
|
31028
|
+
closed = true;
|
|
30972
31029
|
options.signal?.removeEventListener("abort", abort);
|
|
31030
|
+
await rebuildQueue;
|
|
30973
31031
|
if (metro)
|
|
30974
31032
|
await stopProcess(metro);
|
|
30975
31033
|
await closeEnrollmentServer();
|
|
30976
31034
|
setState("closed");
|
|
31035
|
+
},
|
|
31036
|
+
rebuild: () => {
|
|
31037
|
+
const rebuild = rebuildQueue.then(async () => {
|
|
31038
|
+
if (closed)
|
|
31039
|
+
throw new Error("The Expo development session is closed.");
|
|
31040
|
+
if (prepareCommand)
|
|
31041
|
+
await runPrepareCommand(prepareCommand);
|
|
31042
|
+
await runNativeCommands(nativeCommands);
|
|
31043
|
+
setState("ready");
|
|
31044
|
+
return session;
|
|
31045
|
+
});
|
|
31046
|
+
rebuildQueue = rebuild.then(() => {
|
|
31047
|
+
return;
|
|
31048
|
+
}, () => {
|
|
31049
|
+
return;
|
|
31050
|
+
});
|
|
31051
|
+
return rebuild;
|
|
30977
31052
|
}
|
|
30978
31053
|
};
|
|
31054
|
+
return session;
|
|
30979
31055
|
} catch (error) {
|
|
30980
31056
|
options.signal?.removeEventListener("abort", abort);
|
|
30981
31057
|
if (metro)
|
|
@@ -30985,9 +31061,139 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
30985
31061
|
throw error;
|
|
30986
31062
|
}
|
|
30987
31063
|
};
|
|
31064
|
+
// src/mobile/expoNativeWatcher.ts
|
|
31065
|
+
import { watch as watch2 } from "fs";
|
|
31066
|
+
import { access as access12, readdir as readdir5, readFile as readFile16 } from "fs/promises";
|
|
31067
|
+
import { basename as basename5, join as join18, relative as relative12 } from "path";
|
|
31068
|
+
import { createHash as createHash13 } from "crypto";
|
|
31069
|
+
var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
|
|
31070
|
+
var ROOT_NATIVE_INPUTS2 = new Set([
|
|
31071
|
+
"absolute.config.js",
|
|
31072
|
+
"absolute.config.mjs",
|
|
31073
|
+
"absolute.config.ts",
|
|
31074
|
+
"absolutejs.config.js",
|
|
31075
|
+
"absolutejs.config.mjs",
|
|
31076
|
+
"absolutejs.config.ts",
|
|
31077
|
+
"bun.lock",
|
|
31078
|
+
"bun.lockb",
|
|
31079
|
+
"package.json"
|
|
31080
|
+
]);
|
|
31081
|
+
var EXPO_NATIVE_DIRECTORIES = ["modules", "plugins"];
|
|
31082
|
+
var exists5 = async (path) => access12(path).then(() => true, () => false);
|
|
31083
|
+
var filesIn = async (directory, prefix) => {
|
|
31084
|
+
if (!await exists5(directory))
|
|
31085
|
+
return [];
|
|
31086
|
+
const entries = await readdir5(directory, { withFileTypes: true });
|
|
31087
|
+
const nested = await Promise.all(entries.map((entry) => {
|
|
31088
|
+
const path = join18(directory, entry.name);
|
|
31089
|
+
const name = `${prefix}/${entry.name}`;
|
|
31090
|
+
if (entry.isDirectory())
|
|
31091
|
+
return filesIn(path, name);
|
|
31092
|
+
return Promise.resolve(entry.isFile() ? [{ name, path }] : []);
|
|
31093
|
+
}));
|
|
31094
|
+
return nested.flat().sort((left, right) => left.name.localeCompare(right.name));
|
|
31095
|
+
};
|
|
31096
|
+
var fingerprintAbsoluteExpoNativeInputs = async (options) => {
|
|
31097
|
+
const hash = createHash13("sha256");
|
|
31098
|
+
const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
|
|
31099
|
+
const path = join18(options.projectRoot, name);
|
|
31100
|
+
return await exists5(path) ? [{ name: `root/${name}`, path }] : [];
|
|
31101
|
+
}));
|
|
31102
|
+
const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join18(options.expoProjectDirectory, name), name)));
|
|
31103
|
+
const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
|
|
31104
|
+
const contents = await Promise.all(files.map(({ path }) => readFile16(path)));
|
|
31105
|
+
files.forEach(({ name }, index) => {
|
|
31106
|
+
hash.update(name);
|
|
31107
|
+
hash.update(contents[index] ?? Buffer.alloc(0));
|
|
31108
|
+
});
|
|
31109
|
+
return hash.digest("hex");
|
|
31110
|
+
};
|
|
31111
|
+
var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename5(path));
|
|
31112
|
+
var createAbsoluteExpoNativeWatcher = async (options) => {
|
|
31113
|
+
let fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
31114
|
+
let closed = false;
|
|
31115
|
+
let running = false;
|
|
31116
|
+
let timer;
|
|
31117
|
+
let rootInputChanged = false;
|
|
31118
|
+
const changedPaths = new Set;
|
|
31119
|
+
const watchers = [];
|
|
31120
|
+
const debounceMs = options.debounceMs ?? NATIVE_CHANGE_DEBOUNCE_MS2;
|
|
31121
|
+
const close = () => {
|
|
31122
|
+
if (closed)
|
|
31123
|
+
return;
|
|
31124
|
+
closed = true;
|
|
31125
|
+
if (timer)
|
|
31126
|
+
clearTimeout(timer);
|
|
31127
|
+
watchers.forEach((watcher) => watcher.close());
|
|
31128
|
+
options.signal?.removeEventListener("abort", close);
|
|
31129
|
+
};
|
|
31130
|
+
const schedule = () => {
|
|
31131
|
+
if (closed || running)
|
|
31132
|
+
return;
|
|
31133
|
+
if (timer)
|
|
31134
|
+
clearTimeout(timer);
|
|
31135
|
+
timer = setTimeout(() => void flush(), debounceMs);
|
|
31136
|
+
};
|
|
31137
|
+
const record = (path, root) => {
|
|
31138
|
+
if (closed)
|
|
31139
|
+
return;
|
|
31140
|
+
changedPaths.add(path);
|
|
31141
|
+
rootInputChanged ||= root;
|
|
31142
|
+
schedule();
|
|
31143
|
+
};
|
|
31144
|
+
const flush = async () => {
|
|
31145
|
+
timer = undefined;
|
|
31146
|
+
if (closed || running || changedPaths.size === 0)
|
|
31147
|
+
return;
|
|
31148
|
+
running = true;
|
|
31149
|
+
const paths = [...changedPaths].sort();
|
|
31150
|
+
const rootChanged = rootInputChanged;
|
|
31151
|
+
changedPaths.clear();
|
|
31152
|
+
rootInputChanged = false;
|
|
31153
|
+
try {
|
|
31154
|
+
const next = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
31155
|
+
if (next === fingerprint)
|
|
31156
|
+
return;
|
|
31157
|
+
await options.onChange({
|
|
31158
|
+
afterFingerprint: next,
|
|
31159
|
+
beforeFingerprint: fingerprint,
|
|
31160
|
+
paths,
|
|
31161
|
+
rootInputChanged: rootChanged
|
|
31162
|
+
});
|
|
31163
|
+
fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
31164
|
+
} catch (error) {
|
|
31165
|
+
options.onError?.(error);
|
|
31166
|
+
} finally {
|
|
31167
|
+
running = false;
|
|
31168
|
+
if (changedPaths.size > 0)
|
|
31169
|
+
schedule();
|
|
31170
|
+
}
|
|
31171
|
+
};
|
|
31172
|
+
const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
|
|
31173
|
+
const directory = join18(options.expoProjectDirectory, name);
|
|
31174
|
+
return await exists5(directory) ? [directory] : [];
|
|
31175
|
+
}))).flat();
|
|
31176
|
+
nativeDirectories.forEach((directory) => {
|
|
31177
|
+
watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
|
|
31178
|
+
if (!filename)
|
|
31179
|
+
return;
|
|
31180
|
+
record(relative12(options.expoProjectDirectory, join18(directory, String(filename))), false);
|
|
31181
|
+
}));
|
|
31182
|
+
});
|
|
31183
|
+
watchers.push(watch2(options.projectRoot, (_event, filename) => {
|
|
31184
|
+
if (!filename)
|
|
31185
|
+
return;
|
|
31186
|
+
const path = String(filename);
|
|
31187
|
+
if (isAbsoluteExpoNativeRootInput(path))
|
|
31188
|
+
record(path, true);
|
|
31189
|
+
}));
|
|
31190
|
+
watchers.forEach((watcher) => watcher.on("error", (error) => options.onError?.(error)));
|
|
31191
|
+
options.signal?.addEventListener("abort", close, { once: true });
|
|
31192
|
+
return { close };
|
|
31193
|
+
};
|
|
30988
31194
|
// src/mobile/expoUpdate.ts
|
|
30989
|
-
import { access as
|
|
30990
|
-
import { dirname as dirname12, extname as extname4, join as
|
|
31195
|
+
import { access as access13, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile14 } from "fs/promises";
|
|
31196
|
+
import { dirname as dirname12, extname as extname4, join as join19 } from "path";
|
|
30991
31197
|
var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
|
|
30992
31198
|
var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
|
|
30993
31199
|
var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -31053,7 +31259,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
|
|
|
31053
31259
|
};
|
|
31054
31260
|
};
|
|
31055
31261
|
var finalizeAbsoluteExpoUpdateExport = async (options) => {
|
|
31056
|
-
const metadata = JSON.parse(await
|
|
31262
|
+
const metadata = JSON.parse(await readFile17(join19(options.exportDirectory, "metadata.json"), "utf8"));
|
|
31057
31263
|
if (!object4(metadata) || !object4(metadata.fileMetadata))
|
|
31058
31264
|
throw new TypeError("Expo export metadata.json is invalid.");
|
|
31059
31265
|
const descriptor = parseAbsoluteExpoUpdateDescriptor({
|
|
@@ -31064,10 +31270,10 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
|
|
|
31064
31270
|
runtimeVersion: options.runtimeVersion
|
|
31065
31271
|
});
|
|
31066
31272
|
const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
|
|
31067
|
-
await Promise.all(referenced.map(({ path }) =>
|
|
31273
|
+
await Promise.all(referenced.map(({ path }) => access13(join19(options.exportDirectory, path)).catch(() => {
|
|
31068
31274
|
throw new TypeError(`Expo export metadata references missing asset ${path}.`);
|
|
31069
31275
|
})));
|
|
31070
|
-
const destination =
|
|
31276
|
+
const destination = join19(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
|
|
31071
31277
|
await mkdir13(dirname12(destination), { recursive: true });
|
|
31072
31278
|
await writeFile14(destination, `${JSON.stringify(descriptor, null, "\t")}
|
|
31073
31279
|
`);
|
|
@@ -31079,8 +31285,8 @@ init_config();
|
|
|
31079
31285
|
|
|
31080
31286
|
// src/mobile/ciWorkflow.ts
|
|
31081
31287
|
import { existsSync as existsSync4 } from "fs";
|
|
31082
|
-
import { access as
|
|
31083
|
-
import { dirname as dirname13, extname as extname5, relative as
|
|
31288
|
+
import { access as access14, mkdir as mkdir14, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
|
|
31289
|
+
import { dirname as dirname13, extname as extname5, relative as relative13, resolve as resolve15, sep as sep8 } from "path";
|
|
31084
31290
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
|
|
31085
31291
|
var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
|
|
31086
31292
|
var CI_ENV_INDENTATION = 6;
|
|
@@ -31099,9 +31305,9 @@ var RESERVED_SECRET_NAMES = new Set([
|
|
|
31099
31305
|
"APP_STORE_CONNECT_KEY_ID",
|
|
31100
31306
|
"APP_STORE_CONNECT_PRIVATE_KEY_BASE64"
|
|
31101
31307
|
]);
|
|
31102
|
-
var
|
|
31308
|
+
var exists6 = async (path) => {
|
|
31103
31309
|
try {
|
|
31104
|
-
await
|
|
31310
|
+
await access14(path);
|
|
31105
31311
|
return true;
|
|
31106
31312
|
} catch {
|
|
31107
31313
|
return false;
|
|
@@ -31111,7 +31317,7 @@ var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
|
|
|
31111
31317
|
var projectPath = (projectRoot, value, field2, options = {}) => {
|
|
31112
31318
|
const root = resolve15(projectRoot);
|
|
31113
31319
|
const path = resolve15(root, value);
|
|
31114
|
-
const portable =
|
|
31320
|
+
const portable = relative13(root, path).replaceAll("\\", "/");
|
|
31115
31321
|
if (portable === ".." || portable.startsWith(`..${sep8}`) || portable.startsWith("../") || portable === "") {
|
|
31116
31322
|
throw new TypeError(`${field2} must remain inside the project root.`);
|
|
31117
31323
|
}
|
|
@@ -31125,7 +31331,7 @@ var workflowOutputPath = (projectRoot, value) => {
|
|
|
31125
31331
|
const root = resolve15(projectRoot);
|
|
31126
31332
|
const workflows = resolve15(root, ".github/workflows");
|
|
31127
31333
|
const path = resolve15(root, value ?? ".github/workflows/absolute-mobile.yml");
|
|
31128
|
-
const portable =
|
|
31334
|
+
const portable = relative13(workflows, path);
|
|
31129
31335
|
if (portable === ".." || portable.startsWith(`..${sep8}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
|
|
31130
31336
|
throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
|
|
31131
31337
|
}
|
|
@@ -31555,9 +31761,9 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
|
|
|
31555
31761
|
var writeAbsoluteMobileGithubWorkflow = async (options) => {
|
|
31556
31762
|
const path = workflowOutputPath(options.projectRoot, options.outputPath);
|
|
31557
31763
|
const generated = createAbsoluteMobileGithubWorkflow(options);
|
|
31558
|
-
const previous = await
|
|
31764
|
+
const previous = await exists6(path) ? await readFile18(path, "utf8") : undefined;
|
|
31559
31765
|
if (previous !== undefined && previous !== generated.workflow && !options.force)
|
|
31560
|
-
throw new TypeError(`${
|
|
31766
|
+
throw new TypeError(`${relative13(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
|
|
31561
31767
|
if (previous !== generated.workflow) {
|
|
31562
31768
|
await mkdir14(dirname13(path), { recursive: true });
|
|
31563
31769
|
await writeFile15(path, generated.workflow);
|
|
@@ -31578,15 +31784,15 @@ init_materializedBundle();
|
|
|
31578
31784
|
init_mobilePreview();
|
|
31579
31785
|
|
|
31580
31786
|
// src/mobile/nativeDeepLinks.ts
|
|
31581
|
-
import { readFile as
|
|
31582
|
-
import { join as
|
|
31787
|
+
import { readFile as readFile19, rename as rename12, writeFile as writeFile16 } from "fs/promises";
|
|
31788
|
+
import { join as join22 } from "path";
|
|
31583
31789
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
31584
31790
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
31585
31791
|
var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
31586
31792
|
var NOT_FOUND = -1;
|
|
31587
31793
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
31588
31794
|
var writeChangedFile = async (path, source) => {
|
|
31589
|
-
const current = await
|
|
31795
|
+
const current = await readFile19(path, "utf8");
|
|
31590
31796
|
if (current === source)
|
|
31591
31797
|
return false;
|
|
31592
31798
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -31636,8 +31842,8 @@ ${hosts}
|
|
|
31636
31842
|
`;
|
|
31637
31843
|
};
|
|
31638
31844
|
var configureAndroid = async (config) => {
|
|
31639
|
-
const path =
|
|
31640
|
-
const source = await
|
|
31845
|
+
const path = join22(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
31846
|
+
const source = await readFile19(path, "utf8");
|
|
31641
31847
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
31642
31848
|
if (mainActivity === NOT_FOUND) {
|
|
31643
31849
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -31662,8 +31868,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
31662
31868
|
${END_MARKER}
|
|
31663
31869
|
`;
|
|
31664
31870
|
var configureIosInfo = async (config) => {
|
|
31665
|
-
const path =
|
|
31666
|
-
const source = await
|
|
31871
|
+
const path = join22(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
31872
|
+
const source = await readFile19(path, "utf8");
|
|
31667
31873
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
31668
31874
|
${END_MARKER}
|
|
31669
31875
|
`;
|
|
@@ -31686,10 +31892,10 @@ ${domains}
|
|
|
31686
31892
|
`;
|
|
31687
31893
|
};
|
|
31688
31894
|
var configureIosEntitlements = async (config) => {
|
|
31689
|
-
const path =
|
|
31895
|
+
const path = join22(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
31690
31896
|
let current = "";
|
|
31691
31897
|
try {
|
|
31692
|
-
current = await
|
|
31898
|
+
current = await readFile19(path, "utf8");
|
|
31693
31899
|
} catch (error) {
|
|
31694
31900
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
31695
31901
|
throw error;
|
|
@@ -31704,8 +31910,8 @@ var configureIosEntitlements = async (config) => {
|
|
|
31704
31910
|
return true;
|
|
31705
31911
|
};
|
|
31706
31912
|
var configureIosProject = async (config) => {
|
|
31707
|
-
const path =
|
|
31708
|
-
const source = await
|
|
31913
|
+
const path = join22(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
31914
|
+
const source = await readFile19(path, "utf8");
|
|
31709
31915
|
const declarations = [
|
|
31710
31916
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
31711
31917
|
].map((match) => match[1]);
|
|
@@ -31744,8 +31950,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
31744
31950
|
};
|
|
31745
31951
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
31746
31952
|
init_deviceCapabilities();
|
|
31747
|
-
import { readFile as
|
|
31748
|
-
import { join as
|
|
31953
|
+
import { readFile as readFile20, rename as rename13, writeFile as writeFile17 } from "fs/promises";
|
|
31954
|
+
import { join as join23 } from "path";
|
|
31749
31955
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
31750
31956
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
31751
31957
|
var NOT_FOUND2 = -1;
|
|
@@ -31755,7 +31961,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
31755
31961
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
31756
31962
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
31757
31963
|
var writeChangedFile2 = async (path, source) => {
|
|
31758
|
-
const current = await
|
|
31964
|
+
const current = await readFile20(path, "utf8");
|
|
31759
31965
|
if (current === source)
|
|
31760
31966
|
return false;
|
|
31761
31967
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -31775,7 +31981,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
31775
31981
|
};
|
|
31776
31982
|
var optionalSource = async (path) => {
|
|
31777
31983
|
try {
|
|
31778
|
-
return await
|
|
31984
|
+
return await readFile20(path, "utf8");
|
|
31779
31985
|
} catch (error) {
|
|
31780
31986
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
31781
31987
|
return null;
|
|
@@ -31895,8 +32101,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
|
|
|
31895
32101
|
var configureIosPrivacyProject = async (config, requirements) => {
|
|
31896
32102
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
31897
32103
|
return false;
|
|
31898
|
-
const projectPath2 =
|
|
31899
|
-
const project = await
|
|
32104
|
+
const projectPath2 = join23(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
32105
|
+
const project = await readFile20(projectPath2, "utf8");
|
|
31900
32106
|
return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
|
|
31901
32107
|
};
|
|
31902
32108
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -31948,8 +32154,8 @@ ${next.slice(index)}`;
|
|
|
31948
32154
|
return next;
|
|
31949
32155
|
};
|
|
31950
32156
|
var configureIos2 = async (config, plan) => {
|
|
31951
|
-
const path =
|
|
31952
|
-
const source = await
|
|
32157
|
+
const path = join23(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
32158
|
+
const source = await readFile20(path, "utf8");
|
|
31953
32159
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
31954
32160
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
31955
32161
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -31969,7 +32175,7 @@ ${content}
|
|
|
31969
32175
|
${END_MARKER2}
|
|
31970
32176
|
` : "";
|
|
31971
32177
|
const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
|
|
31972
|
-
const privacyPath =
|
|
32178
|
+
const privacyPath = join23(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
31973
32179
|
const privacyCurrent = await optionalSource(privacyPath);
|
|
31974
32180
|
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
31975
32181
|
const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
|
|
@@ -31980,7 +32186,7 @@ ${content}
|
|
|
31980
32186
|
return infoChanged || privacyChanged || projectChanged || pushChanged;
|
|
31981
32187
|
};
|
|
31982
32188
|
var configureIosPushNotifications = async (config, enabled) => {
|
|
31983
|
-
const entitlementsPath =
|
|
32189
|
+
const entitlementsPath = join23(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
31984
32190
|
const entitlements = await optionalSource(entitlementsPath);
|
|
31985
32191
|
if (entitlements === null && !enabled)
|
|
31986
32192
|
return false;
|
|
@@ -31992,7 +32198,7 @@ var configureIosPushNotifications = async (config, enabled) => {
|
|
|
31992
32198
|
<!-- ${PUSH_END_MARKER} -->
|
|
31993
32199
|
` : "";
|
|
31994
32200
|
const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
|
|
31995
|
-
const delegatePath =
|
|
32201
|
+
const delegatePath = join23(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
31996
32202
|
const delegate = await optionalSource(delegatePath);
|
|
31997
32203
|
if (delegate === null && !enabled)
|
|
31998
32204
|
return false;
|
|
@@ -32041,8 +32247,8 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
32041
32247
|
return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
|
|
32042
32248
|
};
|
|
32043
32249
|
var configureAndroid2 = async (config, plan) => {
|
|
32044
|
-
const path =
|
|
32045
|
-
const source = await
|
|
32250
|
+
const path = join23(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
32251
|
+
const source = await readFile20(path, "utf8");
|
|
32046
32252
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
32047
32253
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
32048
32254
|
`);
|
|
@@ -32077,7 +32283,7 @@ ${content}
|
|
|
32077
32283
|
throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
|
|
32078
32284
|
const [manifestChanged, firebaseChanged] = await Promise.all([
|
|
32079
32285
|
writeChangedFile2(path, nextManifest),
|
|
32080
|
-
writeOptionalChangedFile(
|
|
32286
|
+
writeOptionalChangedFile(join23(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
|
|
32081
32287
|
]);
|
|
32082
32288
|
return manifestChanged || firebaseChanged;
|
|
32083
32289
|
};
|
|
@@ -32097,13 +32303,13 @@ init_nativeAuth();
|
|
|
32097
32303
|
// src/mobile/nativeUpdates.ts
|
|
32098
32304
|
import {
|
|
32099
32305
|
mkdir as mkdir15,
|
|
32100
|
-
readFile as
|
|
32101
|
-
readdir as
|
|
32306
|
+
readFile as readFile21,
|
|
32307
|
+
readdir as readdir6,
|
|
32102
32308
|
rename as rename14,
|
|
32103
32309
|
rm as rm11,
|
|
32104
32310
|
writeFile as writeFile18
|
|
32105
32311
|
} from "fs/promises";
|
|
32106
|
-
import { dirname as dirname15, join as
|
|
32312
|
+
import { dirname as dirname15, join as join24 } from "path";
|
|
32107
32313
|
var START = "// absolutejs:mobile-updates:start";
|
|
32108
32314
|
var END = "// absolutejs:mobile-updates:end";
|
|
32109
32315
|
var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
|
|
@@ -32111,7 +32317,7 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
|
|
|
32111
32317
|
var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
|
|
32112
32318
|
var optionalSource2 = async (path) => {
|
|
32113
32319
|
try {
|
|
32114
|
-
return await
|
|
32320
|
+
return await readFile21(path, "utf8");
|
|
32115
32321
|
} catch (error) {
|
|
32116
32322
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32117
32323
|
return null;
|
|
@@ -32273,9 +32479,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
|
|
|
32273
32479
|
${PLUGIN_END}
|
|
32274
32480
|
`;
|
|
32275
32481
|
var configureIos3 = async (config, enabled) => {
|
|
32276
|
-
const path =
|
|
32277
|
-
const capacitorConfigPath =
|
|
32278
|
-
let source = await
|
|
32482
|
+
const path = join24(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
32483
|
+
const capacitorConfigPath = join24(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
32484
|
+
let source = await readFile21(path, "utf8");
|
|
32279
32485
|
const launch = source.indexOf("didFinishLaunchingWithOptions");
|
|
32280
32486
|
const brace = launch < 0 ? -1 : source.indexOf("{", launch);
|
|
32281
32487
|
const launchRegion = enabled ? ` ${START}
|
|
@@ -32286,7 +32492,7 @@ var configureIos3 = async (config, enabled) => {
|
|
|
32286
32492
|
`, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
|
|
32287
32493
|
const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
|
|
32288
32494
|
source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
|
|
32289
|
-
const capacitorConfigSource2 = await
|
|
32495
|
+
const capacitorConfigSource2 = await readFile21(capacitorConfigPath, "utf8");
|
|
32290
32496
|
let capacitorConfig;
|
|
32291
32497
|
try {
|
|
32292
32498
|
const value = JSON.parse(capacitorConfigSource2);
|
|
@@ -32459,19 +32665,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
|
|
|
32459
32665
|
var androidActivityInRoot = async (root) => {
|
|
32460
32666
|
let entries;
|
|
32461
32667
|
try {
|
|
32462
|
-
entries = await
|
|
32668
|
+
entries = await readdir6(root, { recursive: true });
|
|
32463
32669
|
} catch (error) {
|
|
32464
32670
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32465
32671
|
return;
|
|
32466
32672
|
throw error;
|
|
32467
32673
|
}
|
|
32468
32674
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
32469
|
-
return candidate ?
|
|
32675
|
+
return candidate ? join24(root, candidate) : undefined;
|
|
32470
32676
|
};
|
|
32471
32677
|
var androidActivity = async (config) => {
|
|
32472
32678
|
const roots = [
|
|
32473
|
-
|
|
32474
|
-
|
|
32679
|
+
join24(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
32680
|
+
join24(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
32475
32681
|
];
|
|
32476
32682
|
const candidates = await Promise.all(roots.map(androidActivityInRoot));
|
|
32477
32683
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -32570,12 +32776,12 @@ var injectAndroidActivity = (source, enabled) => {
|
|
|
32570
32776
|
};
|
|
32571
32777
|
var configureAndroid3 = async (config, enabled) => {
|
|
32572
32778
|
const activityPath = await androidActivity(config);
|
|
32573
|
-
const activity = await
|
|
32779
|
+
const activity = await readFile21(activityPath, "utf8");
|
|
32574
32780
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
32575
32781
|
if (!packageName)
|
|
32576
32782
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
32577
32783
|
const packagePath = packageName.replaceAll(".", "/");
|
|
32578
|
-
const pluginPath =
|
|
32784
|
+
const pluginPath = join24(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
|
|
32579
32785
|
const changed = await Promise.all([
|
|
32580
32786
|
writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
|
|
32581
32787
|
enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
|
|
@@ -32596,13 +32802,13 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
|
|
|
32596
32802
|
// src/mobile/nativeObservability.ts
|
|
32597
32803
|
import {
|
|
32598
32804
|
mkdir as mkdir16,
|
|
32599
|
-
readFile as
|
|
32600
|
-
readdir as
|
|
32805
|
+
readFile as readFile22,
|
|
32806
|
+
readdir as readdir7,
|
|
32601
32807
|
rename as rename15,
|
|
32602
32808
|
rm as rm12,
|
|
32603
32809
|
writeFile as writeFile19
|
|
32604
32810
|
} from "fs/promises";
|
|
32605
|
-
import { dirname as dirname16, join as
|
|
32811
|
+
import { dirname as dirname16, join as join25 } from "path";
|
|
32606
32812
|
var START2 = "// absolutejs:native-observability:start";
|
|
32607
32813
|
var END2 = "// absolutejs:native-observability:end";
|
|
32608
32814
|
var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
|
|
@@ -32610,7 +32816,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
|
|
|
32610
32816
|
var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
|
|
32611
32817
|
var optionalSource3 = async (path) => {
|
|
32612
32818
|
try {
|
|
32613
|
-
return await
|
|
32819
|
+
return await readFile22(path, "utf8");
|
|
32614
32820
|
} catch (error) {
|
|
32615
32821
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32616
32822
|
return null;
|
|
@@ -32770,9 +32976,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
|
|
|
32770
32976
|
${PLUGIN_END2}
|
|
32771
32977
|
`;
|
|
32772
32978
|
var configureIos4 = async (config, enabled) => {
|
|
32773
|
-
const path =
|
|
32774
|
-
const capacitorConfigPath =
|
|
32775
|
-
let source = await
|
|
32979
|
+
const path = join25(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
32980
|
+
const capacitorConfigPath = join25(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
32981
|
+
let source = await readFile22(path, "utf8");
|
|
32776
32982
|
if (enabled && !source.includes("import MetricKit")) {
|
|
32777
32983
|
const capacitorImport = source.lastIndexOf("import Capacitor");
|
|
32778
32984
|
if (capacitorImport < 0)
|
|
@@ -32786,7 +32992,7 @@ ${source.slice(newline + 1)}`;
|
|
|
32786
32992
|
source = source.replace(`import MetricKit
|
|
32787
32993
|
`, "");
|
|
32788
32994
|
source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
|
|
32789
|
-
const capacitorConfigSource2 = await
|
|
32995
|
+
const capacitorConfigSource2 = await readFile22(capacitorConfigPath, "utf8");
|
|
32790
32996
|
let capacitorConfig;
|
|
32791
32997
|
try {
|
|
32792
32998
|
const value = JSON.parse(capacitorConfigSource2);
|
|
@@ -33024,19 +33230,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
|
|
|
33024
33230
|
var androidActivityInRoot2 = async (root) => {
|
|
33025
33231
|
let entries;
|
|
33026
33232
|
try {
|
|
33027
|
-
entries = await
|
|
33233
|
+
entries = await readdir7(root, { recursive: true });
|
|
33028
33234
|
} catch (error) {
|
|
33029
33235
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
33030
33236
|
return;
|
|
33031
33237
|
throw error;
|
|
33032
33238
|
}
|
|
33033
33239
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
33034
|
-
return candidate ?
|
|
33240
|
+
return candidate ? join25(root, candidate) : undefined;
|
|
33035
33241
|
};
|
|
33036
33242
|
var androidActivity2 = async (config) => {
|
|
33037
33243
|
const roots = [
|
|
33038
|
-
|
|
33039
|
-
|
|
33244
|
+
join25(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
33245
|
+
join25(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
33040
33246
|
];
|
|
33041
33247
|
const candidates = await Promise.all(roots.map(androidActivityInRoot2));
|
|
33042
33248
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -33104,11 +33310,11 @@ var injectAndroidActivity2 = (source, enabled) => {
|
|
|
33104
33310
|
};
|
|
33105
33311
|
var configureAndroid4 = async (config, enabled) => {
|
|
33106
33312
|
const activityPath = await androidActivity2(config);
|
|
33107
|
-
const activity = await
|
|
33313
|
+
const activity = await readFile22(activityPath, "utf8");
|
|
33108
33314
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
33109
33315
|
if (!packageName)
|
|
33110
33316
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
33111
|
-
const pluginPath =
|
|
33317
|
+
const pluginPath = join25(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
|
|
33112
33318
|
const changed = await Promise.all([
|
|
33113
33319
|
writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
|
|
33114
33320
|
enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
|
|
@@ -33133,8 +33339,8 @@ init_producerContext();
|
|
|
33133
33339
|
init_releaseArtifact();
|
|
33134
33340
|
|
|
33135
33341
|
// src/mobile/releasePublisher.ts
|
|
33136
|
-
import { access as
|
|
33137
|
-
import { isAbsolute as isAbsolute7, relative as
|
|
33342
|
+
import { access as access15 } from "fs/promises";
|
|
33343
|
+
import { isAbsolute as isAbsolute7, relative as relative14, resolve as resolve16, sep as sep9 } from "path";
|
|
33138
33344
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
33139
33345
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
33140
33346
|
if (typeof publisher.prepareIosRelease !== "function") {
|
|
@@ -33162,7 +33368,7 @@ var isPublisher = (value) => isRecord13(value) && typeof value.publish === "func
|
|
|
33162
33368
|
var publisherModulePath = (projectRoot, requested) => {
|
|
33163
33369
|
const root = resolve16(projectRoot);
|
|
33164
33370
|
const path = resolve16(root, requested);
|
|
33165
|
-
const projectRelative =
|
|
33371
|
+
const projectRelative = relative14(root, path);
|
|
33166
33372
|
if (projectRelative === ".." || projectRelative.startsWith(`..${sep9}`) || isAbsolute7(projectRelative)) {
|
|
33167
33373
|
throw new TypeError("mobile publish --registry must remain inside the project.");
|
|
33168
33374
|
}
|
|
@@ -33170,7 +33376,7 @@ var publisherModulePath = (projectRoot, requested) => {
|
|
|
33170
33376
|
};
|
|
33171
33377
|
var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
|
|
33172
33378
|
const modulePath = publisherModulePath(projectRoot, requestedModulePath);
|
|
33173
|
-
await
|
|
33379
|
+
await access15(modulePath).catch(() => {
|
|
33174
33380
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
33175
33381
|
});
|
|
33176
33382
|
const loaded = await import(pathToFileURL3(modulePath).href);
|
|
@@ -33234,7 +33440,7 @@ var publishAbsoluteIosRelease = async (options) => {
|
|
|
33234
33440
|
init_pageProtocol();
|
|
33235
33441
|
init_releaseArtifact();
|
|
33236
33442
|
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
33237
|
-
import { dirname as dirname17, extname as extname6, relative as
|
|
33443
|
+
import { dirname as dirname17, extname as extname6, relative as relative15, resolve as resolve17 } from "path";
|
|
33238
33444
|
import ts2 from "typescript";
|
|
33239
33445
|
var ROUTE_METHODS = new Set(["get", "head"]);
|
|
33240
33446
|
var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
|
|
@@ -33403,7 +33609,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
|
|
|
33403
33609
|
const declaration = symbol?.declarations?.[0];
|
|
33404
33610
|
const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
|
|
33405
33611
|
const exportedName = symbol?.name ?? expression.getText(sourceFile);
|
|
33406
|
-
const source = posixPath(
|
|
33612
|
+
const source = posixPath(relative15(projectRoot, file));
|
|
33407
33613
|
return `${source}#${exportedName}`;
|
|
33408
33614
|
};
|
|
33409
33615
|
var resolveAlias = (symbol, checker) => {
|
|
@@ -33759,7 +33965,7 @@ var inspectAbsoluteMobileRouteMetadata = (options) => {
|
|
|
33759
33965
|
const entry = resolve17(options.entry);
|
|
33760
33966
|
const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
|
|
33761
33967
|
return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
|
|
33762
|
-
file: posixPath(
|
|
33968
|
+
file: posixPath(relative15(projectRoot, file)),
|
|
33763
33969
|
metadata
|
|
33764
33970
|
})));
|
|
33765
33971
|
};
|
|
@@ -37756,7 +37962,7 @@ var createBeacon = (options) => {
|
|
|
37756
37962
|
if (signals !== null && signals.mediaFailures !== false && typeof document !== "undefined") {
|
|
37757
37963
|
const stallMs = signals.mediaStallMs ?? MEDIA_STALL_DEFAULT_MS;
|
|
37758
37964
|
const watched = new Map;
|
|
37759
|
-
const
|
|
37965
|
+
const watch3 = (media) => {
|
|
37760
37966
|
if (watched.has(media) || !media.hasAttribute(BEACON_ATTRIBUTE.MEDIA))
|
|
37761
37967
|
return;
|
|
37762
37968
|
const name = media.getAttribute(BEACON_ATTRIBUTE.MEDIA)?.trim() || describeElement(media);
|
|
@@ -37817,10 +38023,10 @@ var createBeacon = (options) => {
|
|
|
37817
38023
|
};
|
|
37818
38024
|
const scan = (root) => {
|
|
37819
38025
|
if (root instanceof HTMLMediaElement)
|
|
37820
|
-
|
|
38026
|
+
watch3(root);
|
|
37821
38027
|
for (const media of Array.from(root.querySelectorAll?.(`audio[${BEACON_ATTRIBUTE.MEDIA}], video[${BEACON_ATTRIBUTE.MEDIA}]`) ?? [])) {
|
|
37822
38028
|
if (media instanceof HTMLMediaElement)
|
|
37823
|
-
|
|
38029
|
+
watch3(media);
|
|
37824
38030
|
}
|
|
37825
38031
|
};
|
|
37826
38032
|
scan(document);
|
|
@@ -37870,7 +38076,7 @@ var createBeacon = (options) => {
|
|
|
37870
38076
|
const originalOpen = factory.open.bind(factory);
|
|
37871
38077
|
const originalDeleteDatabase = factory.deleteDatabase.bind(factory);
|
|
37872
38078
|
const reported = new WeakSet;
|
|
37873
|
-
const
|
|
38079
|
+
const watch3 = (request, operation2, database) => {
|
|
37874
38080
|
request.addEventListener("error", () => {
|
|
37875
38081
|
if (reported.has(request))
|
|
37876
38082
|
return;
|
|
@@ -37886,8 +38092,8 @@ var createBeacon = (options) => {
|
|
|
37886
38092
|
}, { once: true });
|
|
37887
38093
|
return request;
|
|
37888
38094
|
};
|
|
37889
|
-
const wrappedOpen = (name, version) =>
|
|
37890
|
-
const wrappedDeleteDatabase = (name) =>
|
|
38095
|
+
const wrappedOpen = (name, version) => watch3(version === undefined ? originalOpen(name) : originalOpen(name, version), "open", name);
|
|
38096
|
+
const wrappedDeleteDatabase = (name) => watch3(originalDeleteDatabase(name), "delete", name);
|
|
37891
38097
|
try {
|
|
37892
38098
|
factory.open = wrappedOpen;
|
|
37893
38099
|
factory.deleteDatabase = wrappedDeleteDatabase;
|
|
@@ -39951,44 +40157,44 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
39951
40157
|
};
|
|
39952
40158
|
};
|
|
39953
40159
|
// src/mobile/updatePublisher.ts
|
|
39954
|
-
import { access as
|
|
39955
|
-
import { isAbsolute as isAbsolute8, relative as
|
|
40160
|
+
import { access as access16 } from "fs/promises";
|
|
40161
|
+
import { isAbsolute as isAbsolute8, relative as relative17, resolve as resolve19, sep as sep10 } from "path";
|
|
39956
40162
|
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
39957
40163
|
|
|
39958
40164
|
// src/mobile/updateSigning.ts
|
|
39959
|
-
import { createHash as
|
|
40165
|
+
import { createHash as createHash14, sign, verify } from "crypto";
|
|
39960
40166
|
import {
|
|
39961
40167
|
cp as cp3,
|
|
39962
40168
|
mkdir as mkdir17,
|
|
39963
40169
|
mkdtemp as mkdtemp8,
|
|
39964
|
-
readdir as
|
|
39965
|
-
readFile as
|
|
40170
|
+
readdir as readdir8,
|
|
40171
|
+
readFile as readFile23,
|
|
39966
40172
|
rename as rename16,
|
|
39967
40173
|
rm as rm13,
|
|
39968
40174
|
stat as stat4,
|
|
39969
40175
|
writeFile as writeFile20
|
|
39970
40176
|
} from "fs/promises";
|
|
39971
|
-
import { dirname as dirname18, join as
|
|
40177
|
+
import { dirname as dirname18, join as join26, relative as relative16, resolve as resolve18 } from "path";
|
|
39972
40178
|
var UPDATE_MANIFEST_FILE = "update.json";
|
|
39973
40179
|
var UPDATE_FILES_DIRECTORY = "files";
|
|
39974
|
-
var sha2562 = (value) =>
|
|
40180
|
+
var sha2562 = (value) => createHash14("sha256").update(value).digest("hex");
|
|
39975
40181
|
var listFiles = async (root, directory = root) => {
|
|
39976
|
-
const entries = await
|
|
40182
|
+
const entries = await readdir8(directory, { withFileTypes: true });
|
|
39977
40183
|
const paths = await Promise.all(entries.map(async (entry) => {
|
|
39978
|
-
const path =
|
|
40184
|
+
const path = join26(directory, entry.name);
|
|
39979
40185
|
if (entry.isDirectory())
|
|
39980
40186
|
return listFiles(root, path);
|
|
39981
40187
|
if (!entry.isFile())
|
|
39982
40188
|
throw new TypeError("Mobile updates cannot contain links or special files.");
|
|
39983
|
-
return [
|
|
40189
|
+
return [relative16(root, path).replaceAll("\\", "/")];
|
|
39984
40190
|
}));
|
|
39985
40191
|
return paths.flat().sort((left, right) => left.localeCompare(right));
|
|
39986
40192
|
};
|
|
39987
40193
|
var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
|
|
39988
|
-
const source =
|
|
40194
|
+
const source = join26(root, path);
|
|
39989
40195
|
const [metadata, contents] = await Promise.all([
|
|
39990
40196
|
stat4(source),
|
|
39991
|
-
|
|
40197
|
+
readFile23(source)
|
|
39992
40198
|
]);
|
|
39993
40199
|
return { bytes: metadata.size, path, sha256: sha2562(contents) };
|
|
39994
40200
|
}));
|
|
@@ -40024,14 +40230,14 @@ var buildAbsoluteMobileUpdate = async (options) => {
|
|
|
40024
40230
|
}
|
|
40025
40231
|
});
|
|
40026
40232
|
await mkdir17(outputRoot, { recursive: true });
|
|
40027
|
-
const outputDirectory =
|
|
40028
|
-
const staging = await mkdtemp8(
|
|
40233
|
+
const outputDirectory = join26(outputRoot, manifest.releaseId);
|
|
40234
|
+
const staging = await mkdtemp8(join26(outputRoot, ".stage-"));
|
|
40029
40235
|
try {
|
|
40030
|
-
await cp3(bundleDirectory,
|
|
40236
|
+
await cp3(bundleDirectory, join26(staging, UPDATE_FILES_DIRECTORY), {
|
|
40031
40237
|
force: true,
|
|
40032
40238
|
recursive: true
|
|
40033
40239
|
});
|
|
40034
|
-
await writeFile20(
|
|
40240
|
+
await writeFile20(join26(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
40035
40241
|
`);
|
|
40036
40242
|
await rename16(staging, outputDirectory);
|
|
40037
40243
|
} catch (error) {
|
|
@@ -40042,7 +40248,7 @@ var buildAbsoluteMobileUpdate = async (options) => {
|
|
|
40042
40248
|
}
|
|
40043
40249
|
return {
|
|
40044
40250
|
manifest,
|
|
40045
|
-
manifestPath:
|
|
40251
|
+
manifestPath: join26(outputDirectory, UPDATE_MANIFEST_FILE),
|
|
40046
40252
|
outputDirectory
|
|
40047
40253
|
};
|
|
40048
40254
|
};
|
|
@@ -40054,7 +40260,7 @@ var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) =>
|
|
|
40054
40260
|
await mkdir17(dirname18(destination), { recursive: true });
|
|
40055
40261
|
await cp3(source, destination, { force: true });
|
|
40056
40262
|
};
|
|
40057
|
-
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await
|
|
40263
|
+
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile23(join26(resolve18(directory), UPDATE_MANIFEST_FILE), "utf8")));
|
|
40058
40264
|
var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
|
|
40059
40265
|
const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
|
|
40060
40266
|
const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
|
|
@@ -40173,14 +40379,14 @@ var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "
|
|
|
40173
40379
|
var projectPath2 = (projectRoot, requested, label) => {
|
|
40174
40380
|
const root = resolve19(projectRoot);
|
|
40175
40381
|
const path = resolve19(root, requested);
|
|
40176
|
-
const projectRelative =
|
|
40382
|
+
const projectRelative = relative17(root, path);
|
|
40177
40383
|
if (projectRelative === ".." || projectRelative.startsWith(`..${sep10}`) || isAbsolute8(projectRelative))
|
|
40178
40384
|
throw new TypeError(`${label} must remain inside the project.`);
|
|
40179
40385
|
return path;
|
|
40180
40386
|
};
|
|
40181
40387
|
var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
|
|
40182
40388
|
const modulePath = projectPath2(projectRoot, requestedModulePath, "mobile update registry");
|
|
40183
|
-
await
|
|
40389
|
+
await access16(modulePath).catch(() => {
|
|
40184
40390
|
throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
|
|
40185
40391
|
});
|
|
40186
40392
|
const loaded = await import(pathToFileURL4(modulePath).href);
|
|
@@ -40231,7 +40437,7 @@ var rollbackAbsoluteMobileUpdate = async (options) => {
|
|
|
40231
40437
|
return result;
|
|
40232
40438
|
};
|
|
40233
40439
|
// src/mobile/updateRollout.ts
|
|
40234
|
-
import { createHash as
|
|
40440
|
+
import { createHash as createHash15 } from "crypto";
|
|
40235
40441
|
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;
|
|
40236
40442
|
var requireHeader = (headers, name) => {
|
|
40237
40443
|
const value = headers.get(name);
|
|
@@ -40246,7 +40452,7 @@ var isAbsoluteMobileUpdateRolloutMember = (options) => {
|
|
|
40246
40452
|
return false;
|
|
40247
40453
|
if (options.rollout === 1)
|
|
40248
40454
|
return true;
|
|
40249
|
-
const digest =
|
|
40455
|
+
const digest = createHash15("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
|
|
40250
40456
|
const bucket = digest.readUInt32BE(0) / 4294967296;
|
|
40251
40457
|
return bucket < options.rollout;
|
|
40252
40458
|
};
|
|
@@ -40353,6 +40559,7 @@ export {
|
|
|
40353
40559
|
copyAbsoluteMobileUpdateFile,
|
|
40354
40560
|
createAbsoluteExpoBridgeError,
|
|
40355
40561
|
createAbsoluteExpoBridgeResponse,
|
|
40562
|
+
createAbsoluteExpoNativeWatcher,
|
|
40356
40563
|
createAbsoluteIosNativeWatcher,
|
|
40357
40564
|
createAbsoluteMobileAssociationDocuments,
|
|
40358
40565
|
createAbsoluteMobileAssociationPlugin,
|
|
@@ -40384,6 +40591,7 @@ export {
|
|
|
40384
40591
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
40385
40592
|
finalizeAbsoluteMobilePage,
|
|
40386
40593
|
finalizeAbsoluteRouteData,
|
|
40594
|
+
fingerprintAbsoluteExpoNativeInputs,
|
|
40387
40595
|
fingerprintAbsoluteIosDevProject,
|
|
40388
40596
|
fingerprintAbsoluteIosNativeProject,
|
|
40389
40597
|
fingerprintAbsoluteMobileUpdateRuntime,
|
|
@@ -40412,6 +40620,7 @@ export {
|
|
|
40412
40620
|
installAbsoluteMobileSyncRemediation,
|
|
40413
40621
|
installAbsoluteMobileUiPrimitives,
|
|
40414
40622
|
installAbsoluteRemoteMacAgent,
|
|
40623
|
+
isAbsoluteExpoNativeRootInput,
|
|
40415
40624
|
isAbsoluteIosNativeRootInput,
|
|
40416
40625
|
isAbsoluteMobileUpdateRolloutMember,
|
|
40417
40626
|
listAbsoluteRemoteMacProfiles,
|
|
@@ -40512,5 +40721,5 @@ export {
|
|
|
40512
40721
|
writeAbsoluteMobileUpdateRegistry
|
|
40513
40722
|
};
|
|
40514
40723
|
|
|
40515
|
-
//# debugId=
|
|
40724
|
+
//# debugId=B619FED6B184271164756E2164756E21
|
|
40516
40725
|
//# sourceMappingURL=index.js.map
|