@absolutejs/absolute 0.20.0-beta.34 → 0.20.0-beta.36
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/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/angular/index.js +17 -9
- package/dist/angular/index.js.map +3 -3
- package/dist/angular/server.js +17 -9
- package/dist/angular/server.js.map +3 -3
- package/dist/build.js +30 -10
- package/dist/build.js.map +6 -6
- package/dist/cli/index.js +293 -23
- package/dist/index.js +33 -10
- package/dist/index.js.map +8 -8
- package/dist/mobile/index.js +67 -10
- package/dist/mobile/index.js.map +8 -7
- package/dist/mobile/remoteMacAgentEntry.js +11 -11
- package/dist/src/cli/instanceStatus.d.ts +1 -0
- package/dist/src/core/prepare.d.ts +12 -0
- package/dist/src/dev/clientManager.d.ts +1 -0
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/iosDeviceAcceptance.d.ts +32 -0
- package/dist/src/mobile/iosRelease.d.ts +3 -1
- package/dist/src/mobile/iosSimulatorController.d.ts +6 -1
- package/dist/src/mobile/iosTestReport.d.ts +2 -1
- package/dist/src/mobile/nativeTestReport.d.ts +6 -0
- package/dist/src/mobile/remoteMacProtocol.d.ts +7 -0
- package/dist/src/plugins/hmr.d.ts +3 -0
- package/dist/types/cli.d.ts +1 -0
- package/package.json +4 -2
package/dist/cli/index.js
CHANGED
|
@@ -458,6 +458,7 @@ var registeredPids, exitHandlerRegistered = false, instanceFilePath = (pid) => j
|
|
|
458
458
|
frameworks: toStringArray(parsed.frameworks),
|
|
459
459
|
host: typeof parsed.host === "string" ? parsed.host : "localhost",
|
|
460
460
|
https: parsed.https === true,
|
|
461
|
+
...typeof parsed.iosRemoteMac === "string" ? { iosRemoteMac: parsed.iosRemoteMac } : {},
|
|
461
462
|
logFile: typeof parsed.logFile === "string" ? parsed.logFile : null,
|
|
462
463
|
name: typeof parsed.name === "string" ? parsed.name : "unknown",
|
|
463
464
|
pid: parsed.pid,
|
|
@@ -2634,22 +2635,22 @@ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array
|
|
|
2634
2635
|
stdout: ""
|
|
2635
2636
|
};
|
|
2636
2637
|
}
|
|
2637
|
-
}, ignoredFingerprintDirectories, fingerprintFiles = async (root, current = root) => {
|
|
2638
|
+
}, ignoredFingerprintDirectories, fingerprintFiles = async (root, current = root, options = {}) => {
|
|
2638
2639
|
const entries = await readdir2(current, { withFileTypes: true });
|
|
2639
2640
|
const nested = await Promise.all(entries.sort((left, right) => left.name.localeCompare(right.name)).map(async (entry) => {
|
|
2640
2641
|
const path = join9(current, entry.name);
|
|
2641
2642
|
const projectRelative = relative3(root, path).replaceAll("\\", "/");
|
|
2642
|
-
const ignored = entry.isDirectory() && (ignoredFingerprintDirectories.has(entry.name) || projectRelative === "App/App/public");
|
|
2643
|
+
const ignored = entry.isDirectory() && (ignoredFingerprintDirectories.has(entry.name) || projectRelative === "App/App/public" && options.includePublicBundle !== true);
|
|
2643
2644
|
if (ignored)
|
|
2644
2645
|
return [];
|
|
2645
2646
|
if (entry.isDirectory())
|
|
2646
|
-
return fingerprintFiles(root, path);
|
|
2647
|
+
return fingerprintFiles(root, path, options);
|
|
2647
2648
|
return entry.isFile() ? [path] : [];
|
|
2648
2649
|
}));
|
|
2649
2650
|
return nested.flat();
|
|
2650
|
-
}, fingerprintAbsoluteIosNativeProject = async (nativeDirectory) => {
|
|
2651
|
+
}, fingerprintAbsoluteIosNativeProject = async (nativeDirectory, options = {}) => {
|
|
2651
2652
|
const hasher = createHash3("sha256");
|
|
2652
|
-
const files = await fingerprintFiles(nativeDirectory);
|
|
2653
|
+
const files = await fingerprintFiles(nativeDirectory, nativeDirectory, options);
|
|
2653
2654
|
const contents = await Promise.all(files.map((file) => readFile4(file)));
|
|
2654
2655
|
files.forEach((file, index) => {
|
|
2655
2656
|
hasher.update(relative3(nativeDirectory, file).replaceAll("\\", "/"));
|
|
@@ -3298,7 +3299,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
3298
3299
|
return;
|
|
3299
3300
|
});
|
|
3300
3301
|
}
|
|
3301
|
-
}, fingerprintAbsoluteIosDevProject = async (project) => fingerprintAbsoluteIosNativeProject(project.nativeDirectory), simulatorInventory = (xcrun, capture) => {
|
|
3302
|
+
}, fingerprintAbsoluteIosDevProject = async (project, options = {}) => fingerprintAbsoluteIosNativeProject(project.nativeDirectory, options), simulatorInventory = (xcrun, capture) => {
|
|
3302
3303
|
const result = capture([
|
|
3303
3304
|
xcrun,
|
|
3304
3305
|
"simctl",
|
|
@@ -3670,10 +3671,13 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
3670
3671
|
transition("syncing");
|
|
3671
3672
|
await requireSuccess2([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
|
|
3672
3673
|
transition("configuring");
|
|
3673
|
-
|
|
3674
|
+
if (options.embeddedBundle !== true)
|
|
3675
|
+
await writeDevProjection(project, options.port, options.https === true, serverHost);
|
|
3674
3676
|
throwIfAborted2(options.signal);
|
|
3675
3677
|
const fingerprintStartedAt = performance.now();
|
|
3676
|
-
const fingerprintPromise = fingerprintAbsoluteIosDevProject(project
|
|
3678
|
+
const fingerprintPromise = fingerprintAbsoluteIosDevProject(project, {
|
|
3679
|
+
includePublicBundle: options.embeddedBundle === true
|
|
3680
|
+
}).then((fingerprint2) => {
|
|
3677
3681
|
timings.fingerprinting = performance.now() - fingerprintStartedAt;
|
|
3678
3682
|
return fingerprint2;
|
|
3679
3683
|
});
|
|
@@ -3734,7 +3738,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
3734
3738
|
await requireSuccess2(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app launch", run, { signal: options.signal });
|
|
3735
3739
|
transition("ready");
|
|
3736
3740
|
timings.total = performance.now() - startedAt;
|
|
3737
|
-
log(`iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
3741
|
+
log(options.embeddedBundle === true ? `iOS ${targetKind} connected with the embedded bundle and backend on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).` : `iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
3738
3742
|
log(`iOS startup: ${timingSummary(timings)}.`);
|
|
3739
3743
|
let closed = false;
|
|
3740
3744
|
const close = async () => {
|
|
@@ -3923,6 +3927,17 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, PROFILE_NAME, SSH_DESTI
|
|
|
3923
3927
|
if (result.exitCode !== 0)
|
|
3924
3928
|
throw new Error(`${label} failed: ${(result.stderr || result.stdout).trim() || `status ${result.exitCode}`}`);
|
|
3925
3929
|
return result.stdout.trim();
|
|
3930
|
+
}, captureAbsoluteRemoteMacCommand = async (profile, command, transport) => {
|
|
3931
|
+
if (command.length === 0)
|
|
3932
|
+
throw new TypeError("A Remote Mac command cannot be empty.");
|
|
3933
|
+
if (command.some((argument) => /[\r\n\0]/u.test(argument)))
|
|
3934
|
+
throw new TypeError("Remote Mac command arguments cannot contain controls.");
|
|
3935
|
+
const capture = transport?.capture ?? defaultTransport.capture;
|
|
3936
|
+
return capture([
|
|
3937
|
+
...absoluteRemoteMacSshBase(profile),
|
|
3938
|
+
"/bin/sh -lc",
|
|
3939
|
+
shellQuote(command.map((argument) => shellQuote(argument)).join(" "))
|
|
3940
|
+
]);
|
|
3926
3941
|
}, getAbsoluteRemoteMacProfile = async (name, profilePath) => {
|
|
3927
3942
|
const store = await loadStore(profilePath);
|
|
3928
3943
|
const selected = name ?? process.env.ABSOLUTE_IOS_REMOTE ?? store.defaultProfile;
|
|
@@ -18432,6 +18447,44 @@ var init_androidRelease = __esm(() => {
|
|
|
18432
18447
|
init_androidEmulatorController();
|
|
18433
18448
|
});
|
|
18434
18449
|
|
|
18450
|
+
// src/mobile/iosDeviceAcceptance.ts
|
|
18451
|
+
var absoluteIosDeviceAcceptanceCommands = (options) => {
|
|
18452
|
+
const xcrun = options.xcrun ?? "/usr/bin/xcrun";
|
|
18453
|
+
const prefix = [xcrun, "devicectl", "device"];
|
|
18454
|
+
return {
|
|
18455
|
+
apps: [...prefix, "info", "apps", "--device", options.device],
|
|
18456
|
+
details: [...prefix, "info", "details", "--device", options.device],
|
|
18457
|
+
launch: [
|
|
18458
|
+
...prefix,
|
|
18459
|
+
"process",
|
|
18460
|
+
"launch",
|
|
18461
|
+
"--terminate-existing",
|
|
18462
|
+
"--device",
|
|
18463
|
+
options.device,
|
|
18464
|
+
options.appId
|
|
18465
|
+
]
|
|
18466
|
+
};
|
|
18467
|
+
}, requireSuccess3 = (result, message) => {
|
|
18468
|
+
if (result.exitCode !== 0)
|
|
18469
|
+
throw new Error(message);
|
|
18470
|
+
return result;
|
|
18471
|
+
}, testAbsoluteIosPhysicalDevice = async (options) => {
|
|
18472
|
+
const commands = absoluteIosDeviceAcceptanceCommands(options);
|
|
18473
|
+
requireSuccess3(await options.capture(commands.details), "The selected physical iOS device is unavailable. Pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode.");
|
|
18474
|
+
const apps = requireSuccess3(await options.capture(commands.apps), "AbsoluteJS could not inspect installed apps on the physical iOS device.");
|
|
18475
|
+
if (!apps.stdout.includes(options.appId))
|
|
18476
|
+
throw new Error("The AbsoluteJS app is not installed on the selected physical iOS device. Start bun dev with the same --ios-device value first.");
|
|
18477
|
+
const now = options.now ?? performance.now.bind(performance);
|
|
18478
|
+
const startedAt = now();
|
|
18479
|
+
requireSuccess3(await options.capture(commands.launch), "AbsoluteJS could not relaunch the app on the physical iOS device.");
|
|
18480
|
+
await options.waitForHmr();
|
|
18481
|
+
return {
|
|
18482
|
+
hmrConnected: true,
|
|
18483
|
+
installed: true,
|
|
18484
|
+
relaunchMs: Math.round(now() - startedAt)
|
|
18485
|
+
};
|
|
18486
|
+
};
|
|
18487
|
+
|
|
18435
18488
|
// src/mobile/iosConformance.ts
|
|
18436
18489
|
import { readFile as readFile18, stat as stat3 } from "fs/promises";
|
|
18437
18490
|
var HMR_LINE, parseAbsoluteIosHmrLog = (line) => {
|
|
@@ -18502,6 +18555,15 @@ var secretPattern, bearerPattern, coordinatePattern, nativeCredentialPattern, sa
|
|
|
18502
18555
|
if (run.hmr)
|
|
18503
18556
|
hmrResult = run.hmr.outcome === "failed" ? "FAIL" : "PASS";
|
|
18504
18557
|
const routeDetails = run.routes?.length ? ` Routes: ${run.routes.join(", ")}.` : "";
|
|
18558
|
+
let artifactDetails = "No target screenshot was captured.";
|
|
18559
|
+
let artifactResult = "FAIL";
|
|
18560
|
+
if (run.screenshot) {
|
|
18561
|
+
artifactDetails = "A target screenshot was captured. Visually review it before sharing this directory.";
|
|
18562
|
+
artifactResult = "PASS";
|
|
18563
|
+
} else if (run.targetKind === "device") {
|
|
18564
|
+
artifactDetails = "Physical-device screen capture was intentionally skipped; use Xcode Device Hub for manual visual evidence.";
|
|
18565
|
+
artifactResult = "SKIPPED";
|
|
18566
|
+
}
|
|
18505
18567
|
const checks = [
|
|
18506
18568
|
{
|
|
18507
18569
|
details: `Captured host, toolchain, Bun, and AbsoluteJS metadata for ${target}.`,
|
|
@@ -18520,10 +18582,10 @@ var secretPattern, bearerPattern, coordinatePattern, nativeCredentialPattern, sa
|
|
|
18520
18582
|
result: hmrResult
|
|
18521
18583
|
},
|
|
18522
18584
|
{
|
|
18523
|
-
details:
|
|
18585
|
+
details: artifactDetails,
|
|
18524
18586
|
...evidence ? { evidence } : {},
|
|
18525
18587
|
id: "AUTO-ARTIFACT-01",
|
|
18526
|
-
result:
|
|
18588
|
+
result: artifactResult
|
|
18527
18589
|
}
|
|
18528
18590
|
];
|
|
18529
18591
|
if (run.upgrade) {
|
|
@@ -18556,15 +18618,30 @@ var secretPattern, bearerPattern, coordinatePattern, nativeCredentialPattern, sa
|
|
|
18556
18618
|
result: Object.values(syncMigration.state).every(Boolean) ? "PASS" : "FAIL"
|
|
18557
18619
|
});
|
|
18558
18620
|
}
|
|
18621
|
+
if (run.deviceAcceptance) {
|
|
18622
|
+
checks.push({
|
|
18623
|
+
details: `The installed physical-device app relaunched and reconnected to native HMR in ${run.deviceAcceptance.relaunchMs}ms.`,
|
|
18624
|
+
id: "AUTO-DEVICE-01",
|
|
18625
|
+
result: "PASS"
|
|
18626
|
+
}, {
|
|
18627
|
+
details: run.deviceAcceptance.https ? "The physical app reached the HTTPS development server and established native HMR; this proves the active app session accepted the development trust path." : "Physical-device acceptance did not use HTTPS.",
|
|
18628
|
+
id: "AUTO-DEVICE-HTTPS-01",
|
|
18629
|
+
result: run.deviceAcceptance.https ? "PASS" : "FAIL"
|
|
18630
|
+
}, {
|
|
18631
|
+
details: run.deviceAcceptance.remote ? "The lifecycle commands ran on the paired Remote Mac and HMR returned through the active relay." : "The acceptance run used the local Mac.",
|
|
18632
|
+
id: "AUTO-DEVICE-REMOTE-01",
|
|
18633
|
+
result: run.deviceAcceptance.remote ? "PASS" : "SKIPPED"
|
|
18634
|
+
});
|
|
18635
|
+
}
|
|
18559
18636
|
return checks;
|
|
18560
18637
|
}, createAbsoluteNativeTestReport = (options) => ({
|
|
18561
18638
|
automatedChecks: options.automatedChecks ?? createAbsoluteNativeAutomatedChecks(options.run),
|
|
18562
18639
|
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
18563
|
-
manualChecks: options.manualChecks.map(([id, details]) =>
|
|
18640
|
+
manualChecks: options.manualChecks.map(([id, details]) => options.manualCheckResults?.[id] ?? {
|
|
18564
18641
|
details,
|
|
18565
18642
|
id,
|
|
18566
18643
|
result: "NOT_RUN"
|
|
18567
|
-
})
|
|
18644
|
+
}),
|
|
18568
18645
|
metadata: options.metadata,
|
|
18569
18646
|
overallResult: options.run.status === "fail" ? "FAIL" : "INCOMPLETE",
|
|
18570
18647
|
platform: options.run.platform,
|
|
@@ -18626,10 +18703,18 @@ var init_nativeTestReport = __esm(() => {
|
|
|
18626
18703
|
|
|
18627
18704
|
// src/mobile/iosTestReport.ts
|
|
18628
18705
|
var MANUAL_CHECKS, readPackageVersionForIosReport, sanitizeIosReportText, writeAbsoluteIosPartnerReport, createAbsoluteIosPartnerReport = (options) => {
|
|
18629
|
-
const {
|
|
18706
|
+
const { targetId, targetKind, ...run } = options.run;
|
|
18707
|
+
const physicalResults = targetKind === "device" && run.deviceAcceptance ? {
|
|
18708
|
+
"DEVICEDEV-01": {
|
|
18709
|
+
details: "AbsoluteJS selected a physical target from the running development session without using Simulator.",
|
|
18710
|
+
id: "DEVICEDEV-01",
|
|
18711
|
+
result: "PASS"
|
|
18712
|
+
}
|
|
18713
|
+
} : undefined;
|
|
18630
18714
|
return createAbsoluteNativeTestReport({
|
|
18631
18715
|
...options.generatedAt ? { generatedAt: options.generatedAt } : {},
|
|
18632
18716
|
manualChecks: MANUAL_CHECKS,
|
|
18717
|
+
...physicalResults ? { manualCheckResults: physicalResults } : {},
|
|
18633
18718
|
metadata: {
|
|
18634
18719
|
absolutejsVersion: options.absolutejsVersion,
|
|
18635
18720
|
bunVersion: options.bunVersion,
|
|
@@ -18640,8 +18725,8 @@ var MANUAL_CHECKS, readPackageVersionForIosReport, sanitizeIosReportText, writeA
|
|
|
18640
18725
|
run: {
|
|
18641
18726
|
...run,
|
|
18642
18727
|
platform: "ios",
|
|
18643
|
-
targetId
|
|
18644
|
-
targetKind
|
|
18728
|
+
targetId,
|
|
18729
|
+
targetKind
|
|
18645
18730
|
}
|
|
18646
18731
|
});
|
|
18647
18732
|
};
|
|
@@ -18658,6 +18743,10 @@ var init_iosTestReport = __esm(() => {
|
|
|
18658
18743
|
["SETUP-05", "Confirm generated iOS project signing and Xcode warnings."],
|
|
18659
18744
|
["DEV-01", "Record cold and warm bun dev startup timings."],
|
|
18660
18745
|
["DEV-02", "Complete route traversal, HMR, relaunch, and recovery checks."],
|
|
18746
|
+
...Array.from({ length: 10 }, (_, index) => [
|
|
18747
|
+
`DEVICEDEV-${String(index + 1).padStart(2, "0")}`,
|
|
18748
|
+
`Complete physical-device development runbook check DEVICEDEV-${String(index + 1).padStart(2, "0")}.`
|
|
18749
|
+
]),
|
|
18661
18750
|
["CAP-01", "Complete automatic device-capability provisioning checks."],
|
|
18662
18751
|
...Array.from({ length: 8 }, (_, index) => [
|
|
18663
18752
|
`SYSUI-${String(index + 1).padStart(2, "0")}`,
|
|
@@ -19835,7 +19924,7 @@ Emulator setup verification:`);
|
|
|
19835
19924
|
if (!instance?.logFile)
|
|
19836
19925
|
throw new TypeError("The selected dev server has no session log. Run `bun dev` normally before requesting --wait-for-hmr.");
|
|
19837
19926
|
if (!args.includes("--json"))
|
|
19838
|
-
console.log("iOS
|
|
19927
|
+
console.log("iOS app is ready. Save a source edit now; waiting for a native HMR acknowledgement\u2026");
|
|
19839
19928
|
return waitForAbsoluteIosHmrLog({
|
|
19840
19929
|
logPath: instance.logFile,
|
|
19841
19930
|
timeoutMs
|
|
@@ -19845,7 +19934,7 @@ Emulator setup verification:`);
|
|
|
19845
19934
|
console.log(JSON.stringify(report, null, 2));
|
|
19846
19935
|
return;
|
|
19847
19936
|
}
|
|
19848
|
-
console.log(`\u2713 iOS simulator ${report.
|
|
19937
|
+
console.log(report.target === "device" ? `\u2713 Physical iOS app ${report.appId} relaunched and reconnected to HMR; no device identifier or screenshot was recorded.` : `\u2713 iOS simulator ${report.targetId}: ${report.appId} launched; screenshot ${report.screenshot}.`);
|
|
19849
19938
|
if (!report.hmrApply)
|
|
19850
19939
|
return;
|
|
19851
19940
|
const timing = report.hmrApply.serverMs === undefined ? "" : ` (server ${report.hmrApply.serverMs}ms, client ${report.hmrApply.clientMs}ms)`;
|
|
@@ -19856,6 +19945,41 @@ Emulator setup verification:`);
|
|
|
19856
19945
|
if (!xcrun)
|
|
19857
19946
|
throw new TypeError("iOS simulator tools are unavailable. Run this command on macOS after `absolute mobile doctor ios --fix`.");
|
|
19858
19947
|
return xcrun;
|
|
19948
|
+
}, runningIosDevice = (instance) => {
|
|
19949
|
+
if (!instance)
|
|
19950
|
+
return;
|
|
19951
|
+
const index = instance.command.indexOf("--ios-device");
|
|
19952
|
+
return index === NOT_FOUND3 ? undefined : instance.command[index + 1];
|
|
19953
|
+
}, physicalIosCapture = async (options) => {
|
|
19954
|
+
const remoteName = valueAfter(options.args, "--remote");
|
|
19955
|
+
if (remoteName && options.instance.iosRemoteMac && remoteName !== options.instance.iosRemoteMac)
|
|
19956
|
+
throw new TypeError("--remote must match the Remote Mac used by the running bun dev session.");
|
|
19957
|
+
const selectedRemoteName = remoteName ?? options.instance.iosRemoteMac;
|
|
19958
|
+
const remote = process.platform === "darwin" && !selectedRemoteName ? undefined : await getAbsoluteRemoteMacProfile(selectedRemoteName);
|
|
19959
|
+
if (process.platform !== "darwin" && !remote)
|
|
19960
|
+
throw new TypeError("Physical iOS acceptance requires macOS or a paired Remote Mac.");
|
|
19961
|
+
if (remote) {
|
|
19962
|
+
const macos = await captureAbsoluteRemoteMacCommand(remote, [
|
|
19963
|
+
"/usr/bin/sw_vers",
|
|
19964
|
+
"-productVersion"
|
|
19965
|
+
]);
|
|
19966
|
+
if (macos.exitCode !== 0)
|
|
19967
|
+
throw new Error("Remote Mac version inspection failed.");
|
|
19968
|
+
return {
|
|
19969
|
+
macosVersion: macos.stdout.trim(),
|
|
19970
|
+
remote: true,
|
|
19971
|
+
xcodeVersion: remote.xcodeVersion,
|
|
19972
|
+
xcrun: "/usr/bin/xcrun",
|
|
19973
|
+
capture: (command) => captureAbsoluteRemoteMacCommand(remote, command)
|
|
19974
|
+
};
|
|
19975
|
+
}
|
|
19976
|
+
return {
|
|
19977
|
+
macosVersion: requireCapturedCommand(["/usr/bin/sw_vers", "-productVersion"], "macOS version inspection").stdout.trim(),
|
|
19978
|
+
remote: false,
|
|
19979
|
+
xcodeVersion: requireCapturedCommand(["/usr/bin/xcodebuild", "-version"], "Xcode version inspection").stdout.trim(),
|
|
19980
|
+
xcrun: "/usr/bin/xcrun",
|
|
19981
|
+
capture: async (command) => captureCommand4(command)
|
|
19982
|
+
};
|
|
19859
19983
|
}, selectIosSimulator = (xcrun, explicitUdid) => {
|
|
19860
19984
|
const result = captureCommand4([
|
|
19861
19985
|
xcrun,
|
|
@@ -19961,12 +20085,124 @@ Emulator setup verification:`);
|
|
|
19961
20085
|
const reportRoot = nativeReportRoot(options.args, options.projectRoot, "ios");
|
|
19962
20086
|
if (!reportRoot)
|
|
19963
20087
|
return;
|
|
19964
|
-
const metadata = await iosReportMetadata(options.xcrun);
|
|
20088
|
+
const metadata = options.metadata ?? (options.xcrun ? await iosReportMetadata(options.xcrun) : undefined);
|
|
20089
|
+
if (!metadata)
|
|
20090
|
+
throw new Error("iOS report metadata could not be inspected.");
|
|
19965
20091
|
const paths = await writeAbsoluteIosPartnerReport(reportRoot, createAbsoluteIosPartnerReport({ ...metadata, run: options.run }));
|
|
19966
20092
|
const print = options.args.includes("--json") ? console.error : console.log;
|
|
19967
20093
|
print(`iOS partner report: ${paths.markdownPath}`);
|
|
19968
20094
|
print(`Return this report directory: ${paths.directory}`);
|
|
19969
20095
|
return paths;
|
|
20096
|
+
}, testPhysicalIos = async (options) => {
|
|
20097
|
+
const {
|
|
20098
|
+
args,
|
|
20099
|
+
device,
|
|
20100
|
+
https,
|
|
20101
|
+
instance,
|
|
20102
|
+
mobile,
|
|
20103
|
+
port,
|
|
20104
|
+
projectRoot,
|
|
20105
|
+
timeoutMs
|
|
20106
|
+
} = options;
|
|
20107
|
+
const transport = await physicalIosCapture({ args, instance });
|
|
20108
|
+
const reportRoot = nativeReportRoot(args, projectRoot, "ios");
|
|
20109
|
+
const startedAt = performance.now();
|
|
20110
|
+
try {
|
|
20111
|
+
const acceptance = await testAbsoluteIosPhysicalDevice({
|
|
20112
|
+
appId: mobile.appId,
|
|
20113
|
+
capture: transport.capture,
|
|
20114
|
+
device,
|
|
20115
|
+
xcrun: transport.xcrun,
|
|
20116
|
+
waitForHmr: () => waitForIosHmrClient({ https, port, timeoutMs })
|
|
20117
|
+
});
|
|
20118
|
+
const hmrApply = await waitForRequestedIosHmr(args, instance, timeoutMs);
|
|
20119
|
+
const report = {
|
|
20120
|
+
appId: mobile.appId,
|
|
20121
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
20122
|
+
...hmrApply ? { hmrApply } : {},
|
|
20123
|
+
hmrConnected: true,
|
|
20124
|
+
platform: "ios",
|
|
20125
|
+
port,
|
|
20126
|
+
provider: "capacitor",
|
|
20127
|
+
status: "pass",
|
|
20128
|
+
target: "device",
|
|
20129
|
+
targetId: "physical-device"
|
|
20130
|
+
};
|
|
20131
|
+
sendTelemetryEvent("mobile:ios-device-conformance", {
|
|
20132
|
+
durationMs: report.durationMs,
|
|
20133
|
+
platform: report.platform,
|
|
20134
|
+
provider: report.provider,
|
|
20135
|
+
remote: transport.remote,
|
|
20136
|
+
success: true,
|
|
20137
|
+
waitedForHmr: args.includes("--wait-for-hmr")
|
|
20138
|
+
});
|
|
20139
|
+
printIosTestReport(report, args.includes("--json"));
|
|
20140
|
+
await writeRequestedIosReport({
|
|
20141
|
+
args,
|
|
20142
|
+
metadata: {
|
|
20143
|
+
absolutejsVersion: await absolutejsVersionForReport(),
|
|
20144
|
+
bunVersion: Bun.version,
|
|
20145
|
+
macosVersion: transport.macosVersion,
|
|
20146
|
+
xcodeVersion: transport.xcodeVersion
|
|
20147
|
+
},
|
|
20148
|
+
projectRoot,
|
|
20149
|
+
run: {
|
|
20150
|
+
appId: report.appId,
|
|
20151
|
+
deviceAcceptance: {
|
|
20152
|
+
https: true,
|
|
20153
|
+
relaunchMs: acceptance.relaunchMs,
|
|
20154
|
+
remote: transport.remote
|
|
20155
|
+
},
|
|
20156
|
+
durationMs: report.durationMs,
|
|
20157
|
+
...hmrApply ? {
|
|
20158
|
+
hmr: {
|
|
20159
|
+
durationMs: hmrApply.duration,
|
|
20160
|
+
outcome: hmrApply.outcome,
|
|
20161
|
+
...hmrApply.clientMs === undefined ? {} : { clientMs: hmrApply.clientMs },
|
|
20162
|
+
...hmrApply.serverMs === undefined ? {} : { serverMs: hmrApply.serverMs }
|
|
20163
|
+
}
|
|
20164
|
+
} : {},
|
|
20165
|
+
hmrConnected: true,
|
|
20166
|
+
port,
|
|
20167
|
+
status: "pass",
|
|
20168
|
+
targetId: "physical-device",
|
|
20169
|
+
targetKind: "device"
|
|
20170
|
+
}
|
|
20171
|
+
});
|
|
20172
|
+
return report;
|
|
20173
|
+
} catch (error) {
|
|
20174
|
+
const durationMs = Math.round(performance.now() - startedAt);
|
|
20175
|
+
sendTelemetryEvent("mobile:ios-device-conformance", {
|
|
20176
|
+
durationMs,
|
|
20177
|
+
platform: "ios",
|
|
20178
|
+
provider: "capacitor",
|
|
20179
|
+
remote: transport.remote,
|
|
20180
|
+
success: false,
|
|
20181
|
+
waitedForHmr: args.includes("--wait-for-hmr")
|
|
20182
|
+
});
|
|
20183
|
+
if (reportRoot)
|
|
20184
|
+
await writeRequestedIosReport({
|
|
20185
|
+
args,
|
|
20186
|
+
metadata: {
|
|
20187
|
+
absolutejsVersion: await absolutejsVersionForReport(),
|
|
20188
|
+
bunVersion: Bun.version,
|
|
20189
|
+
macosVersion: transport.macosVersion,
|
|
20190
|
+
xcodeVersion: transport.xcodeVersion
|
|
20191
|
+
},
|
|
20192
|
+
projectRoot,
|
|
20193
|
+
run: {
|
|
20194
|
+
appId: mobile.appId,
|
|
20195
|
+
durationMs,
|
|
20196
|
+
error: sanitizeIosReportText(error instanceof Error ? error.message : String(error)),
|
|
20197
|
+
hmrConnected: false,
|
|
20198
|
+
port,
|
|
20199
|
+
status: "fail",
|
|
20200
|
+
targetId: "physical-device",
|
|
20201
|
+
targetKind: "device"
|
|
20202
|
+
}
|
|
20203
|
+
});
|
|
20204
|
+
throw error;
|
|
20205
|
+
}
|
|
19970
20206
|
}, testIos = async (args) => {
|
|
19971
20207
|
const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
|
|
19972
20208
|
const { https, instance, port } = requireIosTestContext(args, projectRoot);
|
|
@@ -19975,6 +20211,35 @@ Emulator setup verification:`);
|
|
|
19975
20211
|
if (args.includes("--route"))
|
|
19976
20212
|
throw new TypeError("iOS simulator route selection is not exposed through simctl; configure mobile.entry for the native route matrix.");
|
|
19977
20213
|
const timeoutMs = androidTestTimeout(args);
|
|
20214
|
+
const requestedDevice = valueAfter(args, "--device");
|
|
20215
|
+
if (args.includes("--device") && !requestedDevice)
|
|
20216
|
+
throw new TypeError("mobile test ios --device requires a device identifier or name.");
|
|
20217
|
+
if (requestedDevice && (valueAfter(args, "--udid") || valueAfter(args, "--serial")))
|
|
20218
|
+
throw new TypeError("mobile test ios --device cannot be combined with a simulator selector.");
|
|
20219
|
+
if (!requestedDevice && args.includes("--remote"))
|
|
20220
|
+
throw new TypeError("mobile test ios --remote is available only with --device.");
|
|
20221
|
+
if (requestedDevice) {
|
|
20222
|
+
const device = normalizeAbsoluteIosDeviceIdentifier(requestedDevice);
|
|
20223
|
+
const activeDevice = runningIosDevice(instance);
|
|
20224
|
+
if (!activeDevice)
|
|
20225
|
+
throw new TypeError("The selected dev server is not running a physical iOS session. Start bun dev with --ios-device first.");
|
|
20226
|
+
if (activeDevice !== device)
|
|
20227
|
+
throw new TypeError("--device must match the --ios-device value used by the running bun dev session.");
|
|
20228
|
+
if (!https)
|
|
20229
|
+
throw new TypeError("Physical iOS acceptance requires dev.https: true so the report can prove the native trust path.");
|
|
20230
|
+
if (!instance)
|
|
20231
|
+
throw new TypeError("Physical iOS acceptance requires a registered bun dev session.");
|
|
20232
|
+
return testPhysicalIos({
|
|
20233
|
+
args,
|
|
20234
|
+
device,
|
|
20235
|
+
https,
|
|
20236
|
+
instance,
|
|
20237
|
+
mobile,
|
|
20238
|
+
port,
|
|
20239
|
+
projectRoot,
|
|
20240
|
+
timeoutMs
|
|
20241
|
+
});
|
|
20242
|
+
}
|
|
19978
20243
|
const xcrun = await requireIosXcrun();
|
|
19979
20244
|
const simulator = selectIosSimulator(xcrun, valueAfter(args, "--udid") ?? valueAfter(args, "--serial"));
|
|
19980
20245
|
const reportRoot = nativeReportRoot(args, projectRoot, "ios");
|
|
@@ -20012,7 +20277,8 @@ Emulator setup verification:`);
|
|
|
20012
20277
|
provider: "capacitor",
|
|
20013
20278
|
screenshot,
|
|
20014
20279
|
status: "pass",
|
|
20015
|
-
|
|
20280
|
+
target: "simulator",
|
|
20281
|
+
targetId: simulator.udid
|
|
20016
20282
|
};
|
|
20017
20283
|
sendTelemetryEvent("mobile:ios-conformance", {
|
|
20018
20284
|
durationMs: report.durationMs,
|
|
@@ -20040,7 +20306,8 @@ Emulator setup verification:`);
|
|
|
20040
20306
|
port: report.port,
|
|
20041
20307
|
screenshot: report.screenshot,
|
|
20042
20308
|
status: report.status,
|
|
20043
|
-
|
|
20309
|
+
targetId: report.targetId,
|
|
20310
|
+
targetKind: report.target
|
|
20044
20311
|
},
|
|
20045
20312
|
xcrun
|
|
20046
20313
|
});
|
|
@@ -20073,7 +20340,8 @@ Emulator setup verification:`);
|
|
|
20073
20340
|
port,
|
|
20074
20341
|
...screenshot ? { screenshot } : {},
|
|
20075
20342
|
status: "fail",
|
|
20076
|
-
|
|
20343
|
+
targetId: simulator.udid,
|
|
20344
|
+
targetKind: "simulator"
|
|
20077
20345
|
},
|
|
20078
20346
|
xcrun
|
|
20079
20347
|
});
|
|
@@ -20133,7 +20401,7 @@ Emulator setup verification:`);
|
|
|
20133
20401
|
await publishIos(args.slice(2));
|
|
20134
20402
|
return;
|
|
20135
20403
|
}
|
|
20136
|
-
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--
|
|
20404
|
+
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
20137
20405
|
};
|
|
20138
20406
|
var init_mobile = __esm(() => {
|
|
20139
20407
|
init_dependencies();
|
|
@@ -20154,6 +20422,7 @@ var init_mobile = __esm(() => {
|
|
|
20154
20422
|
init_androidRelease();
|
|
20155
20423
|
init_iosRelease();
|
|
20156
20424
|
init_iosSimulatorController();
|
|
20425
|
+
init_iosPhysicalDeviceTransport();
|
|
20157
20426
|
init_iosConformance();
|
|
20158
20427
|
init_iosTestReport();
|
|
20159
20428
|
init_androidTestReport();
|
|
@@ -21683,6 +21952,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
21683
21952
|
frameworks: [],
|
|
21684
21953
|
host: resolvedDev.host,
|
|
21685
21954
|
https: httpsEnabled,
|
|
21955
|
+
...selectedRemoteMacProfile ? { iosRemoteMac: selectedRemoteMacProfile.name } : {},
|
|
21686
21956
|
logFile: instanceLogFile,
|
|
21687
21957
|
name: resolveProjectName(process.cwd()),
|
|
21688
21958
|
pid: instancePid,
|