@absolutejs/absolute 0.20.0-beta.103 → 0.20.0-beta.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/changelog.json +33 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/{compile-4xbpm6hf.js → compile-hsbs1xf6.js} +2 -2
- package/dist/cli/{dev-m4r4zs2k.js → dev-9cp5t2n1.js} +4 -4
- package/dist/cli/{expoProject-780thyfd.js → expoProject-zkprmjjz.js} +1 -1
- package/dist/cli/{index-d5fr1xp3.js → index-0zcebhm4.js} +59 -1
- package/dist/cli/{index-wpfvpsk7.js → index-5skbydh0.js} +1 -1
- package/dist/cli/{index-3sdvzrv2.js → index-7fxrgx5q.js} +1 -1
- package/dist/cli/{index-6ff78meg.js → index-hrzd7e5x.js} +10 -2
- package/dist/cli/{index-rvpd4w9t.js → index-mazxtfh4.js} +1 -1
- package/dist/cli/{index-qxnptvwn.js → index-q1d4ns4n.js} +100 -9
- package/dist/cli/index.js +5 -5
- package/dist/cli/{iosNativeWatcher-3k715hq0.js → iosNativeWatcher-t6gv0p1w.js} +2 -2
- package/dist/cli/{iosSimulatorController-dr98a0p9.js → iosSimulatorController-5n2a9fxv.js} +2 -2
- package/dist/cli/{mobile-6xe6zysv.js → mobile-fbtq3s5x.js} +1240 -370
- package/dist/cli/{remoteMacProtocol-kqvkp0qd.js → remoteMacProtocol-bbramzh6.js} +2 -2
- package/dist/cli/{start-nmyy64tr.js → start-5grq7nfr.js} +3 -3
- package/dist/mobile/index.js +1340 -571
- package/dist/mobile/index.js.map +10 -8
- package/dist/mobile/remoteMacAgentEntry.js +302 -255
- package/dist/src/mobile/index.d.ts +2 -0
- package/dist/src/mobile/iosRelease.d.ts +31 -7
- package/dist/src/mobile/iosReleaseAcceptance.d.ts +63 -0
- package/dist/src/mobile/iosTestReport.d.ts +1 -0
- package/dist/src/mobile/nativeReleaseReadiness.d.ts +5 -0
- package/dist/src/mobile/nativeTestReport.d.ts +15 -0
- package/dist/src/mobile/releaseDoctor.d.ts +2 -0
- package/dist/src/mobile/remoteMacProtocol.d.ts +7 -1
- package/dist/src/mobile/shellReleaseReadiness.d.ts +2 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,20 @@ This file is generated by `absolute-changelog` from the entries in
|
|
|
6
6
|
`changelog/`. Edit an entry, not this file — and add new ones under
|
|
7
7
|
`changelog/unreleased/`.
|
|
8
8
|
|
|
9
|
+
## 0.20.0-beta.105 — 2026-09-16
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **iOS releases gain three-lane installed-app acceptance** (`AbsoluteIosReleaseMetadata`, `BuildAbsoluteIosReleaseOptions`, `buildAbsoluteIosRelease`, `buildAbsoluteRemoteIosRelease`, `installAbsoluteIosRelease`, `readAbsoluteIosRelease`, `requireAbsoluteIosReleaseMetadata`, `runAbsoluteIosDeviceReleaseAcceptance`, `runAbsoluteIosSimulatorReleaseAcceptance`)
|
|
14
|
+
`absolute mobile test ios --release` now records honest source-equivalent Simulator, same-archive registered-device, or Apple-processed TestFlight evidence. Capacitor and Expo emit version/build-specific native readiness markers, immutable releases can include a separately hashed registered-device IPA, physical offline claims require explicit confirmation, and sanitized reports retain only artifact classification, outcome, and bounded timings.
|
|
15
|
+
|
|
16
|
+
## 0.20.0-beta.104 — 2026-09-16
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Capacitor Android releases gain installed offline AAB acceptance**
|
|
21
|
+
The provider-neutral release command now installs the exact Capacitor AAB-derived APK set on the managed emulator, takes both network transports offline, and requires an AbsoluteJS-owned native readiness signal across a cold launch and process relaunch. Bun workspace-hoisted Capacitor executables and package manifests are resolved only through the application’s governing workspace. Reports and telemetry retain only provider, artifact identity, outcome, and bounded timings.
|
|
22
|
+
|
|
9
23
|
## 0.20.0-beta.103 — 2026-09-16
|
|
10
24
|
|
|
11
25
|
### Added
|
package/changelog.json
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
"contract": 1,
|
|
3
3
|
"name": "@absolutejs/absolute",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"detail": "`absolute mobile test ios --release` now records honest source-equivalent Simulator, same-archive registered-device, or Apple-processed TestFlight evidence. Capacitor and Expo emit version/build-specific native readiness markers, immutable releases can include a separately hashed registered-device IPA, physical offline claims require explicit confirmation, and sanitized reports retain only artifact classification, outcome, and bounded timings.",
|
|
9
|
+
"kind": "added",
|
|
10
|
+
"summary": "iOS releases gain three-lane installed-app acceptance",
|
|
11
|
+
"symbols": [
|
|
12
|
+
"AbsoluteIosReleaseMetadata",
|
|
13
|
+
"BuildAbsoluteIosReleaseOptions",
|
|
14
|
+
"buildAbsoluteIosRelease",
|
|
15
|
+
"buildAbsoluteRemoteIosRelease",
|
|
16
|
+
"installAbsoluteIosRelease",
|
|
17
|
+
"readAbsoluteIosRelease",
|
|
18
|
+
"requireAbsoluteIosReleaseMetadata",
|
|
19
|
+
"runAbsoluteIosDeviceReleaseAcceptance",
|
|
20
|
+
"runAbsoluteIosSimulatorReleaseAcceptance"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"date": "2026-09-16",
|
|
25
|
+
"version": "0.20.0-beta.105"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"changes": [
|
|
29
|
+
{
|
|
30
|
+
"detail": "The provider-neutral release command now installs the exact Capacitor AAB-derived APK set on the managed emulator, takes both network transports offline, and requires an AbsoluteJS-owned native readiness signal across a cold launch and process relaunch. Bun workspace-hoisted Capacitor executables and package manifests are resolved only through the application’s governing workspace. Reports and telemetry retain only provider, artifact identity, outcome, and bounded timings.",
|
|
31
|
+
"kind": "added",
|
|
32
|
+
"summary": "Capacitor Android releases gain installed offline AAB acceptance"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"date": "2026-09-16",
|
|
36
|
+
"version": "0.20.0-beta.104"
|
|
37
|
+
},
|
|
5
38
|
{
|
|
6
39
|
"changes": [
|
|
7
40
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-WzPLk5/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-WzPLk5/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
48
48
|
getWarningController()?.maybeWarn(primitiveName);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
// .angular-partial-tmp-
|
|
51
|
+
// .angular-partial-tmp-WzPLk5/src/core/streamingSlotRegistry.ts
|
|
52
52
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
53
53
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
54
54
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
createIslandRegistryDefinitionPlugin,
|
|
16
16
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
17
17
|
resolveServerBundleExternals
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-hrzd7e5x.js";
|
|
19
19
|
import {
|
|
20
20
|
loadIslandRegistryBuildInfo
|
|
21
21
|
} from "./index-bzs19w3r.js";
|
|
@@ -36,7 +36,7 @@ import"./index-w5vswatm.js";
|
|
|
36
36
|
import {
|
|
37
37
|
normalizeAbsoluteMobileConfig
|
|
38
38
|
} from "./index-rd2hbttb.js";
|
|
39
|
-
import"./index-
|
|
39
|
+
import"./index-0zcebhm4.js";
|
|
40
40
|
import {
|
|
41
41
|
ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
|
|
42
42
|
installAbsoluteMobileAuthEnvironment
|
|
@@ -1286,16 +1286,16 @@ var loadAbsoluteMobileDevModules = async () => {
|
|
|
1286
1286
|
expoNativeWatcher
|
|
1287
1287
|
] = await Promise.all([
|
|
1288
1288
|
import("./config-vy04mqce.js"),
|
|
1289
|
-
import("./expoProject-
|
|
1289
|
+
import("./expoProject-zkprmjjz.js"),
|
|
1290
1290
|
import("./expoDevController-zz516pdd.js"),
|
|
1291
1291
|
import("./nativeAuth-zx4tsb1f.js"),
|
|
1292
1292
|
import("./androidEmulatorController-nybhzc6c.js"),
|
|
1293
1293
|
import("./emulatorDoctor-y2nqmaha.js"),
|
|
1294
1294
|
import("./emulatorInstaller-3shdna4g.js"),
|
|
1295
1295
|
import("./androidNativeWatcher-2930tb8c.js"),
|
|
1296
|
-
import("./iosSimulatorController-
|
|
1297
|
-
import("./remoteMacProtocol-
|
|
1298
|
-
import("./iosNativeWatcher-
|
|
1296
|
+
import("./iosSimulatorController-5n2a9fxv.js"),
|
|
1297
|
+
import("./remoteMacProtocol-bbramzh6.js"),
|
|
1298
|
+
import("./iosNativeWatcher-t6gv0p1w.js"),
|
|
1299
1299
|
import("./expoNativeWatcher-rmc95bak.js")
|
|
1300
1300
|
]);
|
|
1301
1301
|
return {
|
|
@@ -1416,9 +1416,59 @@ var moduleConfig2 = `${JSON.stringify({
|
|
|
1416
1416
|
"expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryModule"
|
|
1417
1417
|
]
|
|
1418
1418
|
},
|
|
1419
|
-
|
|
1419
|
+
apple: { modules: ["AbsoluteActivityResultRecoveryModule"] },
|
|
1420
|
+
platforms: ["apple", "android"]
|
|
1420
1421
|
}, null, 2)}
|
|
1421
1422
|
`;
|
|
1423
|
+
var podspec2 = `${HEADER2}Pod::Spec.new do |s|
|
|
1424
|
+
s.name = 'AbsoluteActivityResultRecovery'
|
|
1425
|
+
s.version = '0.0.1'
|
|
1426
|
+
s.summary = 'AbsoluteJS native runtime readiness bridge'
|
|
1427
|
+
s.description = 'Generated lifecycle and embedded-content readiness bridge for an AbsoluteJS Expo application.'
|
|
1428
|
+
s.author = 'AbsoluteJS'
|
|
1429
|
+
s.homepage = 'https://absolutejs.com'
|
|
1430
|
+
s.platforms = { :ios => '16.4' }
|
|
1431
|
+
s.source = { git: '' }
|
|
1432
|
+
s.static_framework = true
|
|
1433
|
+
s.dependency 'ExpoModulesCore'
|
|
1434
|
+
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
|
1435
|
+
s.source_files = '**/*.{h,m,mm,swift,hpp,cpp}'
|
|
1436
|
+
end
|
|
1437
|
+
`;
|
|
1438
|
+
var iosModule2 = `${HEADER2}import ExpoModulesCore
|
|
1439
|
+
|
|
1440
|
+
public final class AbsoluteActivityResultRecoveryModule: Module {
|
|
1441
|
+
public func definition() -> ModuleDefinition {
|
|
1442
|
+
Name("AbsoluteActivityResultRecovery")
|
|
1443
|
+
|
|
1444
|
+
Function("markApplicationRuntimeReady") { }
|
|
1445
|
+
|
|
1446
|
+
Function("markEmbeddedWebReady") {
|
|
1447
|
+
let info = Bundle.main.infoDictionary ?? [:]
|
|
1448
|
+
let version = info["CFBundleShortVersionString"] as? String ?? "unknown"
|
|
1449
|
+
let build = info["CFBundleVersion"] as? String ?? "unknown"
|
|
1450
|
+
NSLog("AbsoluteJS: Expo embedded web content ready; version=%@; build=%@", version, build)
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
Function("markEmbeddedWebPhase") { (phase: String) in
|
|
1454
|
+
let allowed = [
|
|
1455
|
+
"assets-start", "assets-ready", "assets-root-failed",
|
|
1456
|
+
"assets-directory-failed", "assets-destination-failed",
|
|
1457
|
+
"assets-module-failed", "assets-source-failed",
|
|
1458
|
+
"assets-download-failed", "assets-copy-failed",
|
|
1459
|
+
"assets-read-failed", "assets-write-failed",
|
|
1460
|
+
"assets-finalize-failed", "assets-unexpected-failed",
|
|
1461
|
+
"devices-start", "devices-ready", "devices-failed"
|
|
1462
|
+
]
|
|
1463
|
+
if allowed.contains(phase) {
|
|
1464
|
+
NSLog("AbsoluteJS: Expo embedded web phase: %@", phase)
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
Function("takePendingCancellation") { false }
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
`;
|
|
1422
1472
|
var androidBuild2 = `${HEADER2}plugins {
|
|
1423
1473
|
id 'com.android.library'
|
|
1424
1474
|
id 'expo-module-gradle-plugin'
|
|
@@ -1595,6 +1645,14 @@ var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
|
|
|
1595
1645
|
join4(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
|
|
1596
1646
|
moduleConfig2
|
|
1597
1647
|
],
|
|
1648
|
+
[
|
|
1649
|
+
join4(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecovery.podspec"),
|
|
1650
|
+
podspec2
|
|
1651
|
+
],
|
|
1652
|
+
[
|
|
1653
|
+
join4(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecoveryModule.swift"),
|
|
1654
|
+
iosModule2
|
|
1655
|
+
],
|
|
1598
1656
|
[
|
|
1599
1657
|
join4(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
|
|
1600
1658
|
androidBuild2
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
resolveAbsoluteMobileUpdateRuntime,
|
|
11
11
|
syncAbsoluteExpoWebAssets,
|
|
12
12
|
writeAbsoluteExpoProject
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-0zcebhm4.js";
|
|
14
14
|
|
|
15
15
|
// src/build/islandRegistryTransform.ts
|
|
16
16
|
import { basename } from "path";
|
|
@@ -847,6 +847,12 @@ var shellUpdateModule = () => {
|
|
|
847
847
|
return candidate;
|
|
848
848
|
throw new TypeError("AbsoluteJS mobile update shell module is missing.");
|
|
849
849
|
};
|
|
850
|
+
var shellReleaseReadinessModule = () => {
|
|
851
|
+
const candidate = ["js", "ts"].map((extension) => join2(import.meta.dir, `shellReleaseReadiness.${extension}`)).find(existsSync);
|
|
852
|
+
if (candidate)
|
|
853
|
+
return candidate;
|
|
854
|
+
throw new TypeError("AbsoluteJS mobile release-readiness module is missing.");
|
|
855
|
+
};
|
|
850
856
|
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
851
857
|
var contentSecurityPolicy = (productionOrigin) => {
|
|
852
858
|
const backend = new URL(productionOrigin);
|
|
@@ -937,6 +943,7 @@ const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absolu
|
|
|
937
943
|
const entryPath = join2(staging, ".absolute-mobile-entry.ts");
|
|
938
944
|
const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
|
|
939
945
|
const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
|
|
946
|
+
const readinessImport = capacitor ? `import { markAbsoluteMobileShellReady } from ${JSON.stringify(shellReleaseReadinessModule())};` : "";
|
|
940
947
|
const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : `installAbsoluteExpoWebDeviceAdapter(${JSON.stringify(deviceCapabilities.capabilities)});`;
|
|
941
948
|
const shellOptionProperties = [
|
|
942
949
|
`engine: ${JSON.stringify(engine)}`
|
|
@@ -954,9 +961,10 @@ const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absolu
|
|
|
954
961
|
const shellOptions = `{ ${shellOptionProperties.join(", ")} }`;
|
|
955
962
|
await writeFile2(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
|
|
956
963
|
${adapterImport}
|
|
964
|
+
${readinessImport}
|
|
957
965
|
${authImport}${syncImport}${pushImport}${updateImport}${capabilityImports}
|
|
958
966
|
${pushSetup}${adapterInstall}
|
|
959
|
-
void startAbsoluteMobileShell(${shellOptions});
|
|
967
|
+
void startAbsoluteMobileShell(${shellOptions})${capacitor ? ".then(markAbsoluteMobileShellReady)" : ""};
|
|
960
968
|
`);
|
|
961
969
|
const build = await Bun.build({
|
|
962
970
|
entrypoints: [entryPath],
|
|
@@ -120,6 +120,25 @@ var safeOutputDirectory = (projectRoot, requested) => {
|
|
|
120
120
|
return output;
|
|
121
121
|
};
|
|
122
122
|
var sha256File = async (path) => createHash("sha256").update(await readFile(path)).digest("hex");
|
|
123
|
+
var verifyRegisteredReleaseArtifact = async (releaseRoot, metadata) => {
|
|
124
|
+
if (!metadata.registeredDevice)
|
|
125
|
+
return;
|
|
126
|
+
const destination = join(releaseRoot, metadata.registeredDevice.artifact);
|
|
127
|
+
const [bytes, sha256] = await Promise.all([
|
|
128
|
+
stat(destination).then(({ size }) => size),
|
|
129
|
+
sha256File(destination)
|
|
130
|
+
]);
|
|
131
|
+
if (bytes !== metadata.registeredDevice.bytes || sha256 !== metadata.registeredDevice.sha256)
|
|
132
|
+
throw new TypeError(`Immutable iOS release ${metadata.releaseId} registered-device artifact is missing or modified.`);
|
|
133
|
+
return destination;
|
|
134
|
+
};
|
|
135
|
+
var copyRegisteredReleaseArtifact = async (staging, metadata, registeredArtifactPath) => {
|
|
136
|
+
if (!metadata.registeredDevice)
|
|
137
|
+
return;
|
|
138
|
+
if (!registeredArtifactPath)
|
|
139
|
+
throw new TypeError("iOS release metadata requires a registered-device artifact.");
|
|
140
|
+
await copyFile(registeredArtifactPath, join(staging, metadata.registeredDevice.artifact));
|
|
141
|
+
};
|
|
123
142
|
var findByExtension = async (root, extension) => {
|
|
124
143
|
if (!await pathExists(root))
|
|
125
144
|
return;
|
|
@@ -175,12 +194,12 @@ var resolveAbsoluteIosXcodeProject = async (nativeDirectory, options = {}) => {
|
|
|
175
194
|
throw new TypeError(schemes.length > 1 ? `iOS release found multiple shared Xcode schemes: ${schemes.join(", ")}. Pass an explicit scheme.` : "iOS release could not find a shared Xcode scheme.");
|
|
176
195
|
return { scheme: schemes[0], workspacePath };
|
|
177
196
|
};
|
|
178
|
-
var exportOptions = () => `<?xml version="1.0" encoding="UTF-8"?>
|
|
197
|
+
var exportOptions = (method) => `<?xml version="1.0" encoding="UTF-8"?>
|
|
179
198
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
180
199
|
<plist version="1.0"><dict>
|
|
181
200
|
<key>destination</key><string>export</string>
|
|
182
201
|
<key>manageAppVersionAndBuildNumber</key><false/>
|
|
183
|
-
<key>method</key><string
|
|
202
|
+
<key>method</key><string>${method}</string>
|
|
184
203
|
<key>signingStyle</key><string>automatic</string>
|
|
185
204
|
<key>stripSwiftSymbols</key><true/>
|
|
186
205
|
<key>uploadSymbols</key><true/>
|
|
@@ -191,7 +210,19 @@ var requireBuildNumber = (value) => {
|
|
|
191
210
|
throw new TypeError("iOS build number must be a positive integer.");
|
|
192
211
|
return value;
|
|
193
212
|
};
|
|
213
|
+
var normalizeRegisteredDevice = (value) => {
|
|
214
|
+
if (value === undefined)
|
|
215
|
+
return;
|
|
216
|
+
if (!isRecord(value) || value.artifact !== "App.registered.ipa" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || typeof value.sha256 !== "string" || !/^[a-f0-9]{64}$/u.test(value.sha256))
|
|
217
|
+
throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
|
|
218
|
+
return {
|
|
219
|
+
artifact: "App.registered.ipa",
|
|
220
|
+
bytes: value.bytes,
|
|
221
|
+
sha256: value.sha256
|
|
222
|
+
};
|
|
223
|
+
};
|
|
194
224
|
var requireAbsoluteIosReleaseMetadata = (value) => {
|
|
225
|
+
const registeredDevice = normalizeRegisteredDevice(isRecord(value) ? value.registeredDevice : undefined);
|
|
195
226
|
if (!isRecord(value) || value.artifact !== "App.ipa" || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || value.engine !== "capacitor" && value.engine !== "expo" || value.format !== ABSOLUTE_IOS_RELEASE_FORMAT || typeof value.marketingVersion !== "string" || value.platform !== "ios" || typeof value.releaseId !== "string" || typeof value.runtime !== "string" || typeof value.sha256 !== "string" || typeof value.signed !== "boolean" || value.type !== "ipa" || value.buildNumber !== undefined && (typeof value.buildNumber !== "number" || !Number.isSafeInteger(value.buildNumber) || value.buildNumber < 1) || !/^amobile_ios_[a-f0-9]{64}$/u.test(value.releaseId) || !/^[a-f0-9]{64}$/u.test(value.sha256) || value.releaseId !== `amobile_ios_${value.sha256}`) {
|
|
196
227
|
throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
|
|
197
228
|
}
|
|
@@ -205,6 +236,7 @@ var requireAbsoluteIosReleaseMetadata = (value) => {
|
|
|
205
236
|
format: value.format,
|
|
206
237
|
marketingVersion: value.marketingVersion,
|
|
207
238
|
platform: value.platform,
|
|
239
|
+
...registeredDevice ? { registeredDevice } : {},
|
|
208
240
|
releaseId: value.releaseId,
|
|
209
241
|
runtime: value.runtime,
|
|
210
242
|
sha256: value.sha256,
|
|
@@ -212,12 +244,13 @@ var requireAbsoluteIosReleaseMetadata = (value) => {
|
|
|
212
244
|
type: value.type
|
|
213
245
|
};
|
|
214
246
|
};
|
|
215
|
-
var installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
247
|
+
var installRelease = async (artifactPath, metadata, outputRoot, registeredArtifactPath) => {
|
|
216
248
|
const releaseRoot = join(outputRoot, metadata.releaseId);
|
|
217
249
|
const destination = join(releaseRoot, "App.ipa");
|
|
218
250
|
if (await pathExists(releaseRoot)) {
|
|
219
251
|
const value = JSON.parse(await readFile(join(releaseRoot, "release.json"), "utf8"));
|
|
220
|
-
|
|
252
|
+
const existing = requireAbsoluteIosReleaseMetadata(value);
|
|
253
|
+
if (JSON.stringify(existing) !== JSON.stringify({ ...metadata, artifact: "App.ipa" })) {
|
|
221
254
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} does not match its content.`);
|
|
222
255
|
}
|
|
223
256
|
const [bytes, sha256] = await Promise.all([
|
|
@@ -226,12 +259,14 @@ var installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
|
226
259
|
]);
|
|
227
260
|
if (bytes !== metadata.bytes || sha256 !== metadata.sha256)
|
|
228
261
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} artifact is missing or modified.`);
|
|
262
|
+
const registeredDestination = await verifyRegisteredReleaseArtifact(releaseRoot, metadata);
|
|
229
263
|
return {
|
|
230
264
|
artifactPath: destination,
|
|
231
265
|
metadata: {
|
|
232
266
|
...metadata,
|
|
233
267
|
artifact: "App.ipa"
|
|
234
268
|
},
|
|
269
|
+
...registeredDestination ? { registeredArtifactPath: registeredDestination } : {},
|
|
235
270
|
releaseRoot
|
|
236
271
|
};
|
|
237
272
|
}
|
|
@@ -239,6 +274,7 @@ var installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
|
239
274
|
const staging = await mkdtemp(join(dirname(releaseRoot), ".ios-stage-"));
|
|
240
275
|
try {
|
|
241
276
|
await copyFile(artifactPath, join(staging, "App.ipa"));
|
|
277
|
+
await copyRegisteredReleaseArtifact(staging, metadata, registeredArtifactPath);
|
|
242
278
|
const complete = {
|
|
243
279
|
...metadata,
|
|
244
280
|
artifact: "App.ipa"
|
|
@@ -246,13 +282,50 @@ var installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
|
246
282
|
await writeFile(join(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
|
|
247
283
|
`, { flag: "wx" });
|
|
248
284
|
await rename(staging, releaseRoot);
|
|
249
|
-
return {
|
|
285
|
+
return {
|
|
286
|
+
artifactPath: destination,
|
|
287
|
+
metadata: complete,
|
|
288
|
+
...metadata.registeredDevice ? {
|
|
289
|
+
registeredArtifactPath: join(releaseRoot, metadata.registeredDevice.artifact)
|
|
290
|
+
} : {},
|
|
291
|
+
releaseRoot
|
|
292
|
+
};
|
|
250
293
|
} finally {
|
|
251
294
|
await rm(staging, { force: true, recursive: true }).catch(() => {
|
|
252
295
|
return;
|
|
253
296
|
});
|
|
254
297
|
}
|
|
255
298
|
};
|
|
299
|
+
var exportRegisteredDeviceArtifact = async (options) => {
|
|
300
|
+
const exportPath = join(options.staging, "registered-export");
|
|
301
|
+
const exportPlist = join(options.staging, "RegisteredExportOptions.plist");
|
|
302
|
+
await mkdir(exportPath, { recursive: true });
|
|
303
|
+
await writeFile(exportPlist, exportOptions("debugging"));
|
|
304
|
+
const exitCode = await options.run([
|
|
305
|
+
"xcodebuild",
|
|
306
|
+
"-exportArchive",
|
|
307
|
+
"-archivePath",
|
|
308
|
+
options.archivePath,
|
|
309
|
+
"-exportPath",
|
|
310
|
+
exportPath,
|
|
311
|
+
"-exportOptionsPlist",
|
|
312
|
+
exportPlist
|
|
313
|
+
], { cwd: options.nativeDirectory, env: options.env });
|
|
314
|
+
if (exitCode !== 0)
|
|
315
|
+
throw new TypeError("Xcode failed to export the registered-device IPA. Confirm the selected development team includes the test device.");
|
|
316
|
+
const artifactPath = await findByExtension(exportPath, ".ipa");
|
|
317
|
+
if (!artifactPath)
|
|
318
|
+
throw new TypeError("Xcode did not produce a registered-device IPA.");
|
|
319
|
+
const [bytes, sha256] = await Promise.all([
|
|
320
|
+
stat(artifactPath).then(({ size }) => size),
|
|
321
|
+
sha256File(artifactPath)
|
|
322
|
+
]);
|
|
323
|
+
const metadata = { artifact: "App.registered.ipa", bytes, sha256 };
|
|
324
|
+
return {
|
|
325
|
+
artifactPath,
|
|
326
|
+
metadata
|
|
327
|
+
};
|
|
328
|
+
};
|
|
256
329
|
var buildAbsoluteIosRelease = async (options) => {
|
|
257
330
|
if (options.buildNumber !== undefined && options.prepareBuildNumber)
|
|
258
331
|
throw new TypeError("iOS release buildNumber and prepareBuildNumber cannot be combined.");
|
|
@@ -282,7 +355,7 @@ var buildAbsoluteIosRelease = async (options) => {
|
|
|
282
355
|
const exportPath = join(staging, "export");
|
|
283
356
|
const exportPlist = join(staging, "ExportOptions.plist");
|
|
284
357
|
await mkdir(exportPath, { recursive: true });
|
|
285
|
-
await writeFile(exportPlist, exportOptions());
|
|
358
|
+
await writeFile(exportPlist, exportOptions("app-store-connect"));
|
|
286
359
|
const run = options.run ?? defaultRun;
|
|
287
360
|
try {
|
|
288
361
|
const developmentTeam = developmentTeamArgument(options.developmentTeam);
|
|
@@ -339,6 +412,13 @@ var buildAbsoluteIosRelease = async (options) => {
|
|
|
339
412
|
sha256File(artifactPath)
|
|
340
413
|
]);
|
|
341
414
|
const releaseId = `amobile_ios_${sha256}`;
|
|
415
|
+
const registered = options.registeredDeviceArtifact ? await exportRegisteredDeviceArtifact({
|
|
416
|
+
archivePath,
|
|
417
|
+
...options.env ? { env: options.env } : {},
|
|
418
|
+
nativeDirectory,
|
|
419
|
+
run,
|
|
420
|
+
staging
|
|
421
|
+
}) : undefined;
|
|
342
422
|
return await installRelease(artifactPath, {
|
|
343
423
|
appBuild: manifest.appBuild,
|
|
344
424
|
appId: manifest.appId,
|
|
@@ -348,12 +428,13 @@ var buildAbsoluteIosRelease = async (options) => {
|
|
|
348
428
|
format: 1,
|
|
349
429
|
marketingVersion,
|
|
350
430
|
platform: "ios",
|
|
431
|
+
...registered ? { registeredDevice: registered.metadata } : {},
|
|
351
432
|
releaseId,
|
|
352
433
|
runtime: manifest.runtime,
|
|
353
434
|
sha256,
|
|
354
435
|
signed,
|
|
355
436
|
type: "ipa"
|
|
356
|
-
}, safeOutputDirectory(options.projectRoot, options.outputDirectory));
|
|
437
|
+
}, safeOutputDirectory(options.projectRoot, options.outputDirectory), registered?.artifactPath);
|
|
357
438
|
} finally {
|
|
358
439
|
await rm(staging, { force: true, recursive: true }).catch(() => {
|
|
359
440
|
return;
|
|
@@ -368,8 +449,18 @@ var installAbsoluteIosRelease = async (options) => {
|
|
|
368
449
|
]);
|
|
369
450
|
if (bytes !== metadata.bytes || sha256 !== metadata.sha256)
|
|
370
451
|
throw new TypeError("Remote iOS release artifact does not match its signed metadata.");
|
|
452
|
+
if (metadata.registeredDevice) {
|
|
453
|
+
if (!options.registeredArtifactPath)
|
|
454
|
+
throw new TypeError("Remote iOS release metadata requires its registered-device artifact.");
|
|
455
|
+
const [registeredBytes, registeredSha256] = await Promise.all([
|
|
456
|
+
stat(options.registeredArtifactPath).then(({ size }) => size),
|
|
457
|
+
sha256File(options.registeredArtifactPath)
|
|
458
|
+
]);
|
|
459
|
+
if (registeredBytes !== metadata.registeredDevice.bytes || registeredSha256 !== metadata.registeredDevice.sha256)
|
|
460
|
+
throw new TypeError("Remote iOS registered-device artifact does not match its signed metadata.");
|
|
461
|
+
}
|
|
371
462
|
const { artifact: _artifact, ...releaseMetadata } = metadata;
|
|
372
|
-
return installRelease(options.artifactPath, releaseMetadata, safeOutputDirectory(options.projectRoot, options.outputDirectory));
|
|
463
|
+
return installRelease(options.artifactPath, releaseMetadata, safeOutputDirectory(options.projectRoot, options.outputDirectory), options.registeredArtifactPath);
|
|
373
464
|
};
|
|
374
465
|
|
|
375
|
-
export { fingerprintAbsoluteIosNativeProject, requireAbsoluteIosReleaseMetadata, buildAbsoluteIosRelease, installAbsoluteIosRelease };
|
|
466
|
+
export { fingerprintAbsoluteIosNativeProject, resolveAbsoluteIosXcodeProject, requireAbsoluteIosReleaseMetadata, buildAbsoluteIosRelease, installAbsoluteIosRelease };
|
package/dist/cli/index.js
CHANGED
|
@@ -58,7 +58,7 @@ if (command === "dev") {
|
|
|
58
58
|
}
|
|
59
59
|
const positionalArgs = stripNamedArgs("--config", "--android-device", "--ios-device").filter((arg) => arg !== "--no-mobile" && arg !== "--eager");
|
|
60
60
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
61
|
-
const { dev } = await import("./dev-
|
|
61
|
+
const { dev } = await import("./dev-9cp5t2n1.js");
|
|
62
62
|
await dev(serverEntry, configPath, {
|
|
63
63
|
androidDevice,
|
|
64
64
|
eager: args.includes("--eager"),
|
|
@@ -71,7 +71,7 @@ if (command === "dev") {
|
|
|
71
71
|
const configPath = parseNamedArg("--config");
|
|
72
72
|
const positionalArgs = stripNamedArgs("--outdir", "--config").filter((arg) => arg !== "--prebuilt");
|
|
73
73
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
74
|
-
const { start } = await import("./start-
|
|
74
|
+
const { start } = await import("./start-5grq7nfr.js");
|
|
75
75
|
await start(serverEntry, outdir, configPath, {
|
|
76
76
|
prebuilt: args.includes("--prebuilt")
|
|
77
77
|
});
|
|
@@ -81,7 +81,7 @@ if (command === "dev") {
|
|
|
81
81
|
const configPath = parseNamedArg("--config");
|
|
82
82
|
const positionalArgs = stripNamedArgs("--outdir", "--config");
|
|
83
83
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
84
|
-
const { start } = await import("./start-
|
|
84
|
+
const { start } = await import("./start-5grq7nfr.js");
|
|
85
85
|
await start(serverEntry, outdir, configPath, { prepareOnly: true });
|
|
86
86
|
} else if (command === "build") {
|
|
87
87
|
sendTelemetryEvent("cli:command", { command });
|
|
@@ -197,13 +197,13 @@ if (command === "dev") {
|
|
|
197
197
|
const configPath = parseNamedArg("--config");
|
|
198
198
|
const positionalArgs = stripNamedArgs("--outdir", "--outfile", "--config");
|
|
199
199
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
200
|
-
const { compile } = await import("./compile-
|
|
200
|
+
const { compile } = await import("./compile-hsbs1xf6.js");
|
|
201
201
|
await compile(serverEntry, outdir, outfile, configPath);
|
|
202
202
|
} else if (command === "mobile") {
|
|
203
203
|
sendTelemetryEvent("cli:command", {
|
|
204
204
|
command: `mobile:${workspaceCommand ?? "unknown"}`
|
|
205
205
|
});
|
|
206
|
-
const { runMobile } = await import("./mobile-
|
|
206
|
+
const { runMobile } = await import("./mobile-fbtq3s5x.js");
|
|
207
207
|
try {
|
|
208
208
|
await runMobile(args);
|
|
209
209
|
} catch (error) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
fingerprintAbsoluteIosDevProject
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-5skbydh0.js";
|
|
5
|
+
import"./index-q1d4ns4n.js";
|
|
6
6
|
import"./index-j66p8hn5.js";
|
|
7
7
|
import"./index-28pbrd3q.js";
|
|
8
8
|
import"./index-knt92dm8.js";
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
redactAbsoluteIosLog,
|
|
11
11
|
repairAbsoluteIosDevSession,
|
|
12
12
|
startAbsoluteIosDevSession
|
|
13
|
-
} from "./index-
|
|
14
|
-
import"./index-
|
|
13
|
+
} from "./index-5skbydh0.js";
|
|
14
|
+
import"./index-q1d4ns4n.js";
|
|
15
15
|
import"./index-j66p8hn5.js";
|
|
16
16
|
import"./index-28pbrd3q.js";
|
|
17
17
|
import"./index-knt92dm8.js";
|