@absolutejs/absolute 0.20.0-beta.92 → 0.20.0-beta.94
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 +24 -0
- package/changelog.json +48 -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-vf61bv90.js → compile-qg75ewma.js} +5 -5
- package/dist/cli/{dev-perzmh2w.js → dev-sm9px53g.js} +83 -11
- package/dist/cli/{expoDevController-tr63cg78.js → expoDevController-a0jk8d43.js} +31 -2
- package/dist/cli/expoNativeWatcher-rmc95bak.js +138 -0
- package/dist/cli/{expoProject-djc0vk7g.js → expoProject-h38entbj.js} +1 -1
- package/dist/cli/{index-8zrnvazp.js → index-0t1cxstr.js} +261 -48
- package/dist/cli/{index-fn44wefq.js → index-3sdvzrv2.js} +37 -28
- package/dist/cli/{index-gxkmg2ss.js → index-51yyq29s.js} +1 -1
- package/dist/cli/index-bw4ktfnz.js +11 -0
- package/dist/cli/{index-751czk1b.js → index-d8va9b7v.js} +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-yk7qr9qg.js → mobile-dev4mjsa.js} +20 -12
- package/dist/cli/{remoteMacProtocol-vw931n0a.js → remoteMacProtocol-kqvkp0qd.js} +2 -1
- package/dist/cli/{start-ef7tgbmf.js → start-0ddnh0y4.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 +599 -208
- package/dist/mobile/index.js.map +11 -8
- package/dist/mobile/mobilePreviewClient.ts +1 -1
- package/dist/mobile/remoteMacAgentEntry.js +354 -188
- package/dist/src/dev/clientManager.d.ts +2 -2
- package/dist/src/mobile/androidConformance.d.ts +4 -1
- package/dist/src/mobile/expoActivityResultRecovery.d.ts +1 -0
- package/dist/src/mobile/expoBridge.d.ts +2 -2
- package/dist/src/mobile/expoDevController.d.ts +2 -6
- 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 join21 } 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 = join21(homedir3(), ".absolutejs");
|
|
19368
|
+
configPath = join21(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 join22, 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 = join22(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) => {
|
|
@@ -26836,7 +26851,7 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
|
|
|
26836
26851
|
};
|
|
26837
26852
|
// src/mobile/buildPipeline.ts
|
|
26838
26853
|
import { readFile as readFile15 } from "fs/promises";
|
|
26839
|
-
import { join as
|
|
26854
|
+
import { join as join17, resolve as resolve13 } from "path";
|
|
26840
26855
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
26841
26856
|
|
|
26842
26857
|
// src/mobile/buildRelease.ts
|
|
@@ -27607,7 +27622,7 @@ import {
|
|
|
27607
27622
|
writeFile as writeFile12
|
|
27608
27623
|
} from "fs/promises";
|
|
27609
27624
|
import { createHash as createHash12 } from "crypto";
|
|
27610
|
-
import { basename as basename4, dirname as dirname10, join as
|
|
27625
|
+
import { basename as basename4, dirname as dirname10, join as join16, relative as relative10, resolve as resolve12, sep as sep6 } from "path";
|
|
27611
27626
|
|
|
27612
27627
|
// src/mobile/updateRuntime.ts
|
|
27613
27628
|
init_deviceCapabilities();
|
|
@@ -28250,6 +28265,127 @@ var absoluteExpoNativeObservabilityPaths = (project) => [
|
|
|
28250
28265
|
...absoluteExpoNativeObservabilityFiles(project).keys()
|
|
28251
28266
|
];
|
|
28252
28267
|
|
|
28268
|
+
// src/mobile/expoActivityResultRecovery.ts
|
|
28269
|
+
import { join as join15 } from "path";
|
|
28270
|
+
var HEADER2 = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
28271
|
+
`;
|
|
28272
|
+
var XML_HEADER2 = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
|
|
28273
|
+
`;
|
|
28274
|
+
var moduleConfig2 = `${JSON.stringify({
|
|
28275
|
+
android: {
|
|
28276
|
+
modules: [
|
|
28277
|
+
"expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryModule"
|
|
28278
|
+
]
|
|
28279
|
+
},
|
|
28280
|
+
platforms: ["android"]
|
|
28281
|
+
}, null, 2)}
|
|
28282
|
+
`;
|
|
28283
|
+
var androidBuild2 = `${HEADER2}plugins {
|
|
28284
|
+
id 'com.android.library'
|
|
28285
|
+
id 'expo-module-gradle-plugin'
|
|
28286
|
+
}
|
|
28287
|
+
|
|
28288
|
+
group = 'expo.modules.absoluteactivityresultrecovery'
|
|
28289
|
+
version = '0.0.1'
|
|
28290
|
+
|
|
28291
|
+
android {
|
|
28292
|
+
namespace 'expo.modules.absoluteactivityresultrecovery'
|
|
28293
|
+
defaultConfig {
|
|
28294
|
+
versionCode 1
|
|
28295
|
+
versionName '0.0.1'
|
|
28296
|
+
}
|
|
28297
|
+
lintOptions { abortOnError false }
|
|
28298
|
+
}
|
|
28299
|
+
`;
|
|
28300
|
+
var androidManifest2 = `${XML_HEADER2}<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
|
|
28301
|
+
`;
|
|
28302
|
+
var androidModule2 = `${HEADER2}package expo.modules.absoluteactivityresultrecovery
|
|
28303
|
+
|
|
28304
|
+
import android.content.Intent
|
|
28305
|
+
import android.util.Log
|
|
28306
|
+
import expo.modules.kotlin.modules.Module
|
|
28307
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
28308
|
+
|
|
28309
|
+
data class AbsolutePendingActivityResult(
|
|
28310
|
+
val requestCode: Int,
|
|
28311
|
+
val resultCode: Int,
|
|
28312
|
+
val data: Intent?
|
|
28313
|
+
)
|
|
28314
|
+
|
|
28315
|
+
object AbsoluteActivityResultRecoveryState {
|
|
28316
|
+
@Volatile
|
|
28317
|
+
var applicationRuntimeReady = false
|
|
28318
|
+
|
|
28319
|
+
private val pendingActivityResults = ArrayDeque<AbsolutePendingActivityResult>()
|
|
28320
|
+
|
|
28321
|
+
@Synchronized
|
|
28322
|
+
fun enqueueActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
28323
|
+
if (pendingActivityResults.size == 8) pendingActivityResults.removeFirst()
|
|
28324
|
+
pendingActivityResults.addLast(
|
|
28325
|
+
AbsolutePendingActivityResult(requestCode, resultCode, data?.let(::Intent))
|
|
28326
|
+
)
|
|
28327
|
+
Log.d("AbsoluteJS", "Queued early Android activity result; pending=" + pendingActivityResults.size)
|
|
28328
|
+
}
|
|
28329
|
+
|
|
28330
|
+
@Synchronized
|
|
28331
|
+
fun hasPendingActivityResults() = pendingActivityResults.isNotEmpty()
|
|
28332
|
+
|
|
28333
|
+
@Synchronized
|
|
28334
|
+
fun drainActivityResults(): List<AbsolutePendingActivityResult> {
|
|
28335
|
+
val drained = pendingActivityResults.toList()
|
|
28336
|
+
pendingActivityResults.clear()
|
|
28337
|
+
Log.d("AbsoluteJS", "Replaying queued Android activity results; count=" + drained.size)
|
|
28338
|
+
return drained
|
|
28339
|
+
}
|
|
28340
|
+
}
|
|
28341
|
+
|
|
28342
|
+
class AbsoluteActivityResultRecoveryModule : Module() {
|
|
28343
|
+
override fun definition() = ModuleDefinition {
|
|
28344
|
+
Name("AbsoluteActivityResultRecovery")
|
|
28345
|
+
|
|
28346
|
+
Function("markApplicationRuntimeReady") {
|
|
28347
|
+
AbsoluteActivityResultRecoveryState.applicationRuntimeReady = true
|
|
28348
|
+
Log.d("AbsoluteJS", "Expo application runtime ready for Android activity results")
|
|
28349
|
+
}
|
|
28350
|
+
}
|
|
28351
|
+
}
|
|
28352
|
+
`;
|
|
28353
|
+
var runtime = `${HEADER2}import { requireNativeModule } from 'expo-modules-core';
|
|
28354
|
+
|
|
28355
|
+
type AbsoluteActivityResultRecoveryNative = {
|
|
28356
|
+
markApplicationRuntimeReady(): void;
|
|
28357
|
+
};
|
|
28358
|
+
|
|
28359
|
+
const native = requireNativeModule<AbsoluteActivityResultRecoveryNative>(
|
|
28360
|
+
'AbsoluteActivityResultRecovery'
|
|
28361
|
+
);
|
|
28362
|
+
|
|
28363
|
+
export const markAbsoluteApplicationRuntimeReady = () =>
|
|
28364
|
+
native.markApplicationRuntimeReady();
|
|
28365
|
+
`;
|
|
28366
|
+
var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
|
|
28367
|
+
[
|
|
28368
|
+
join15(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
|
|
28369
|
+
moduleConfig2
|
|
28370
|
+
],
|
|
28371
|
+
[
|
|
28372
|
+
join15(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
|
|
28373
|
+
androidBuild2
|
|
28374
|
+
],
|
|
28375
|
+
[
|
|
28376
|
+
join15(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
|
|
28377
|
+
androidManifest2
|
|
28378
|
+
],
|
|
28379
|
+
[
|
|
28380
|
+
join15(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
|
|
28381
|
+
androidModule2
|
|
28382
|
+
],
|
|
28383
|
+
[
|
|
28384
|
+
join15(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
|
|
28385
|
+
runtime
|
|
28386
|
+
]
|
|
28387
|
+
]);
|
|
28388
|
+
|
|
28253
28389
|
// src/mobile/expoProject.ts
|
|
28254
28390
|
var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
28255
28391
|
`;
|
|
@@ -28330,7 +28466,7 @@ var routeSegments = (route) => {
|
|
|
28330
28466
|
return segment;
|
|
28331
28467
|
});
|
|
28332
28468
|
};
|
|
28333
|
-
var routeFile = (project, route) =>
|
|
28469
|
+
var routeFile = (project, route) => join16(project, "app", ...routeSegments(route), "index.tsx");
|
|
28334
28470
|
var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
|
|
28335
28471
|
const separator = spec.lastIndexOf("@");
|
|
28336
28472
|
return [spec.slice(0, separator), spec.slice(separator + 1)];
|
|
@@ -28338,7 +28474,7 @@ var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map
|
|
|
28338
28474
|
var expoPackage = (auth, sync, devices, updates) => ({
|
|
28339
28475
|
dependencies: {
|
|
28340
28476
|
"@absolutejs/devices": "0.7.0",
|
|
28341
|
-
"@absolutejs/devices-expo": "0.0.
|
|
28477
|
+
"@absolutejs/devices-expo": "0.0.9",
|
|
28342
28478
|
...auth ? {
|
|
28343
28479
|
"@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
|
|
28344
28480
|
[ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
|
|
@@ -28474,6 +28610,7 @@ var expoAppConfig = (config, auth, sync, devices, runtimeFingerprint) => {
|
|
|
28474
28610
|
plugins: [
|
|
28475
28611
|
"expo-router",
|
|
28476
28612
|
["expo-dev-client", { launchMode: "most-recent" }],
|
|
28613
|
+
"./plugins/withAbsoluteActivityResultRecovery",
|
|
28477
28614
|
...auth || config.updates ? ["expo-secure-store"] : [],
|
|
28478
28615
|
...sync ? [
|
|
28479
28616
|
"expo-sqlite",
|
|
@@ -28563,6 +28700,77 @@ const withAbsoluteDevelopmentCa = config => {
|
|
|
28563
28700
|
|
|
28564
28701
|
module.exports = withAbsoluteDevelopmentCa;
|
|
28565
28702
|
`;
|
|
28703
|
+
var expoActivityResultRecoveryPlugin = `${EXPO_GENERATED_HEADER}const { withMainActivity } = require('expo/config-plugins');
|
|
28704
|
+
|
|
28705
|
+
const IMPORT_ANCHOR = 'import android.os.Bundle';
|
|
28706
|
+
const CLASS_ANCHOR = 'class MainActivity : ReactActivity() {';
|
|
28707
|
+
const RECOVERY_MARKER = 'absolutePendingActivityResults';
|
|
28708
|
+
|
|
28709
|
+
const withAbsoluteActivityResultRecovery = config => withMainActivity(config, value => {
|
|
28710
|
+
if (value.modResults.language !== 'kt') {
|
|
28711
|
+
throw new Error('AbsoluteJS Expo activity-result recovery requires a Kotlin MainActivity.');
|
|
28712
|
+
}
|
|
28713
|
+
let source = value.modResults.contents;
|
|
28714
|
+
if (source.includes(RECOVERY_MARKER)) return value;
|
|
28715
|
+
if (!source.includes(IMPORT_ANCHOR) || !source.includes(CLASS_ANCHOR)) {
|
|
28716
|
+
throw new Error('AbsoluteJS could not locate the Expo MainActivity integration points.');
|
|
28717
|
+
}
|
|
28718
|
+
source = source.replace(IMPORT_ANCHOR, [
|
|
28719
|
+
'import android.content.Intent',
|
|
28720
|
+
'import android.os.Bundle',
|
|
28721
|
+
'import android.os.Handler',
|
|
28722
|
+
'import android.os.Looper',
|
|
28723
|
+
'import expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryState'
|
|
28724
|
+
].join('\\n'));
|
|
28725
|
+
source = source.replace(CLASS_ANCHOR, \`\${CLASS_ANCHOR}
|
|
28726
|
+
private val absoluteActivityResultHandler = Handler(Looper.getMainLooper())
|
|
28727
|
+
private var absoluteActivityResultAttempts = 0
|
|
28728
|
+
private val absoluteReplayActivityResults = object : Runnable {
|
|
28729
|
+
override fun run() {
|
|
28730
|
+
if (isFinishing || isDestroyed || !AbsoluteActivityResultRecoveryState.hasPendingActivityResults()) return
|
|
28731
|
+
if (!AbsoluteActivityResultRecoveryState.applicationRuntimeReady) {
|
|
28732
|
+
if (absoluteActivityResultAttempts++ < 240) {
|
|
28733
|
+
absoluteActivityResultHandler.postDelayed(this, 250)
|
|
28734
|
+
}
|
|
28735
|
+
return
|
|
28736
|
+
}
|
|
28737
|
+
absoluteActivityResultAttempts = 0
|
|
28738
|
+
AbsoluteActivityResultRecoveryState.drainActivityResults().forEach { result ->
|
|
28739
|
+
super@MainActivity.onActivityResult(result.requestCode, result.resultCode, result.data)
|
|
28740
|
+
}
|
|
28741
|
+
}
|
|
28742
|
+
}
|
|
28743
|
+
|
|
28744
|
+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
28745
|
+
if (AbsoluteActivityResultRecoveryState.applicationRuntimeReady) {
|
|
28746
|
+
super.onActivityResult(requestCode, resultCode, data)
|
|
28747
|
+
return
|
|
28748
|
+
}
|
|
28749
|
+
AbsoluteActivityResultRecoveryState.enqueueActivityResult(requestCode, resultCode, data)
|
|
28750
|
+
absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
|
|
28751
|
+
absoluteActivityResultHandler.postDelayed(absoluteReplayActivityResults, 250)
|
|
28752
|
+
}
|
|
28753
|
+
|
|
28754
|
+
override fun onResume() {
|
|
28755
|
+
super.onResume()
|
|
28756
|
+
if (AbsoluteActivityResultRecoveryState.hasPendingActivityResults()) {
|
|
28757
|
+
absoluteActivityResultAttempts = 0
|
|
28758
|
+
absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
|
|
28759
|
+
absoluteActivityResultHandler.post(absoluteReplayActivityResults)
|
|
28760
|
+
}
|
|
28761
|
+
}
|
|
28762
|
+
|
|
28763
|
+
override fun onDestroy() {
|
|
28764
|
+
absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
|
|
28765
|
+
super.onDestroy()
|
|
28766
|
+
}
|
|
28767
|
+
\`);
|
|
28768
|
+
value.modResults.contents = source;
|
|
28769
|
+
return value;
|
|
28770
|
+
});
|
|
28771
|
+
|
|
28772
|
+
module.exports = withAbsoluteActivityResultRecovery;
|
|
28773
|
+
`;
|
|
28566
28774
|
var metroConfig = (projectRoot) => `${EXPO_GENERATED_HEADER}const { getDefaultConfig } = require('expo/metro-config');
|
|
28567
28775
|
const path = require('node:path');
|
|
28568
28776
|
|
|
@@ -28580,6 +28788,8 @@ module.exports = config;
|
|
|
28580
28788
|
`;
|
|
28581
28789
|
var layoutSource = (auth, sync, updates, observability) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
|
|
28582
28790
|
import '../src/generated/AbsoluteDevices';
|
|
28791
|
+
import { useEffect as useActivityResultRecoveryEffect } from 'react';
|
|
28792
|
+
import { markAbsoluteApplicationRuntimeReady } from '../src/generated/AbsoluteActivityResultRecovery';
|
|
28583
28793
|
${auth ? `import { useEffect, useState } from 'react';
|
|
28584
28794
|
import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
|
|
28585
28795
|
${sync ? "import { startAbsoluteExpoSync } from '../src/generated/AbsoluteSync';" : ""}
|
|
@@ -28589,6 +28799,9 @@ ${observability ? `import { useEffect as useNativeObservabilityEffect } from 're
|
|
|
28589
28799
|
import { startAbsoluteExpoNativeObservability } from '../src/generated/AbsoluteNativeObservability';` : ""}
|
|
28590
28800
|
|
|
28591
28801
|
export default function AbsoluteLayout() {
|
|
28802
|
+
useActivityResultRecoveryEffect(() => {
|
|
28803
|
+
markAbsoluteApplicationRuntimeReady();
|
|
28804
|
+
}, []);
|
|
28592
28805
|
${updates ? "useUpdateEffect(() => { void startAbsoluteExpoUpdates(); }, []);" : ""}
|
|
28593
28806
|
${observability ? "useNativeObservabilityEffect(() => { void startAbsoluteExpoNativeObservability(); }, []);" : ""}
|
|
28594
28807
|
${auth ? `const [ready, setReady] = useState(false);
|
|
@@ -28945,7 +29158,7 @@ var webHostSource = (config, auth, sync) => {
|
|
|
28945
29158
|
const nativeRoutePatterns = nativeRoutes.map((route) => route.split("/").filter(Boolean));
|
|
28946
29159
|
return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
|
|
28947
29160
|
import { router, usePathname } from 'expo-router';
|
|
28948
|
-
import { useEffect, useRef, useState } from 'react';
|
|
29161
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
28949
29162
|
import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
|
|
28950
29163
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
28951
29164
|
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
|
|
@@ -29100,17 +29313,21 @@ const authStatus = async () => {
|
|
|
29100
29313
|
return { principal: principal ? { namespace: principal.namespace } : null, user };` : "throw new Error('Expo Auth is not configured.');"}
|
|
29101
29314
|
};
|
|
29102
29315
|
|
|
29103
|
-
export
|
|
29104
|
-
|
|
29316
|
+
export type AbsoluteWebHostProps = { path?: string };
|
|
29317
|
+
|
|
29318
|
+
export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
|
|
29319
|
+
const routerPathname = usePathname() || '/';
|
|
29320
|
+
const pathname = path?.startsWith('/') && !path.startsWith('//') ? path : routerPathname;
|
|
29105
29321
|
const safeAreaInsets = useSafeAreaInsets();
|
|
29106
29322
|
const webView = useRef<WebView>(null);
|
|
29107
29323
|
const devicesBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
29108
29324
|
const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
29109
29325
|
const [indexUri, setIndexUri] = useState<string>();
|
|
29110
|
-
const
|
|
29326
|
+
const canGoBack = useRef(false);
|
|
29111
29327
|
const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
|
|
29112
29328
|
const [devicesReady, setDevicesReady] = useState(false);
|
|
29113
29329
|
const activeWebPath = useRef(pathname);
|
|
29330
|
+
const webSource = useMemo(() => indexUri ? { uri: indexUri } : undefined, [indexUri]);
|
|
29114
29331
|
|
|
29115
29332
|
useEffect(() => {
|
|
29116
29333
|
if (!AUTH_ENABLED && !SYNC_ENABLED) return;
|
|
@@ -29168,7 +29385,7 @@ export function AbsoluteWebHost() {
|
|
|
29168
29385
|
if (!active) return;
|
|
29169
29386
|
respond({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
|
|
29170
29387
|
}).then(host => {
|
|
29171
|
-
if (!active) return void host.close();
|
|
29388
|
+
if (!active) return void Promise.resolve(host.close()).catch(() => undefined);
|
|
29172
29389
|
devicesBridge.current = host;
|
|
29173
29390
|
setDevicesReady(true);
|
|
29174
29391
|
});
|
|
@@ -29176,7 +29393,7 @@ export function AbsoluteWebHost() {
|
|
|
29176
29393
|
active = false;
|
|
29177
29394
|
const host = devicesBridge.current;
|
|
29178
29395
|
devicesBridge.current = undefined;
|
|
29179
|
-
void host
|
|
29396
|
+
if (host) void Promise.resolve(host.close()).catch(() => undefined);
|
|
29180
29397
|
};
|
|
29181
29398
|
}, []);
|
|
29182
29399
|
const hasOrigin = (source: string, origin: string) => {
|
|
@@ -29196,7 +29413,7 @@ export function AbsoluteWebHost() {
|
|
|
29196
29413
|
return;
|
|
29197
29414
|
}
|
|
29198
29415
|
if (message.kind === 'event' && message.event === 'back-unhandled') {
|
|
29199
|
-
if (canGoBack) webView.current?.goBack();
|
|
29416
|
+
if (canGoBack.current) webView.current?.goBack();
|
|
29200
29417
|
else BackHandler.exitApp();
|
|
29201
29418
|
return;
|
|
29202
29419
|
}
|
|
@@ -29230,22 +29447,27 @@ export function AbsoluteWebHost() {
|
|
|
29230
29447
|
}
|
|
29231
29448
|
};
|
|
29232
29449
|
|
|
29233
|
-
if (!
|
|
29450
|
+
if (!webSource || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
|
|
29234
29451
|
return <WebView
|
|
29235
29452
|
allowFileAccess
|
|
29236
29453
|
allowFileAccessFromFileURLs
|
|
29237
29454
|
allowUniversalAccessFromFileURLs={false}
|
|
29238
|
-
allowingReadAccessToURL={
|
|
29455
|
+
allowingReadAccessToURL={webSource.uri.slice(0, webSource.uri.lastIndexOf('/') + 1)}
|
|
29239
29456
|
injectedJavaScriptBeforeContentLoaded={bridgeBootstrap(pathname, safeAreaInsets)}
|
|
29240
29457
|
onMessage={onMessage}
|
|
29241
|
-
onNavigationStateChange={state =>
|
|
29458
|
+
onNavigationStateChange={state => {
|
|
29459
|
+
canGoBack.current = state.canGoBack;
|
|
29460
|
+
if (!DEV_ORIGIN || !hasOrigin(state.url, DEV_ORIGIN)) return;
|
|
29461
|
+
const route = new URL(state.url);
|
|
29462
|
+
activeWebPath.current = route.pathname + route.search + route.hash;
|
|
29463
|
+
}}
|
|
29242
29464
|
onShouldStartLoadWithRequest={request => {
|
|
29243
29465
|
if (request.url.startsWith('file:') || hasOrigin(request.url, PRODUCTION_ORIGIN) || DEV_ORIGIN && hasOrigin(request.url, DEV_ORIGIN)) return true;
|
|
29244
29466
|
void Linking.openURL(request.url);
|
|
29245
29467
|
return false;
|
|
29246
29468
|
}}
|
|
29247
29469
|
ref={webView}
|
|
29248
|
-
source={
|
|
29470
|
+
source={webSource}
|
|
29249
29471
|
style={styles.web}
|
|
29250
29472
|
/>;
|
|
29251
29473
|
}
|
|
@@ -29444,8 +29666,8 @@ const styles = StyleSheet.create({
|
|
|
29444
29666
|
error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
|
|
29445
29667
|
});
|
|
29446
29668
|
`;
|
|
29447
|
-
var nativeWrapperSource = (wrapper, module,
|
|
29448
|
-
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname10(wrapper),
|
|
29669
|
+
var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname10(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
29670
|
+
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname10(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
29449
29671
|
|
|
29450
29672
|
export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
|
|
29451
29673
|
export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
|
|
@@ -29514,7 +29736,7 @@ var pruneManagedFiles = async (paths) => {
|
|
|
29514
29736
|
return removed.filter(Boolean).length;
|
|
29515
29737
|
};
|
|
29516
29738
|
var pruneStaleManagedExpoRoutes = async (project, expected) => {
|
|
29517
|
-
const appDirectory =
|
|
29739
|
+
const appDirectory = join16(project, "app");
|
|
29518
29740
|
if (!await exists3(appDirectory))
|
|
29519
29741
|
return 0;
|
|
29520
29742
|
const files = await walkFiles(appDirectory);
|
|
@@ -29562,7 +29784,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
|
|
|
29562
29784
|
if (missing) {
|
|
29563
29785
|
throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
|
|
29564
29786
|
}
|
|
29565
|
-
const marker =
|
|
29787
|
+
const marker = join16(project, EXPO_PROJECT_MARKER);
|
|
29566
29788
|
if (await exists3(project) && !await exists3(marker)) {
|
|
29567
29789
|
const entries = await readdir4(project);
|
|
29568
29790
|
if (entries.length > 0 && !options.force) {
|
|
@@ -29575,7 +29797,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
|
|
|
29575
29797
|
const authEnabled = Boolean(auth);
|
|
29576
29798
|
const files = new Map([
|
|
29577
29799
|
[
|
|
29578
|
-
|
|
29800
|
+
join16(project, ".gitignore"),
|
|
29579
29801
|
`.expo/
|
|
29580
29802
|
android/
|
|
29581
29803
|
ios/
|
|
@@ -29583,74 +29805,80 @@ node_modules/
|
|
|
29583
29805
|
`
|
|
29584
29806
|
],
|
|
29585
29807
|
[
|
|
29586
|
-
|
|
29808
|
+
join16(project, "app.json"),
|
|
29587
29809
|
jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
|
|
29588
29810
|
],
|
|
29589
|
-
[
|
|
29811
|
+
[join16(project, "app.config.js"), expoDynamicAppConfig],
|
|
29590
29812
|
[
|
|
29591
|
-
|
|
29813
|
+
join16(project, "package.json"),
|
|
29592
29814
|
jsonSource(expoPackage(authEnabled, syncEnabled, devices, config.updates !== undefined))
|
|
29593
29815
|
],
|
|
29594
|
-
[
|
|
29816
|
+
[join16(project, "metro.config.js"), metroConfig(projectRoot)],
|
|
29595
29817
|
[
|
|
29596
|
-
|
|
29818
|
+
join16(project, "plugins", "withAbsoluteDevelopmentCa.js"),
|
|
29597
29819
|
expoDevelopmentCaPlugin
|
|
29598
29820
|
],
|
|
29599
29821
|
[
|
|
29600
|
-
|
|
29822
|
+
join16(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
|
|
29823
|
+
expoActivityResultRecoveryPlugin
|
|
29824
|
+
],
|
|
29825
|
+
[
|
|
29826
|
+
join16(project, "tsconfig.json"),
|
|
29601
29827
|
jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
|
|
29602
29828
|
],
|
|
29603
29829
|
[
|
|
29604
|
-
|
|
29830
|
+
join16(project, "app", "_layout.tsx"),
|
|
29605
29831
|
layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
|
|
29606
29832
|
],
|
|
29607
29833
|
[
|
|
29608
|
-
|
|
29834
|
+
join16(project, "app", "__absolute", "native", "index.tsx"),
|
|
29609
29835
|
nativeDiagnosticSource
|
|
29610
29836
|
],
|
|
29611
29837
|
[
|
|
29612
|
-
|
|
29838
|
+
join16(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
29613
29839
|
devicesRuntimeSource(config, devices, authEnabled)
|
|
29614
29840
|
],
|
|
29615
29841
|
[
|
|
29616
|
-
|
|
29842
|
+
join16(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
|
|
29617
29843
|
nativeRouteRuntimeSource(authEnabled)
|
|
29618
29844
|
],
|
|
29619
29845
|
[
|
|
29620
|
-
|
|
29846
|
+
join16(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
29621
29847
|
webHostSource(config, auth, syncEnabled)
|
|
29622
29848
|
]
|
|
29623
29849
|
]);
|
|
29850
|
+
for (const [path, source] of absoluteExpoActivityResultRecoveryFiles(project))
|
|
29851
|
+
files.set(path, source);
|
|
29624
29852
|
if (config.observability) {
|
|
29625
29853
|
for (const [path, source] of absoluteExpoNativeObservabilityFiles(project))
|
|
29626
29854
|
files.set(path, source);
|
|
29627
29855
|
}
|
|
29628
29856
|
if (config.updates) {
|
|
29629
|
-
files.set(
|
|
29857
|
+
files.set(join16(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
|
|
29630
29858
|
}
|
|
29631
29859
|
const expoCodeSigning = config.updates?.expoCodeSigning;
|
|
29632
29860
|
if (expoCodeSigning)
|
|
29633
|
-
files.set(
|
|
29861
|
+
files.set(join16(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
|
|
29634
29862
|
if (auth) {
|
|
29635
|
-
files.set(
|
|
29863
|
+
files.set(join16(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
|
|
29636
29864
|
}
|
|
29637
29865
|
if (syncSchema) {
|
|
29638
|
-
files.set(
|
|
29866
|
+
files.set(join16(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
|
|
29639
29867
|
}
|
|
29640
|
-
const webAssetsPath =
|
|
29868
|
+
const webAssetsPath = join16(project, "src", "generated", "webAssets.ts");
|
|
29641
29869
|
if (!await exists3(webAssetsPath)) {
|
|
29642
29870
|
files.set(webAssetsPath, emptyWebAssetsSource);
|
|
29643
29871
|
}
|
|
29644
29872
|
if (!config.expoNativeRoutes["/"]) {
|
|
29645
|
-
files.set(
|
|
29873
|
+
files.set(join16(project, "app", "index.tsx"), webRouteSource);
|
|
29646
29874
|
}
|
|
29647
|
-
files.set(
|
|
29648
|
-
const nativeRouteRuntime =
|
|
29875
|
+
files.set(join16(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
29876
|
+
const nativeRouteRuntime = join16(project, "src", "generated", "AbsoluteNativeRoute.tsx");
|
|
29649
29877
|
for (const [route, module] of routeModules) {
|
|
29650
|
-
const wrapper = route === "/" ?
|
|
29878
|
+
const wrapper = route === "/" ? join16(project, "app", "index.tsx") : routeFile(project, route);
|
|
29651
29879
|
files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
|
|
29652
29880
|
}
|
|
29653
|
-
const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${
|
|
29881
|
+
const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join16(project, "app")}${sep6}`))));
|
|
29654
29882
|
const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
|
|
29655
29883
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
29656
29884
|
const changed = removedRoutes + removedObservability + changes.filter(Boolean).length;
|
|
@@ -29659,7 +29887,7 @@ node_modules/
|
|
|
29659
29887
|
var walkFiles = async (root, directory = root) => {
|
|
29660
29888
|
const entries = await readdir4(directory, { withFileTypes: true });
|
|
29661
29889
|
const nested = await Promise.all(entries.map((entry) => {
|
|
29662
|
-
const path =
|
|
29890
|
+
const path = join16(directory, entry.name);
|
|
29663
29891
|
if (entry.isDirectory())
|
|
29664
29892
|
return walkFiles(root, path);
|
|
29665
29893
|
if (entry.isFile())
|
|
@@ -29726,11 +29954,11 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
29726
29954
|
var syncAbsoluteExpoWebAssets = async (config) => {
|
|
29727
29955
|
if (config.engine !== "expo")
|
|
29728
29956
|
throw new TypeError("Expo asset sync requires mobile.engine: expo.");
|
|
29729
|
-
const marker =
|
|
29957
|
+
const marker = join16(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
|
|
29730
29958
|
if (!await exists3(marker)) {
|
|
29731
29959
|
throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
|
|
29732
29960
|
}
|
|
29733
|
-
const manifestPath =
|
|
29961
|
+
const manifestPath = join16(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
29734
29962
|
const manifest = JSON.parse(await readFile14(manifestPath, "utf8"));
|
|
29735
29963
|
const nativeDataManifest = expoNativeDataManifest(manifest);
|
|
29736
29964
|
const { appBuild } = nativeDataManifest;
|
|
@@ -29744,16 +29972,16 @@ var syncAbsoluteExpoWebAssets = async (config) => {
|
|
|
29744
29972
|
bundleHash.update("\x00");
|
|
29745
29973
|
});
|
|
29746
29974
|
const bundleId = `amexpo_${bundleHash.digest("hex")}`;
|
|
29747
|
-
const destination =
|
|
29975
|
+
const destination = join16(config.nativeProjectDirectory, "assets", "absolute");
|
|
29748
29976
|
await mkdir11(dirname10(destination), { recursive: true });
|
|
29749
|
-
const staging = await mkdtemp7(
|
|
29977
|
+
const staging = await mkdtemp7(join16(dirname10(destination), `.${basename4(destination)}.stage-`));
|
|
29750
29978
|
let assets;
|
|
29751
29979
|
try {
|
|
29752
29980
|
assets = await Promise.all(files.map(async (source, index) => {
|
|
29753
29981
|
const name = `${String(index).padStart(6, "0")}${EXPO_ASSET_EXTENSION}`;
|
|
29754
|
-
await cp2(source,
|
|
29982
|
+
await cp2(source, join16(staging, name));
|
|
29755
29983
|
return {
|
|
29756
|
-
asset: portableRelative2(
|
|
29984
|
+
asset: portableRelative2(join16(config.nativeProjectDirectory, "src", "generated"), join16(destination, name)),
|
|
29757
29985
|
path: relative10(config.bundleDirectory, source).replaceAll("\\", "/")
|
|
29758
29986
|
};
|
|
29759
29987
|
}));
|
|
@@ -29762,7 +29990,7 @@ var syncAbsoluteExpoWebAssets = async (config) => {
|
|
|
29762
29990
|
await rm10(staging, { force: true, recursive: true });
|
|
29763
29991
|
throw error;
|
|
29764
29992
|
}
|
|
29765
|
-
const generated =
|
|
29993
|
+
const generated = join16(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
29766
29994
|
await writeManagedFile(generated, assetModuleSource(assets, bundleId, nativeDataManifest), true);
|
|
29767
29995
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
29768
29996
|
};
|
|
@@ -29803,9 +30031,9 @@ var loadServerApp = async (producerPath) => {
|
|
|
29803
30031
|
var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
29804
30032
|
const buildDirectory = resolve13(options.buildDirectory);
|
|
29805
30033
|
const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
|
|
29806
|
-
const root =
|
|
30034
|
+
const root = join17(buildDirectory, ".absolutejs", "mobile-compatibility");
|
|
29807
30035
|
const [manifestSource, previous] = await Promise.all([
|
|
29808
|
-
readFile15(
|
|
30036
|
+
readFile15(join17(buildDirectory, "manifest.json"), "utf8"),
|
|
29809
30037
|
readAbsoluteMobileMaterializedReleases(root)
|
|
29810
30038
|
]);
|
|
29811
30039
|
const manifest = JSON.parse(manifestSource);
|
|
@@ -30006,6 +30234,7 @@ var ABSOLUTE_EXPO_BRIDGE_MAX_BYTES = 64 * 1024;
|
|
|
30006
30234
|
var ABSOLUTE_EXPO_BRIDGE_METHODS = [
|
|
30007
30235
|
"devices.platform.getInfo",
|
|
30008
30236
|
"devices.lifecycle.getState",
|
|
30237
|
+
"devices.lifecycle.takeRestoredOperations",
|
|
30009
30238
|
"devices.links.getLaunchUrl",
|
|
30010
30239
|
"devices.links.openExternal",
|
|
30011
30240
|
"devices.network.getStatus",
|
|
@@ -30290,7 +30519,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
|
|
|
30290
30519
|
// src/mobile/expoDevController.ts
|
|
30291
30520
|
import { spawn } from "child_process";
|
|
30292
30521
|
import { access as access11 } from "fs/promises";
|
|
30293
|
-
import { join as
|
|
30522
|
+
import { join as join18, resolve as resolvePath4 } from "path";
|
|
30294
30523
|
var METRO_READY_TIMEOUT_MS = 120000;
|
|
30295
30524
|
var PROCESS_CLOSE_TIMEOUT_MS = 2000;
|
|
30296
30525
|
var preserveWindowsSubstRealpaths = `
|
|
@@ -30483,10 +30712,15 @@ var encodedWindowsExpoAndroidCommand = (project, androidRoot, appId, args, captu
|
|
|
30483
30712
|
`$env:NODE_ENV = '${mode === "development" ? "development" : "production"}'`,
|
|
30484
30713
|
...preferredDevice ? [] : ["$env:ORG_GRADLE_PROJECT_reactNativeArchitectures = 'x86_64'"],
|
|
30485
30714
|
"New-Item -ItemType Directory -Force -Path $directory | Out-Null",
|
|
30486
|
-
"& robocopy.exe $source $directory /MIR /XD node_modules .expo .git .gradle .cxx .kotlin build /XF bun.lock bun.lockb .absolutejs-preserve-subst.cjs /NFL /NDL /NJH /NJS /NP",
|
|
30715
|
+
"& robocopy.exe $source $directory /MIR /XD node_modules .expo .git .gradle .cxx .kotlin build /XF bun.lock bun.lockb .absolutejs-preserve-subst.cjs .absolutejs-source-lock.sha256 /NFL /NDL /NJH /NJS /NP",
|
|
30487
30716
|
"$copyExit = $LASTEXITCODE",
|
|
30488
30717
|
"if ($copyExit -ge 8) { exit $copyExit }",
|
|
30489
30718
|
"Set-Location $directory",
|
|
30719
|
+
"$sourceLock = @('bun.lock', 'bun.lockb') | ForEach-Object { Join-Path $source $_ } | Where-Object { Test-Path $_ } | Select-Object -First 1",
|
|
30720
|
+
"$sourceLockHash = if ($sourceLock) { (Get-FileHash $sourceLock -Algorithm SHA256).Hash } else { 'none' }",
|
|
30721
|
+
"$lockMarker = Join-Path $directory '.absolutejs-source-lock.sha256'",
|
|
30722
|
+
"$priorLockHash = if (Test-Path $lockMarker) { (Get-Content $lockMarker -Raw).Trim() } else { '' }",
|
|
30723
|
+
"if ($priorLockHash -ne $sourceLockHash) { Remove-Item (Join-Path $directory 'bun.lock'), (Join-Path $directory 'bun.lockb') -Force -ErrorAction SilentlyContinue; Set-Content $lockMarker $sourceLockHash -NoNewline }",
|
|
30490
30724
|
"$bun = (Get-Command bun.exe -ErrorAction Stop).Source",
|
|
30491
30725
|
"& $bun install",
|
|
30492
30726
|
"if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }",
|
|
@@ -30518,7 +30752,7 @@ var commandEnvironment = (options) => ({
|
|
|
30518
30752
|
...options.metroHost ? { REACT_NATIVE_PACKAGER_HOSTNAME: options.metroHost } : {}
|
|
30519
30753
|
});
|
|
30520
30754
|
var absoluteExpoExecutable = async (project) => {
|
|
30521
|
-
const executable =
|
|
30755
|
+
const executable = join18(project, "node_modules", ".bin", "expo");
|
|
30522
30756
|
try {
|
|
30523
30757
|
await access11(executable);
|
|
30524
30758
|
return executable;
|
|
@@ -30681,7 +30915,7 @@ var installAbsoluteExpoAndroidRelease = async (options) => {
|
|
|
30681
30915
|
const releaseExit = await runUtilityCommand(run, releaseExecutable, releaseArguments, utilityOptions);
|
|
30682
30916
|
if (releaseExit !== 0)
|
|
30683
30917
|
throw new Error(`Expo Android release build exited with status ${releaseExit}.`);
|
|
30684
|
-
const adb = options.androidAdb ??
|
|
30918
|
+
const adb = options.androidAdb ?? join18(androidRoot, "platform-tools", host3 === "windows" || host3 === "wsl" ? "adb.exe" : "adb");
|
|
30685
30919
|
const serial = host3 === "wsl" ? options.androidDevice ?? capture([adb, "devices"]).stdout.split(/\r?\n/u).flatMap((line) => {
|
|
30686
30920
|
const match = /^(\S+)\s+device$/u.exec(line.trim());
|
|
30687
30921
|
return match?.[1] ? [match[1]] : [];
|
|
@@ -30915,7 +31149,7 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
30915
31149
|
}
|
|
30916
31150
|
if (platform2 === "android" && host3 !== "wsl") {
|
|
30917
31151
|
const androidRoot = options.androidRoot ?? process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host3);
|
|
30918
|
-
const adb = options.androidAdb ??
|
|
31152
|
+
const adb = options.androidAdb ?? join18(androidRoot, "platform-tools", host3 === "windows" ? "adb.exe" : "adb");
|
|
30919
31153
|
connectLocalExpoAndroid(adb, options.config.appId, options.metroPort, capture, options.androidDevice);
|
|
30920
31154
|
log("Connected the Expo Android development client to Metro.");
|
|
30921
31155
|
}
|
|
@@ -30992,18 +31226,42 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
30992
31226
|
publishTiming("starting-metro", performance.now() - metroStarted);
|
|
30993
31227
|
await runNativeCommands(nativeCommands);
|
|
30994
31228
|
setState("ready");
|
|
30995
|
-
|
|
31229
|
+
let closed = false;
|
|
31230
|
+
let rebuildQueue = Promise.resolve();
|
|
31231
|
+
const session = {
|
|
30996
31232
|
metroPort: plan.metroPort,
|
|
30997
31233
|
platforms: options.platforms,
|
|
30998
31234
|
timings,
|
|
30999
31235
|
close: async () => {
|
|
31236
|
+
if (closed)
|
|
31237
|
+
return;
|
|
31238
|
+
closed = true;
|
|
31000
31239
|
options.signal?.removeEventListener("abort", abort);
|
|
31240
|
+
await rebuildQueue;
|
|
31001
31241
|
if (metro)
|
|
31002
31242
|
await stopProcess(metro);
|
|
31003
31243
|
await closeEnrollmentServer();
|
|
31004
31244
|
setState("closed");
|
|
31245
|
+
},
|
|
31246
|
+
rebuild: () => {
|
|
31247
|
+
const rebuild = rebuildQueue.then(async () => {
|
|
31248
|
+
if (closed)
|
|
31249
|
+
throw new Error("The Expo development session is closed.");
|
|
31250
|
+
if (prepareCommand)
|
|
31251
|
+
await runPrepareCommand(prepareCommand);
|
|
31252
|
+
await runNativeCommands(nativeCommands);
|
|
31253
|
+
setState("ready");
|
|
31254
|
+
return session;
|
|
31255
|
+
});
|
|
31256
|
+
rebuildQueue = rebuild.then(() => {
|
|
31257
|
+
return;
|
|
31258
|
+
}, () => {
|
|
31259
|
+
return;
|
|
31260
|
+
});
|
|
31261
|
+
return rebuild;
|
|
31005
31262
|
}
|
|
31006
31263
|
};
|
|
31264
|
+
return session;
|
|
31007
31265
|
} catch (error) {
|
|
31008
31266
|
options.signal?.removeEventListener("abort", abort);
|
|
31009
31267
|
if (metro)
|
|
@@ -31013,9 +31271,139 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
31013
31271
|
throw error;
|
|
31014
31272
|
}
|
|
31015
31273
|
};
|
|
31274
|
+
// src/mobile/expoNativeWatcher.ts
|
|
31275
|
+
import { watch as watch2 } from "fs";
|
|
31276
|
+
import { access as access12, readdir as readdir5, readFile as readFile16 } from "fs/promises";
|
|
31277
|
+
import { basename as basename5, join as join19, relative as relative12 } from "path";
|
|
31278
|
+
import { createHash as createHash13 } from "crypto";
|
|
31279
|
+
var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
|
|
31280
|
+
var ROOT_NATIVE_INPUTS2 = new Set([
|
|
31281
|
+
"absolute.config.js",
|
|
31282
|
+
"absolute.config.mjs",
|
|
31283
|
+
"absolute.config.ts",
|
|
31284
|
+
"absolutejs.config.js",
|
|
31285
|
+
"absolutejs.config.mjs",
|
|
31286
|
+
"absolutejs.config.ts",
|
|
31287
|
+
"bun.lock",
|
|
31288
|
+
"bun.lockb",
|
|
31289
|
+
"package.json"
|
|
31290
|
+
]);
|
|
31291
|
+
var EXPO_NATIVE_DIRECTORIES = ["modules", "plugins"];
|
|
31292
|
+
var exists5 = async (path) => access12(path).then(() => true, () => false);
|
|
31293
|
+
var filesIn = async (directory, prefix) => {
|
|
31294
|
+
if (!await exists5(directory))
|
|
31295
|
+
return [];
|
|
31296
|
+
const entries = await readdir5(directory, { withFileTypes: true });
|
|
31297
|
+
const nested = await Promise.all(entries.map((entry) => {
|
|
31298
|
+
const path = join19(directory, entry.name);
|
|
31299
|
+
const name = `${prefix}/${entry.name}`;
|
|
31300
|
+
if (entry.isDirectory())
|
|
31301
|
+
return filesIn(path, name);
|
|
31302
|
+
return Promise.resolve(entry.isFile() ? [{ name, path }] : []);
|
|
31303
|
+
}));
|
|
31304
|
+
return nested.flat().sort((left, right) => left.name.localeCompare(right.name));
|
|
31305
|
+
};
|
|
31306
|
+
var fingerprintAbsoluteExpoNativeInputs = async (options) => {
|
|
31307
|
+
const hash = createHash13("sha256");
|
|
31308
|
+
const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
|
|
31309
|
+
const path = join19(options.projectRoot, name);
|
|
31310
|
+
return await exists5(path) ? [{ name: `root/${name}`, path }] : [];
|
|
31311
|
+
}));
|
|
31312
|
+
const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join19(options.expoProjectDirectory, name), name)));
|
|
31313
|
+
const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
|
|
31314
|
+
const contents = await Promise.all(files.map(({ path }) => readFile16(path)));
|
|
31315
|
+
files.forEach(({ name }, index) => {
|
|
31316
|
+
hash.update(name);
|
|
31317
|
+
hash.update(contents[index] ?? Buffer.alloc(0));
|
|
31318
|
+
});
|
|
31319
|
+
return hash.digest("hex");
|
|
31320
|
+
};
|
|
31321
|
+
var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename5(path));
|
|
31322
|
+
var createAbsoluteExpoNativeWatcher = async (options) => {
|
|
31323
|
+
let fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
31324
|
+
let closed = false;
|
|
31325
|
+
let running = false;
|
|
31326
|
+
let timer;
|
|
31327
|
+
let rootInputChanged = false;
|
|
31328
|
+
const changedPaths = new Set;
|
|
31329
|
+
const watchers = [];
|
|
31330
|
+
const debounceMs = options.debounceMs ?? NATIVE_CHANGE_DEBOUNCE_MS2;
|
|
31331
|
+
const close = () => {
|
|
31332
|
+
if (closed)
|
|
31333
|
+
return;
|
|
31334
|
+
closed = true;
|
|
31335
|
+
if (timer)
|
|
31336
|
+
clearTimeout(timer);
|
|
31337
|
+
watchers.forEach((watcher) => watcher.close());
|
|
31338
|
+
options.signal?.removeEventListener("abort", close);
|
|
31339
|
+
};
|
|
31340
|
+
const schedule = () => {
|
|
31341
|
+
if (closed || running)
|
|
31342
|
+
return;
|
|
31343
|
+
if (timer)
|
|
31344
|
+
clearTimeout(timer);
|
|
31345
|
+
timer = setTimeout(() => void flush(), debounceMs);
|
|
31346
|
+
};
|
|
31347
|
+
const record = (path, root) => {
|
|
31348
|
+
if (closed)
|
|
31349
|
+
return;
|
|
31350
|
+
changedPaths.add(path);
|
|
31351
|
+
rootInputChanged ||= root;
|
|
31352
|
+
schedule();
|
|
31353
|
+
};
|
|
31354
|
+
const flush = async () => {
|
|
31355
|
+
timer = undefined;
|
|
31356
|
+
if (closed || running || changedPaths.size === 0)
|
|
31357
|
+
return;
|
|
31358
|
+
running = true;
|
|
31359
|
+
const paths = [...changedPaths].sort();
|
|
31360
|
+
const rootChanged = rootInputChanged;
|
|
31361
|
+
changedPaths.clear();
|
|
31362
|
+
rootInputChanged = false;
|
|
31363
|
+
try {
|
|
31364
|
+
const next = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
31365
|
+
if (next === fingerprint)
|
|
31366
|
+
return;
|
|
31367
|
+
await options.onChange({
|
|
31368
|
+
afterFingerprint: next,
|
|
31369
|
+
beforeFingerprint: fingerprint,
|
|
31370
|
+
paths,
|
|
31371
|
+
rootInputChanged: rootChanged
|
|
31372
|
+
});
|
|
31373
|
+
fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
|
|
31374
|
+
} catch (error) {
|
|
31375
|
+
options.onError?.(error);
|
|
31376
|
+
} finally {
|
|
31377
|
+
running = false;
|
|
31378
|
+
if (changedPaths.size > 0)
|
|
31379
|
+
schedule();
|
|
31380
|
+
}
|
|
31381
|
+
};
|
|
31382
|
+
const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
|
|
31383
|
+
const directory = join19(options.expoProjectDirectory, name);
|
|
31384
|
+
return await exists5(directory) ? [directory] : [];
|
|
31385
|
+
}))).flat();
|
|
31386
|
+
nativeDirectories.forEach((directory) => {
|
|
31387
|
+
watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
|
|
31388
|
+
if (!filename)
|
|
31389
|
+
return;
|
|
31390
|
+
record(relative12(options.expoProjectDirectory, join19(directory, String(filename))), false);
|
|
31391
|
+
}));
|
|
31392
|
+
});
|
|
31393
|
+
watchers.push(watch2(options.projectRoot, (_event, filename) => {
|
|
31394
|
+
if (!filename)
|
|
31395
|
+
return;
|
|
31396
|
+
const path = String(filename);
|
|
31397
|
+
if (isAbsoluteExpoNativeRootInput(path))
|
|
31398
|
+
record(path, true);
|
|
31399
|
+
}));
|
|
31400
|
+
watchers.forEach((watcher) => watcher.on("error", (error) => options.onError?.(error)));
|
|
31401
|
+
options.signal?.addEventListener("abort", close, { once: true });
|
|
31402
|
+
return { close };
|
|
31403
|
+
};
|
|
31016
31404
|
// src/mobile/expoUpdate.ts
|
|
31017
|
-
import { access as
|
|
31018
|
-
import { dirname as dirname12, extname as extname4, join as
|
|
31405
|
+
import { access as access13, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile14 } from "fs/promises";
|
|
31406
|
+
import { dirname as dirname12, extname as extname4, join as join20 } from "path";
|
|
31019
31407
|
var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
|
|
31020
31408
|
var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
|
|
31021
31409
|
var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -31081,7 +31469,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
|
|
|
31081
31469
|
};
|
|
31082
31470
|
};
|
|
31083
31471
|
var finalizeAbsoluteExpoUpdateExport = async (options) => {
|
|
31084
|
-
const metadata = JSON.parse(await
|
|
31472
|
+
const metadata = JSON.parse(await readFile17(join20(options.exportDirectory, "metadata.json"), "utf8"));
|
|
31085
31473
|
if (!object4(metadata) || !object4(metadata.fileMetadata))
|
|
31086
31474
|
throw new TypeError("Expo export metadata.json is invalid.");
|
|
31087
31475
|
const descriptor = parseAbsoluteExpoUpdateDescriptor({
|
|
@@ -31092,10 +31480,10 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
|
|
|
31092
31480
|
runtimeVersion: options.runtimeVersion
|
|
31093
31481
|
});
|
|
31094
31482
|
const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
|
|
31095
|
-
await Promise.all(referenced.map(({ path }) =>
|
|
31483
|
+
await Promise.all(referenced.map(({ path }) => access13(join20(options.exportDirectory, path)).catch(() => {
|
|
31096
31484
|
throw new TypeError(`Expo export metadata references missing asset ${path}.`);
|
|
31097
31485
|
})));
|
|
31098
|
-
const destination =
|
|
31486
|
+
const destination = join20(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
|
|
31099
31487
|
await mkdir13(dirname12(destination), { recursive: true });
|
|
31100
31488
|
await writeFile14(destination, `${JSON.stringify(descriptor, null, "\t")}
|
|
31101
31489
|
`);
|
|
@@ -31107,8 +31495,8 @@ init_config();
|
|
|
31107
31495
|
|
|
31108
31496
|
// src/mobile/ciWorkflow.ts
|
|
31109
31497
|
import { existsSync as existsSync4 } from "fs";
|
|
31110
|
-
import { access as
|
|
31111
|
-
import { dirname as dirname13, extname as extname5, relative as
|
|
31498
|
+
import { access as access14, mkdir as mkdir14, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
|
|
31499
|
+
import { dirname as dirname13, extname as extname5, relative as relative13, resolve as resolve15, sep as sep8 } from "path";
|
|
31112
31500
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
|
|
31113
31501
|
var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
|
|
31114
31502
|
var CI_ENV_INDENTATION = 6;
|
|
@@ -31127,9 +31515,9 @@ var RESERVED_SECRET_NAMES = new Set([
|
|
|
31127
31515
|
"APP_STORE_CONNECT_KEY_ID",
|
|
31128
31516
|
"APP_STORE_CONNECT_PRIVATE_KEY_BASE64"
|
|
31129
31517
|
]);
|
|
31130
|
-
var
|
|
31518
|
+
var exists6 = async (path) => {
|
|
31131
31519
|
try {
|
|
31132
|
-
await
|
|
31520
|
+
await access14(path);
|
|
31133
31521
|
return true;
|
|
31134
31522
|
} catch {
|
|
31135
31523
|
return false;
|
|
@@ -31139,7 +31527,7 @@ var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
|
|
|
31139
31527
|
var projectPath = (projectRoot, value, field2, options = {}) => {
|
|
31140
31528
|
const root = resolve15(projectRoot);
|
|
31141
31529
|
const path = resolve15(root, value);
|
|
31142
|
-
const portable =
|
|
31530
|
+
const portable = relative13(root, path).replaceAll("\\", "/");
|
|
31143
31531
|
if (portable === ".." || portable.startsWith(`..${sep8}`) || portable.startsWith("../") || portable === "") {
|
|
31144
31532
|
throw new TypeError(`${field2} must remain inside the project root.`);
|
|
31145
31533
|
}
|
|
@@ -31153,7 +31541,7 @@ var workflowOutputPath = (projectRoot, value) => {
|
|
|
31153
31541
|
const root = resolve15(projectRoot);
|
|
31154
31542
|
const workflows = resolve15(root, ".github/workflows");
|
|
31155
31543
|
const path = resolve15(root, value ?? ".github/workflows/absolute-mobile.yml");
|
|
31156
|
-
const portable =
|
|
31544
|
+
const portable = relative13(workflows, path);
|
|
31157
31545
|
if (portable === ".." || portable.startsWith(`..${sep8}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
|
|
31158
31546
|
throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
|
|
31159
31547
|
}
|
|
@@ -31583,9 +31971,9 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
|
|
|
31583
31971
|
var writeAbsoluteMobileGithubWorkflow = async (options) => {
|
|
31584
31972
|
const path = workflowOutputPath(options.projectRoot, options.outputPath);
|
|
31585
31973
|
const generated = createAbsoluteMobileGithubWorkflow(options);
|
|
31586
|
-
const previous = await
|
|
31974
|
+
const previous = await exists6(path) ? await readFile18(path, "utf8") : undefined;
|
|
31587
31975
|
if (previous !== undefined && previous !== generated.workflow && !options.force)
|
|
31588
|
-
throw new TypeError(`${
|
|
31976
|
+
throw new TypeError(`${relative13(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
|
|
31589
31977
|
if (previous !== generated.workflow) {
|
|
31590
31978
|
await mkdir14(dirname13(path), { recursive: true });
|
|
31591
31979
|
await writeFile15(path, generated.workflow);
|
|
@@ -31606,15 +31994,15 @@ init_materializedBundle();
|
|
|
31606
31994
|
init_mobilePreview();
|
|
31607
31995
|
|
|
31608
31996
|
// src/mobile/nativeDeepLinks.ts
|
|
31609
|
-
import { readFile as
|
|
31610
|
-
import { join as
|
|
31997
|
+
import { readFile as readFile19, rename as rename12, writeFile as writeFile16 } from "fs/promises";
|
|
31998
|
+
import { join as join23 } from "path";
|
|
31611
31999
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
31612
32000
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
31613
32001
|
var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
31614
32002
|
var NOT_FOUND = -1;
|
|
31615
32003
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
31616
32004
|
var writeChangedFile = async (path, source) => {
|
|
31617
|
-
const current = await
|
|
32005
|
+
const current = await readFile19(path, "utf8");
|
|
31618
32006
|
if (current === source)
|
|
31619
32007
|
return false;
|
|
31620
32008
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -31664,8 +32052,8 @@ ${hosts}
|
|
|
31664
32052
|
`;
|
|
31665
32053
|
};
|
|
31666
32054
|
var configureAndroid = async (config) => {
|
|
31667
|
-
const path =
|
|
31668
|
-
const source = await
|
|
32055
|
+
const path = join23(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
32056
|
+
const source = await readFile19(path, "utf8");
|
|
31669
32057
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
31670
32058
|
if (mainActivity === NOT_FOUND) {
|
|
31671
32059
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -31690,8 +32078,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
31690
32078
|
${END_MARKER}
|
|
31691
32079
|
`;
|
|
31692
32080
|
var configureIosInfo = async (config) => {
|
|
31693
|
-
const path =
|
|
31694
|
-
const source = await
|
|
32081
|
+
const path = join23(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
32082
|
+
const source = await readFile19(path, "utf8");
|
|
31695
32083
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
31696
32084
|
${END_MARKER}
|
|
31697
32085
|
`;
|
|
@@ -31714,10 +32102,10 @@ ${domains}
|
|
|
31714
32102
|
`;
|
|
31715
32103
|
};
|
|
31716
32104
|
var configureIosEntitlements = async (config) => {
|
|
31717
|
-
const path =
|
|
32105
|
+
const path = join23(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
31718
32106
|
let current = "";
|
|
31719
32107
|
try {
|
|
31720
|
-
current = await
|
|
32108
|
+
current = await readFile19(path, "utf8");
|
|
31721
32109
|
} catch (error) {
|
|
31722
32110
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
31723
32111
|
throw error;
|
|
@@ -31732,8 +32120,8 @@ var configureIosEntitlements = async (config) => {
|
|
|
31732
32120
|
return true;
|
|
31733
32121
|
};
|
|
31734
32122
|
var configureIosProject = async (config) => {
|
|
31735
|
-
const path =
|
|
31736
|
-
const source = await
|
|
32123
|
+
const path = join23(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
32124
|
+
const source = await readFile19(path, "utf8");
|
|
31737
32125
|
const declarations = [
|
|
31738
32126
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
31739
32127
|
].map((match) => match[1]);
|
|
@@ -31772,8 +32160,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
31772
32160
|
};
|
|
31773
32161
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
31774
32162
|
init_deviceCapabilities();
|
|
31775
|
-
import { readFile as
|
|
31776
|
-
import { join as
|
|
32163
|
+
import { readFile as readFile20, rename as rename13, writeFile as writeFile17 } from "fs/promises";
|
|
32164
|
+
import { join as join24 } from "path";
|
|
31777
32165
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
31778
32166
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
31779
32167
|
var NOT_FOUND2 = -1;
|
|
@@ -31783,7 +32171,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
31783
32171
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
31784
32172
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
31785
32173
|
var writeChangedFile2 = async (path, source) => {
|
|
31786
|
-
const current = await
|
|
32174
|
+
const current = await readFile20(path, "utf8");
|
|
31787
32175
|
if (current === source)
|
|
31788
32176
|
return false;
|
|
31789
32177
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -31803,7 +32191,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
31803
32191
|
};
|
|
31804
32192
|
var optionalSource = async (path) => {
|
|
31805
32193
|
try {
|
|
31806
|
-
return await
|
|
32194
|
+
return await readFile20(path, "utf8");
|
|
31807
32195
|
} catch (error) {
|
|
31808
32196
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
31809
32197
|
return null;
|
|
@@ -31923,8 +32311,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
|
|
|
31923
32311
|
var configureIosPrivacyProject = async (config, requirements) => {
|
|
31924
32312
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
31925
32313
|
return false;
|
|
31926
|
-
const projectPath2 =
|
|
31927
|
-
const project = await
|
|
32314
|
+
const projectPath2 = join24(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
32315
|
+
const project = await readFile20(projectPath2, "utf8");
|
|
31928
32316
|
return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
|
|
31929
32317
|
};
|
|
31930
32318
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -31976,8 +32364,8 @@ ${next.slice(index)}`;
|
|
|
31976
32364
|
return next;
|
|
31977
32365
|
};
|
|
31978
32366
|
var configureIos2 = async (config, plan) => {
|
|
31979
|
-
const path =
|
|
31980
|
-
const source = await
|
|
32367
|
+
const path = join24(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
32368
|
+
const source = await readFile20(path, "utf8");
|
|
31981
32369
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
31982
32370
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
31983
32371
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -31997,7 +32385,7 @@ ${content}
|
|
|
31997
32385
|
${END_MARKER2}
|
|
31998
32386
|
` : "";
|
|
31999
32387
|
const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
|
|
32000
|
-
const privacyPath =
|
|
32388
|
+
const privacyPath = join24(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
32001
32389
|
const privacyCurrent = await optionalSource(privacyPath);
|
|
32002
32390
|
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
32003
32391
|
const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
|
|
@@ -32008,7 +32396,7 @@ ${content}
|
|
|
32008
32396
|
return infoChanged || privacyChanged || projectChanged || pushChanged;
|
|
32009
32397
|
};
|
|
32010
32398
|
var configureIosPushNotifications = async (config, enabled) => {
|
|
32011
|
-
const entitlementsPath =
|
|
32399
|
+
const entitlementsPath = join24(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
32012
32400
|
const entitlements = await optionalSource(entitlementsPath);
|
|
32013
32401
|
if (entitlements === null && !enabled)
|
|
32014
32402
|
return false;
|
|
@@ -32020,7 +32408,7 @@ var configureIosPushNotifications = async (config, enabled) => {
|
|
|
32020
32408
|
<!-- ${PUSH_END_MARKER} -->
|
|
32021
32409
|
` : "";
|
|
32022
32410
|
const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
|
|
32023
|
-
const delegatePath =
|
|
32411
|
+
const delegatePath = join24(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
32024
32412
|
const delegate = await optionalSource(delegatePath);
|
|
32025
32413
|
if (delegate === null && !enabled)
|
|
32026
32414
|
return false;
|
|
@@ -32069,8 +32457,8 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
32069
32457
|
return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
|
|
32070
32458
|
};
|
|
32071
32459
|
var configureAndroid2 = async (config, plan) => {
|
|
32072
|
-
const path =
|
|
32073
|
-
const source = await
|
|
32460
|
+
const path = join24(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
32461
|
+
const source = await readFile20(path, "utf8");
|
|
32074
32462
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
32075
32463
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
32076
32464
|
`);
|
|
@@ -32105,7 +32493,7 @@ ${content}
|
|
|
32105
32493
|
throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
|
|
32106
32494
|
const [manifestChanged, firebaseChanged] = await Promise.all([
|
|
32107
32495
|
writeChangedFile2(path, nextManifest),
|
|
32108
|
-
writeOptionalChangedFile(
|
|
32496
|
+
writeOptionalChangedFile(join24(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
|
|
32109
32497
|
]);
|
|
32110
32498
|
return manifestChanged || firebaseChanged;
|
|
32111
32499
|
};
|
|
@@ -32125,13 +32513,13 @@ init_nativeAuth();
|
|
|
32125
32513
|
// src/mobile/nativeUpdates.ts
|
|
32126
32514
|
import {
|
|
32127
32515
|
mkdir as mkdir15,
|
|
32128
|
-
readFile as
|
|
32129
|
-
readdir as
|
|
32516
|
+
readFile as readFile21,
|
|
32517
|
+
readdir as readdir6,
|
|
32130
32518
|
rename as rename14,
|
|
32131
32519
|
rm as rm11,
|
|
32132
32520
|
writeFile as writeFile18
|
|
32133
32521
|
} from "fs/promises";
|
|
32134
|
-
import { dirname as dirname15, join as
|
|
32522
|
+
import { dirname as dirname15, join as join25 } from "path";
|
|
32135
32523
|
var START = "// absolutejs:mobile-updates:start";
|
|
32136
32524
|
var END = "// absolutejs:mobile-updates:end";
|
|
32137
32525
|
var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
|
|
@@ -32139,7 +32527,7 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
|
|
|
32139
32527
|
var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
|
|
32140
32528
|
var optionalSource2 = async (path) => {
|
|
32141
32529
|
try {
|
|
32142
|
-
return await
|
|
32530
|
+
return await readFile21(path, "utf8");
|
|
32143
32531
|
} catch (error) {
|
|
32144
32532
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32145
32533
|
return null;
|
|
@@ -32301,9 +32689,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
|
|
|
32301
32689
|
${PLUGIN_END}
|
|
32302
32690
|
`;
|
|
32303
32691
|
var configureIos3 = async (config, enabled) => {
|
|
32304
|
-
const path =
|
|
32305
|
-
const capacitorConfigPath =
|
|
32306
|
-
let source = await
|
|
32692
|
+
const path = join25(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
32693
|
+
const capacitorConfigPath = join25(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
32694
|
+
let source = await readFile21(path, "utf8");
|
|
32307
32695
|
const launch = source.indexOf("didFinishLaunchingWithOptions");
|
|
32308
32696
|
const brace = launch < 0 ? -1 : source.indexOf("{", launch);
|
|
32309
32697
|
const launchRegion = enabled ? ` ${START}
|
|
@@ -32314,7 +32702,7 @@ var configureIos3 = async (config, enabled) => {
|
|
|
32314
32702
|
`, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
|
|
32315
32703
|
const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
|
|
32316
32704
|
source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
|
|
32317
|
-
const capacitorConfigSource2 = await
|
|
32705
|
+
const capacitorConfigSource2 = await readFile21(capacitorConfigPath, "utf8");
|
|
32318
32706
|
let capacitorConfig;
|
|
32319
32707
|
try {
|
|
32320
32708
|
const value = JSON.parse(capacitorConfigSource2);
|
|
@@ -32487,19 +32875,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
|
|
|
32487
32875
|
var androidActivityInRoot = async (root) => {
|
|
32488
32876
|
let entries;
|
|
32489
32877
|
try {
|
|
32490
|
-
entries = await
|
|
32878
|
+
entries = await readdir6(root, { recursive: true });
|
|
32491
32879
|
} catch (error) {
|
|
32492
32880
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32493
32881
|
return;
|
|
32494
32882
|
throw error;
|
|
32495
32883
|
}
|
|
32496
32884
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
32497
|
-
return candidate ?
|
|
32885
|
+
return candidate ? join25(root, candidate) : undefined;
|
|
32498
32886
|
};
|
|
32499
32887
|
var androidActivity = async (config) => {
|
|
32500
32888
|
const roots = [
|
|
32501
|
-
|
|
32502
|
-
|
|
32889
|
+
join25(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
32890
|
+
join25(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
32503
32891
|
];
|
|
32504
32892
|
const candidates = await Promise.all(roots.map(androidActivityInRoot));
|
|
32505
32893
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -32598,12 +32986,12 @@ var injectAndroidActivity = (source, enabled) => {
|
|
|
32598
32986
|
};
|
|
32599
32987
|
var configureAndroid3 = async (config, enabled) => {
|
|
32600
32988
|
const activityPath = await androidActivity(config);
|
|
32601
|
-
const activity = await
|
|
32989
|
+
const activity = await readFile21(activityPath, "utf8");
|
|
32602
32990
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
32603
32991
|
if (!packageName)
|
|
32604
32992
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
32605
32993
|
const packagePath = packageName.replaceAll(".", "/");
|
|
32606
|
-
const pluginPath =
|
|
32994
|
+
const pluginPath = join25(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
|
|
32607
32995
|
const changed = await Promise.all([
|
|
32608
32996
|
writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
|
|
32609
32997
|
enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
|
|
@@ -32624,13 +33012,13 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
|
|
|
32624
33012
|
// src/mobile/nativeObservability.ts
|
|
32625
33013
|
import {
|
|
32626
33014
|
mkdir as mkdir16,
|
|
32627
|
-
readFile as
|
|
32628
|
-
readdir as
|
|
33015
|
+
readFile as readFile22,
|
|
33016
|
+
readdir as readdir7,
|
|
32629
33017
|
rename as rename15,
|
|
32630
33018
|
rm as rm12,
|
|
32631
33019
|
writeFile as writeFile19
|
|
32632
33020
|
} from "fs/promises";
|
|
32633
|
-
import { dirname as dirname16, join as
|
|
33021
|
+
import { dirname as dirname16, join as join26 } from "path";
|
|
32634
33022
|
var START2 = "// absolutejs:native-observability:start";
|
|
32635
33023
|
var END2 = "// absolutejs:native-observability:end";
|
|
32636
33024
|
var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
|
|
@@ -32638,7 +33026,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
|
|
|
32638
33026
|
var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
|
|
32639
33027
|
var optionalSource3 = async (path) => {
|
|
32640
33028
|
try {
|
|
32641
|
-
return await
|
|
33029
|
+
return await readFile22(path, "utf8");
|
|
32642
33030
|
} catch (error) {
|
|
32643
33031
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
32644
33032
|
return null;
|
|
@@ -32798,9 +33186,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
|
|
|
32798
33186
|
${PLUGIN_END2}
|
|
32799
33187
|
`;
|
|
32800
33188
|
var configureIos4 = async (config, enabled) => {
|
|
32801
|
-
const path =
|
|
32802
|
-
const capacitorConfigPath =
|
|
32803
|
-
let source = await
|
|
33189
|
+
const path = join26(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
33190
|
+
const capacitorConfigPath = join26(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
33191
|
+
let source = await readFile22(path, "utf8");
|
|
32804
33192
|
if (enabled && !source.includes("import MetricKit")) {
|
|
32805
33193
|
const capacitorImport = source.lastIndexOf("import Capacitor");
|
|
32806
33194
|
if (capacitorImport < 0)
|
|
@@ -32814,7 +33202,7 @@ ${source.slice(newline + 1)}`;
|
|
|
32814
33202
|
source = source.replace(`import MetricKit
|
|
32815
33203
|
`, "");
|
|
32816
33204
|
source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
|
|
32817
|
-
const capacitorConfigSource2 = await
|
|
33205
|
+
const capacitorConfigSource2 = await readFile22(capacitorConfigPath, "utf8");
|
|
32818
33206
|
let capacitorConfig;
|
|
32819
33207
|
try {
|
|
32820
33208
|
const value = JSON.parse(capacitorConfigSource2);
|
|
@@ -33052,19 +33440,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
|
|
|
33052
33440
|
var androidActivityInRoot2 = async (root) => {
|
|
33053
33441
|
let entries;
|
|
33054
33442
|
try {
|
|
33055
|
-
entries = await
|
|
33443
|
+
entries = await readdir7(root, { recursive: true });
|
|
33056
33444
|
} catch (error) {
|
|
33057
33445
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
33058
33446
|
return;
|
|
33059
33447
|
throw error;
|
|
33060
33448
|
}
|
|
33061
33449
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
33062
|
-
return candidate ?
|
|
33450
|
+
return candidate ? join26(root, candidate) : undefined;
|
|
33063
33451
|
};
|
|
33064
33452
|
var androidActivity2 = async (config) => {
|
|
33065
33453
|
const roots = [
|
|
33066
|
-
|
|
33067
|
-
|
|
33454
|
+
join26(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
33455
|
+
join26(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
33068
33456
|
];
|
|
33069
33457
|
const candidates = await Promise.all(roots.map(androidActivityInRoot2));
|
|
33070
33458
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -33132,11 +33520,11 @@ var injectAndroidActivity2 = (source, enabled) => {
|
|
|
33132
33520
|
};
|
|
33133
33521
|
var configureAndroid4 = async (config, enabled) => {
|
|
33134
33522
|
const activityPath = await androidActivity2(config);
|
|
33135
|
-
const activity = await
|
|
33523
|
+
const activity = await readFile22(activityPath, "utf8");
|
|
33136
33524
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
33137
33525
|
if (!packageName)
|
|
33138
33526
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
33139
|
-
const pluginPath =
|
|
33527
|
+
const pluginPath = join26(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
|
|
33140
33528
|
const changed = await Promise.all([
|
|
33141
33529
|
writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
|
|
33142
33530
|
enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
|
|
@@ -33161,8 +33549,8 @@ init_producerContext();
|
|
|
33161
33549
|
init_releaseArtifact();
|
|
33162
33550
|
|
|
33163
33551
|
// src/mobile/releasePublisher.ts
|
|
33164
|
-
import { access as
|
|
33165
|
-
import { isAbsolute as isAbsolute7, relative as
|
|
33552
|
+
import { access as access15 } from "fs/promises";
|
|
33553
|
+
import { isAbsolute as isAbsolute7, relative as relative14, resolve as resolve16, sep as sep9 } from "path";
|
|
33166
33554
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
33167
33555
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
33168
33556
|
if (typeof publisher.prepareIosRelease !== "function") {
|
|
@@ -33190,7 +33578,7 @@ var isPublisher = (value) => isRecord13(value) && typeof value.publish === "func
|
|
|
33190
33578
|
var publisherModulePath = (projectRoot, requested) => {
|
|
33191
33579
|
const root = resolve16(projectRoot);
|
|
33192
33580
|
const path = resolve16(root, requested);
|
|
33193
|
-
const projectRelative =
|
|
33581
|
+
const projectRelative = relative14(root, path);
|
|
33194
33582
|
if (projectRelative === ".." || projectRelative.startsWith(`..${sep9}`) || isAbsolute7(projectRelative)) {
|
|
33195
33583
|
throw new TypeError("mobile publish --registry must remain inside the project.");
|
|
33196
33584
|
}
|
|
@@ -33198,7 +33586,7 @@ var publisherModulePath = (projectRoot, requested) => {
|
|
|
33198
33586
|
};
|
|
33199
33587
|
var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
|
|
33200
33588
|
const modulePath = publisherModulePath(projectRoot, requestedModulePath);
|
|
33201
|
-
await
|
|
33589
|
+
await access15(modulePath).catch(() => {
|
|
33202
33590
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
33203
33591
|
});
|
|
33204
33592
|
const loaded = await import(pathToFileURL3(modulePath).href);
|
|
@@ -33262,7 +33650,7 @@ var publishAbsoluteIosRelease = async (options) => {
|
|
|
33262
33650
|
init_pageProtocol();
|
|
33263
33651
|
init_releaseArtifact();
|
|
33264
33652
|
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
33265
|
-
import { dirname as dirname17, extname as extname6, relative as
|
|
33653
|
+
import { dirname as dirname17, extname as extname6, relative as relative15, resolve as resolve17 } from "path";
|
|
33266
33654
|
import ts2 from "typescript";
|
|
33267
33655
|
var ROUTE_METHODS = new Set(["get", "head"]);
|
|
33268
33656
|
var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
|
|
@@ -33431,7 +33819,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
|
|
|
33431
33819
|
const declaration = symbol?.declarations?.[0];
|
|
33432
33820
|
const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
|
|
33433
33821
|
const exportedName = symbol?.name ?? expression.getText(sourceFile);
|
|
33434
|
-
const source = posixPath(
|
|
33822
|
+
const source = posixPath(relative15(projectRoot, file));
|
|
33435
33823
|
return `${source}#${exportedName}`;
|
|
33436
33824
|
};
|
|
33437
33825
|
var resolveAlias = (symbol, checker) => {
|
|
@@ -33787,7 +34175,7 @@ var inspectAbsoluteMobileRouteMetadata = (options) => {
|
|
|
33787
34175
|
const entry = resolve17(options.entry);
|
|
33788
34176
|
const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
|
|
33789
34177
|
return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
|
|
33790
|
-
file: posixPath(
|
|
34178
|
+
file: posixPath(relative15(projectRoot, file)),
|
|
33791
34179
|
metadata
|
|
33792
34180
|
})));
|
|
33793
34181
|
};
|
|
@@ -33846,11 +34234,11 @@ var resolveAbsoluteHttpUrl = (target, origin) => {
|
|
|
33846
34234
|
var createAbsoluteHttpTransport = ({
|
|
33847
34235
|
fetch: fetchImpl = globalThis.fetch,
|
|
33848
34236
|
origin,
|
|
33849
|
-
runtime
|
|
34237
|
+
runtime: runtime2
|
|
33850
34238
|
}) => ({
|
|
33851
34239
|
fetch: fetchImpl,
|
|
33852
34240
|
origin: normalizeAbsoluteHttpOrigin(origin),
|
|
33853
|
-
runtime
|
|
34241
|
+
runtime: runtime2
|
|
33854
34242
|
});
|
|
33855
34243
|
var createWebHttpTransport = (options = {}) => {
|
|
33856
34244
|
const origin = options.origin ?? globalThis.location?.origin;
|
|
@@ -37784,7 +38172,7 @@ var createBeacon = (options) => {
|
|
|
37784
38172
|
if (signals !== null && signals.mediaFailures !== false && typeof document !== "undefined") {
|
|
37785
38173
|
const stallMs = signals.mediaStallMs ?? MEDIA_STALL_DEFAULT_MS;
|
|
37786
38174
|
const watched = new Map;
|
|
37787
|
-
const
|
|
38175
|
+
const watch3 = (media) => {
|
|
37788
38176
|
if (watched.has(media) || !media.hasAttribute(BEACON_ATTRIBUTE.MEDIA))
|
|
37789
38177
|
return;
|
|
37790
38178
|
const name = media.getAttribute(BEACON_ATTRIBUTE.MEDIA)?.trim() || describeElement(media);
|
|
@@ -37845,10 +38233,10 @@ var createBeacon = (options) => {
|
|
|
37845
38233
|
};
|
|
37846
38234
|
const scan = (root) => {
|
|
37847
38235
|
if (root instanceof HTMLMediaElement)
|
|
37848
|
-
|
|
38236
|
+
watch3(root);
|
|
37849
38237
|
for (const media of Array.from(root.querySelectorAll?.(`audio[${BEACON_ATTRIBUTE.MEDIA}], video[${BEACON_ATTRIBUTE.MEDIA}]`) ?? [])) {
|
|
37850
38238
|
if (media instanceof HTMLMediaElement)
|
|
37851
|
-
|
|
38239
|
+
watch3(media);
|
|
37852
38240
|
}
|
|
37853
38241
|
};
|
|
37854
38242
|
scan(document);
|
|
@@ -37898,7 +38286,7 @@ var createBeacon = (options) => {
|
|
|
37898
38286
|
const originalOpen = factory.open.bind(factory);
|
|
37899
38287
|
const originalDeleteDatabase = factory.deleteDatabase.bind(factory);
|
|
37900
38288
|
const reported = new WeakSet;
|
|
37901
|
-
const
|
|
38289
|
+
const watch3 = (request, operation2, database) => {
|
|
37902
38290
|
request.addEventListener("error", () => {
|
|
37903
38291
|
if (reported.has(request))
|
|
37904
38292
|
return;
|
|
@@ -37914,8 +38302,8 @@ var createBeacon = (options) => {
|
|
|
37914
38302
|
}, { once: true });
|
|
37915
38303
|
return request;
|
|
37916
38304
|
};
|
|
37917
|
-
const wrappedOpen = (name, version) =>
|
|
37918
|
-
const wrappedDeleteDatabase = (name) =>
|
|
38305
|
+
const wrappedOpen = (name, version) => watch3(version === undefined ? originalOpen(name) : originalOpen(name, version), "open", name);
|
|
38306
|
+
const wrappedDeleteDatabase = (name) => watch3(originalDeleteDatabase(name), "delete", name);
|
|
37919
38307
|
try {
|
|
37920
38308
|
factory.open = wrappedOpen;
|
|
37921
38309
|
factory.deleteDatabase = wrappedDeleteDatabase;
|
|
@@ -39979,44 +40367,44 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
39979
40367
|
};
|
|
39980
40368
|
};
|
|
39981
40369
|
// src/mobile/updatePublisher.ts
|
|
39982
|
-
import { access as
|
|
39983
|
-
import { isAbsolute as isAbsolute8, relative as
|
|
40370
|
+
import { access as access16 } from "fs/promises";
|
|
40371
|
+
import { isAbsolute as isAbsolute8, relative as relative17, resolve as resolve19, sep as sep10 } from "path";
|
|
39984
40372
|
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
39985
40373
|
|
|
39986
40374
|
// src/mobile/updateSigning.ts
|
|
39987
|
-
import { createHash as
|
|
40375
|
+
import { createHash as createHash14, sign, verify } from "crypto";
|
|
39988
40376
|
import {
|
|
39989
40377
|
cp as cp3,
|
|
39990
40378
|
mkdir as mkdir17,
|
|
39991
40379
|
mkdtemp as mkdtemp8,
|
|
39992
|
-
readdir as
|
|
39993
|
-
readFile as
|
|
40380
|
+
readdir as readdir8,
|
|
40381
|
+
readFile as readFile23,
|
|
39994
40382
|
rename as rename16,
|
|
39995
40383
|
rm as rm13,
|
|
39996
40384
|
stat as stat4,
|
|
39997
40385
|
writeFile as writeFile20
|
|
39998
40386
|
} from "fs/promises";
|
|
39999
|
-
import { dirname as dirname18, join as
|
|
40387
|
+
import { dirname as dirname18, join as join27, relative as relative16, resolve as resolve18 } from "path";
|
|
40000
40388
|
var UPDATE_MANIFEST_FILE = "update.json";
|
|
40001
40389
|
var UPDATE_FILES_DIRECTORY = "files";
|
|
40002
|
-
var sha2562 = (value) =>
|
|
40390
|
+
var sha2562 = (value) => createHash14("sha256").update(value).digest("hex");
|
|
40003
40391
|
var listFiles = async (root, directory = root) => {
|
|
40004
|
-
const entries = await
|
|
40392
|
+
const entries = await readdir8(directory, { withFileTypes: true });
|
|
40005
40393
|
const paths = await Promise.all(entries.map(async (entry) => {
|
|
40006
|
-
const path =
|
|
40394
|
+
const path = join27(directory, entry.name);
|
|
40007
40395
|
if (entry.isDirectory())
|
|
40008
40396
|
return listFiles(root, path);
|
|
40009
40397
|
if (!entry.isFile())
|
|
40010
40398
|
throw new TypeError("Mobile updates cannot contain links or special files.");
|
|
40011
|
-
return [
|
|
40399
|
+
return [relative16(root, path).replaceAll("\\", "/")];
|
|
40012
40400
|
}));
|
|
40013
40401
|
return paths.flat().sort((left, right) => left.localeCompare(right));
|
|
40014
40402
|
};
|
|
40015
40403
|
var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
|
|
40016
|
-
const source =
|
|
40404
|
+
const source = join27(root, path);
|
|
40017
40405
|
const [metadata, contents] = await Promise.all([
|
|
40018
40406
|
stat4(source),
|
|
40019
|
-
|
|
40407
|
+
readFile23(source)
|
|
40020
40408
|
]);
|
|
40021
40409
|
return { bytes: metadata.size, path, sha256: sha2562(contents) };
|
|
40022
40410
|
}));
|
|
@@ -40052,14 +40440,14 @@ var buildAbsoluteMobileUpdate = async (options) => {
|
|
|
40052
40440
|
}
|
|
40053
40441
|
});
|
|
40054
40442
|
await mkdir17(outputRoot, { recursive: true });
|
|
40055
|
-
const outputDirectory =
|
|
40056
|
-
const staging = await mkdtemp8(
|
|
40443
|
+
const outputDirectory = join27(outputRoot, manifest.releaseId);
|
|
40444
|
+
const staging = await mkdtemp8(join27(outputRoot, ".stage-"));
|
|
40057
40445
|
try {
|
|
40058
|
-
await cp3(bundleDirectory,
|
|
40446
|
+
await cp3(bundleDirectory, join27(staging, UPDATE_FILES_DIRECTORY), {
|
|
40059
40447
|
force: true,
|
|
40060
40448
|
recursive: true
|
|
40061
40449
|
});
|
|
40062
|
-
await writeFile20(
|
|
40450
|
+
await writeFile20(join27(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
40063
40451
|
`);
|
|
40064
40452
|
await rename16(staging, outputDirectory);
|
|
40065
40453
|
} catch (error) {
|
|
@@ -40070,7 +40458,7 @@ var buildAbsoluteMobileUpdate = async (options) => {
|
|
|
40070
40458
|
}
|
|
40071
40459
|
return {
|
|
40072
40460
|
manifest,
|
|
40073
|
-
manifestPath:
|
|
40461
|
+
manifestPath: join27(outputDirectory, UPDATE_MANIFEST_FILE),
|
|
40074
40462
|
outputDirectory
|
|
40075
40463
|
};
|
|
40076
40464
|
};
|
|
@@ -40082,7 +40470,7 @@ var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) =>
|
|
|
40082
40470
|
await mkdir17(dirname18(destination), { recursive: true });
|
|
40083
40471
|
await cp3(source, destination, { force: true });
|
|
40084
40472
|
};
|
|
40085
|
-
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await
|
|
40473
|
+
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile23(join27(resolve18(directory), UPDATE_MANIFEST_FILE), "utf8")));
|
|
40086
40474
|
var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
|
|
40087
40475
|
const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
|
|
40088
40476
|
const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
|
|
@@ -40201,14 +40589,14 @@ var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "
|
|
|
40201
40589
|
var projectPath2 = (projectRoot, requested, label) => {
|
|
40202
40590
|
const root = resolve19(projectRoot);
|
|
40203
40591
|
const path = resolve19(root, requested);
|
|
40204
|
-
const projectRelative =
|
|
40592
|
+
const projectRelative = relative17(root, path);
|
|
40205
40593
|
if (projectRelative === ".." || projectRelative.startsWith(`..${sep10}`) || isAbsolute8(projectRelative))
|
|
40206
40594
|
throw new TypeError(`${label} must remain inside the project.`);
|
|
40207
40595
|
return path;
|
|
40208
40596
|
};
|
|
40209
40597
|
var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
|
|
40210
40598
|
const modulePath = projectPath2(projectRoot, requestedModulePath, "mobile update registry");
|
|
40211
|
-
await
|
|
40599
|
+
await access16(modulePath).catch(() => {
|
|
40212
40600
|
throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
|
|
40213
40601
|
});
|
|
40214
40602
|
const loaded = await import(pathToFileURL4(modulePath).href);
|
|
@@ -40259,7 +40647,7 @@ var rollbackAbsoluteMobileUpdate = async (options) => {
|
|
|
40259
40647
|
return result;
|
|
40260
40648
|
};
|
|
40261
40649
|
// src/mobile/updateRollout.ts
|
|
40262
|
-
import { createHash as
|
|
40650
|
+
import { createHash as createHash15 } from "crypto";
|
|
40263
40651
|
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;
|
|
40264
40652
|
var requireHeader = (headers, name) => {
|
|
40265
40653
|
const value = headers.get(name);
|
|
@@ -40274,7 +40662,7 @@ var isAbsoluteMobileUpdateRolloutMember = (options) => {
|
|
|
40274
40662
|
return false;
|
|
40275
40663
|
if (options.rollout === 1)
|
|
40276
40664
|
return true;
|
|
40277
|
-
const digest =
|
|
40665
|
+
const digest = createHash15("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
|
|
40278
40666
|
const bucket = digest.readUInt32BE(0) / 4294967296;
|
|
40279
40667
|
return bucket < options.rollout;
|
|
40280
40668
|
};
|
|
@@ -40381,6 +40769,7 @@ export {
|
|
|
40381
40769
|
copyAbsoluteMobileUpdateFile,
|
|
40382
40770
|
createAbsoluteExpoBridgeError,
|
|
40383
40771
|
createAbsoluteExpoBridgeResponse,
|
|
40772
|
+
createAbsoluteExpoNativeWatcher,
|
|
40384
40773
|
createAbsoluteIosNativeWatcher,
|
|
40385
40774
|
createAbsoluteMobileAssociationDocuments,
|
|
40386
40775
|
createAbsoluteMobileAssociationPlugin,
|
|
@@ -40412,6 +40801,7 @@ export {
|
|
|
40412
40801
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
40413
40802
|
finalizeAbsoluteMobilePage,
|
|
40414
40803
|
finalizeAbsoluteRouteData,
|
|
40804
|
+
fingerprintAbsoluteExpoNativeInputs,
|
|
40415
40805
|
fingerprintAbsoluteIosDevProject,
|
|
40416
40806
|
fingerprintAbsoluteIosNativeProject,
|
|
40417
40807
|
fingerprintAbsoluteMobileUpdateRuntime,
|
|
@@ -40440,6 +40830,7 @@ export {
|
|
|
40440
40830
|
installAbsoluteMobileSyncRemediation,
|
|
40441
40831
|
installAbsoluteMobileUiPrimitives,
|
|
40442
40832
|
installAbsoluteRemoteMacAgent,
|
|
40833
|
+
isAbsoluteExpoNativeRootInput,
|
|
40443
40834
|
isAbsoluteIosNativeRootInput,
|
|
40444
40835
|
isAbsoluteMobileUpdateRolloutMember,
|
|
40445
40836
|
listAbsoluteRemoteMacProfiles,
|
|
@@ -40540,5 +40931,5 @@ export {
|
|
|
40540
40931
|
writeAbsoluteMobileUpdateRegistry
|
|
40541
40932
|
};
|
|
40542
40933
|
|
|
40543
|
-
//# debugId=
|
|
40934
|
+
//# debugId=60D5DDBF8A7817D064756E2164756E21
|
|
40544
40935
|
//# sourceMappingURL=index.js.map
|