@absolutejs/absolute 0.20.0-beta.33 → 0.20.0-beta.35
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 +762 -158
- package/dist/index.js +33 -10
- package/dist/index.js.map +8 -8
- package/dist/mobile/index.js +483 -93
- package/dist/mobile/index.js.map +8 -6
- package/dist/mobile/remoteMacAgentEntry.js +14 -14
- package/dist/src/cli/instanceStatus.d.ts +1 -0
- package/dist/src/cli/scripts/dev.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 +2 -0
- package/dist/src/mobile/iosDeviceAcceptance.d.ts +32 -0
- package/dist/src/mobile/iosPhysicalDeviceTransport.d.ts +16 -0
- package/dist/src/mobile/iosSimulatorController.d.ts +12 -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 +10 -0
- package/dist/src/plugins/hmr.d.ts +3 -0
- package/dist/types/cli.d.ts +1 -0
- package/package.json +1 -1
package/dist/mobile/index.js
CHANGED
|
@@ -2580,17 +2580,134 @@ var waitForAbsoluteIosHmrLog = async (options) => {
|
|
|
2580
2580
|
return poll();
|
|
2581
2581
|
};
|
|
2582
2582
|
// src/mobile/iosSimulatorController.ts
|
|
2583
|
-
import { createHash as createHash6, randomUUID as
|
|
2583
|
+
import { createHash as createHash6, randomUUID as randomUUID3 } from "crypto";
|
|
2584
2584
|
import {
|
|
2585
2585
|
access as access6,
|
|
2586
2586
|
copyFile as copyFile4,
|
|
2587
2587
|
mkdir as mkdir5,
|
|
2588
|
-
readFile as
|
|
2588
|
+
readFile as readFile8,
|
|
2589
2589
|
rename as rename6,
|
|
2590
2590
|
rm as rm5,
|
|
2591
2591
|
writeFile as writeFile6
|
|
2592
2592
|
} from "fs/promises";
|
|
2593
|
+
import { isIP as isIP2 } from "net";
|
|
2593
2594
|
import { dirname as dirname4, isAbsolute as isAbsolute4, join as join6, relative as relative5, resolve as resolve5, sep as sep4 } from "path";
|
|
2595
|
+
|
|
2596
|
+
// src/mobile/iosPhysicalDeviceTransport.ts
|
|
2597
|
+
import { randomUUID as randomUUID2, X509Certificate } from "crypto";
|
|
2598
|
+
import { createServer } from "http";
|
|
2599
|
+
import {
|
|
2600
|
+
connect as connectTcp,
|
|
2601
|
+
createServer as createTcpServer,
|
|
2602
|
+
isIP
|
|
2603
|
+
} from "net";
|
|
2604
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
2605
|
+
var closeServer = (server) => new Promise((resolve5, reject) => {
|
|
2606
|
+
server.close((error) => {
|
|
2607
|
+
if (error)
|
|
2608
|
+
reject(error);
|
|
2609
|
+
else
|
|
2610
|
+
resolve5();
|
|
2611
|
+
});
|
|
2612
|
+
});
|
|
2613
|
+
var listen = (server, port) => new Promise((resolve5, reject) => {
|
|
2614
|
+
server.once("error", reject);
|
|
2615
|
+
server.listen(port, "0.0.0.0", () => {
|
|
2616
|
+
server.off("error", reject);
|
|
2617
|
+
const address = server.address();
|
|
2618
|
+
if (!address || typeof address === "string") {
|
|
2619
|
+
reject(new Error("Could not determine the iOS device helper port."));
|
|
2620
|
+
return;
|
|
2621
|
+
}
|
|
2622
|
+
resolve5(address.port);
|
|
2623
|
+
});
|
|
2624
|
+
});
|
|
2625
|
+
var findEphemeralPort = async () => {
|
|
2626
|
+
const probe = createTcpServer();
|
|
2627
|
+
const port = await new Promise((resolve5, reject) => {
|
|
2628
|
+
probe.once("error", reject);
|
|
2629
|
+
probe.listen(0, "127.0.0.1", () => {
|
|
2630
|
+
const address = probe.address();
|
|
2631
|
+
if (!address || typeof address === "string") {
|
|
2632
|
+
reject(new Error("Could not allocate the iOS CA enrollment port."));
|
|
2633
|
+
return;
|
|
2634
|
+
}
|
|
2635
|
+
resolve5(address.port);
|
|
2636
|
+
});
|
|
2637
|
+
});
|
|
2638
|
+
await closeServer(probe);
|
|
2639
|
+
return port;
|
|
2640
|
+
};
|
|
2641
|
+
var normalizeAbsoluteIosDeviceHost = (value) => {
|
|
2642
|
+
const normalized = value.trim();
|
|
2643
|
+
if (!normalized || normalized.length > 253 || /[\0\s/?#]/u.test(normalized))
|
|
2644
|
+
throw new TypeError("Physical iOS development requires a valid LAN host.");
|
|
2645
|
+
return normalized;
|
|
2646
|
+
};
|
|
2647
|
+
var normalizeAbsoluteIosDeviceIdentifier = (value) => {
|
|
2648
|
+
const normalized = value.trim();
|
|
2649
|
+
if (!normalized || normalized.length > 256 || /[\0\r\n]/u.test(normalized))
|
|
2650
|
+
throw new TypeError("--ios-device requires a valid Xcode device identifier or name.");
|
|
2651
|
+
return normalized;
|
|
2652
|
+
};
|
|
2653
|
+
var urlForHost = (protocol, host, port) => {
|
|
2654
|
+
const url = new URL(`${protocol}://localhost:${port}`);
|
|
2655
|
+
const normalizedHost = normalizeAbsoluteIosDeviceHost(host);
|
|
2656
|
+
url.hostname = isIP(normalizedHost) === 6 ? `[${normalizedHost}]` : normalizedHost;
|
|
2657
|
+
return url;
|
|
2658
|
+
};
|
|
2659
|
+
var startAbsoluteIosCaEnrollmentServer = async (options) => {
|
|
2660
|
+
const certificate = new X509Certificate(await readFile7(options.certificateAuthorityPath));
|
|
2661
|
+
const certificateBytes = certificate.raw;
|
|
2662
|
+
const token = randomUUID2().replaceAll("-", "");
|
|
2663
|
+
const certificatePath = `/${token}/absolutejs-development-ca.cer`;
|
|
2664
|
+
const server = createServer((request, response) => {
|
|
2665
|
+
if (request.method !== "GET" || request.url !== certificatePath) {
|
|
2666
|
+
response.writeHead(404, {
|
|
2667
|
+
"Cache-Control": "no-store",
|
|
2668
|
+
"Content-Type": "text/plain; charset=utf-8"
|
|
2669
|
+
});
|
|
2670
|
+
response.end("Not found.");
|
|
2671
|
+
return;
|
|
2672
|
+
}
|
|
2673
|
+
response.writeHead(200, {
|
|
2674
|
+
"Cache-Control": "no-store",
|
|
2675
|
+
"Content-Disposition": 'attachment; filename="absolutejs-development-ca.cer"',
|
|
2676
|
+
"Content-Length": String(certificateBytes.byteLength),
|
|
2677
|
+
"Content-Type": "application/x-x509-ca-cert",
|
|
2678
|
+
"X-Content-Type-Options": "nosniff"
|
|
2679
|
+
});
|
|
2680
|
+
response.end(certificateBytes);
|
|
2681
|
+
});
|
|
2682
|
+
const port = await findEphemeralPort();
|
|
2683
|
+
await listen(server, port);
|
|
2684
|
+
const url = urlForHost("http", options.displayHost, port);
|
|
2685
|
+
url.pathname = certificatePath;
|
|
2686
|
+
return {
|
|
2687
|
+
url: url.href,
|
|
2688
|
+
close: () => closeServer(server)
|
|
2689
|
+
};
|
|
2690
|
+
};
|
|
2691
|
+
var startAbsoluteIosTcpRelay = async (options) => {
|
|
2692
|
+
const server = createTcpServer((downstream) => {
|
|
2693
|
+
const upstream = connectTcp({
|
|
2694
|
+
host: "127.0.0.1",
|
|
2695
|
+
port: options.targetPort
|
|
2696
|
+
});
|
|
2697
|
+
downstream.pipe(upstream);
|
|
2698
|
+
upstream.pipe(downstream);
|
|
2699
|
+
const closePeer = () => {
|
|
2700
|
+
downstream.destroy();
|
|
2701
|
+
upstream.destroy();
|
|
2702
|
+
};
|
|
2703
|
+
downstream.once("error", closePeer);
|
|
2704
|
+
upstream.once("error", closePeer);
|
|
2705
|
+
});
|
|
2706
|
+
await listen(server, options.listenPort);
|
|
2707
|
+
return { close: () => closeServer(server) };
|
|
2708
|
+
};
|
|
2709
|
+
|
|
2710
|
+
// src/mobile/iosSimulatorController.ts
|
|
2594
2711
|
init_getDurationString();
|
|
2595
2712
|
var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone";
|
|
2596
2713
|
var BOOT_TIMEOUT_MS = 180000;
|
|
@@ -2716,6 +2833,24 @@ var trustIosSimulatorDevelopmentCa = async (options, udid, run, log) => {
|
|
|
2716
2833
|
], "iOS Simulator development CA trust", run, { signal: options.signal });
|
|
2717
2834
|
log("Installed the AbsoluteJS development CA into this iOS Simulator trust store.");
|
|
2718
2835
|
};
|
|
2836
|
+
var iosLaunchCommand = (project, udid, physical) => physical ? [
|
|
2837
|
+
project.xcrun,
|
|
2838
|
+
"devicectl",
|
|
2839
|
+
"device",
|
|
2840
|
+
"process",
|
|
2841
|
+
"launch",
|
|
2842
|
+
"--terminate-existing",
|
|
2843
|
+
"--device",
|
|
2844
|
+
udid,
|
|
2845
|
+
project.config.appId
|
|
2846
|
+
] : [
|
|
2847
|
+
project.xcrun,
|
|
2848
|
+
"simctl",
|
|
2849
|
+
"launch",
|
|
2850
|
+
"--terminate-running-process",
|
|
2851
|
+
udid,
|
|
2852
|
+
project.config.appId
|
|
2853
|
+
];
|
|
2719
2854
|
var requireCapturedSuccess = (result, label) => {
|
|
2720
2855
|
if (result.exitCode !== 0) {
|
|
2721
2856
|
throw new Error(`${label} failed: ${result.stderr.trim() || result.stdout.trim() || `status ${result.exitCode}`}`);
|
|
@@ -2853,7 +2988,7 @@ var repairAbsoluteIosDevSession = async (projectRoot) => {
|
|
|
2853
2988
|
await rm5(paths.root, { force: true, recursive: true });
|
|
2854
2989
|
return false;
|
|
2855
2990
|
}
|
|
2856
|
-
const journal = await
|
|
2991
|
+
const journal = await readFile8(paths.journal, "utf8").then((source) => parseJournal(JSON.parse(source))).catch(() => null);
|
|
2857
2992
|
if (!journal || !isInside(projectRoot, journal.nativeConfigPath) || !isInside(projectRoot, journal.infoPath) || !isInside(paths.root, journal.configBackupPath) || !isInside(paths.root, journal.infoBackupPath)) {
|
|
2858
2993
|
throw new Error(`Refusing unsafe or invalid iOS dev journal at ${paths.journal}.`);
|
|
2859
2994
|
}
|
|
@@ -2884,14 +3019,14 @@ var iosDevelopmentInfoPlist = (source, cleartext) => {
|
|
|
2884
3019
|
<true/>
|
|
2885
3020
|
</dict>`);
|
|
2886
3021
|
};
|
|
2887
|
-
var writeDevProjection = async (project, port, https) => {
|
|
3022
|
+
var writeDevProjection = async (project, port, https, serverHost = "localhost") => {
|
|
2888
3023
|
const paths = journalPaths(project.projectRoot);
|
|
2889
3024
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
2890
3025
|
const nativeConfigPath = join6(project.nativeDirectory, "App", "App", "capacitor.config.json");
|
|
2891
3026
|
const infoPath = join6(project.nativeDirectory, "App", "App", "Info.plist");
|
|
2892
3027
|
const [configSource, infoSource] = await Promise.all([
|
|
2893
|
-
|
|
2894
|
-
|
|
3028
|
+
readFile8(nativeConfigPath, "utf8"),
|
|
3029
|
+
readFile8(infoPath, "utf8")
|
|
2895
3030
|
]);
|
|
2896
3031
|
const parsed = JSON.parse(configSource);
|
|
2897
3032
|
if (!isRecord3(parsed))
|
|
@@ -2913,6 +3048,7 @@ var writeDevProjection = async (project, port, https) => {
|
|
|
2913
3048
|
flag: "wx"
|
|
2914
3049
|
});
|
|
2915
3050
|
const developmentUrl = new URL(`${https ? "https" : "http"}://localhost:${port}${project.config.entry}`);
|
|
3051
|
+
developmentUrl.hostname = isIP2(serverHost) === 6 ? `[${serverHost}]` : serverHost;
|
|
2916
3052
|
developmentUrl.searchParams.set("__absolute_target", "capacitor-ios");
|
|
2917
3053
|
const existingServer = parsed.server;
|
|
2918
3054
|
parsed.server = {
|
|
@@ -2942,10 +3078,10 @@ var parseNativeCache = (value) => {
|
|
|
2942
3078
|
]))
|
|
2943
3079
|
};
|
|
2944
3080
|
};
|
|
2945
|
-
var readNativeCache = (projectRoot) =>
|
|
3081
|
+
var readNativeCache = (projectRoot) => readFile8(nativeCachePath(projectRoot), "utf8").then((source) => parseNativeCache(JSON.parse(source))).catch(() => null);
|
|
2946
3082
|
var writeNativeCache = async (projectRoot, cache) => {
|
|
2947
3083
|
const destination = nativeCachePath(projectRoot);
|
|
2948
|
-
const temporary = `${destination}.${process.pid}.${
|
|
3084
|
+
const temporary = `${destination}.${process.pid}.${randomUUID3()}.tmp`;
|
|
2949
3085
|
await mkdir5(dirname4(destination), { recursive: true });
|
|
2950
3086
|
try {
|
|
2951
3087
|
await writeFile6(temporary, `${JSON.stringify(cache, null, "\t")}
|
|
@@ -3034,6 +3170,31 @@ var installedAppIdentity = (project, udid, capture) => {
|
|
|
3034
3170
|
]);
|
|
3035
3171
|
return result.exitCode === 0 && result.stdout.trim() ? result.stdout.trim() : undefined;
|
|
3036
3172
|
};
|
|
3173
|
+
var validatePhysicalIosDevice = (project, identifier, capture) => {
|
|
3174
|
+
const result = capture([
|
|
3175
|
+
project.xcrun,
|
|
3176
|
+
"devicectl",
|
|
3177
|
+
"device",
|
|
3178
|
+
"info",
|
|
3179
|
+
"details",
|
|
3180
|
+
"--device",
|
|
3181
|
+
identifier
|
|
3182
|
+
]);
|
|
3183
|
+
if (result.exitCode !== 0)
|
|
3184
|
+
throw new Error(`Physical iOS device ${JSON.stringify(identifier)} is unavailable: ${result.stderr.trim() || result.stdout.trim() || "pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode."}`);
|
|
3185
|
+
};
|
|
3186
|
+
var physicalIosAppIsInstalled = (project, identifier, capture) => {
|
|
3187
|
+
const result = capture([
|
|
3188
|
+
project.xcrun,
|
|
3189
|
+
"devicectl",
|
|
3190
|
+
"device",
|
|
3191
|
+
"info",
|
|
3192
|
+
"apps",
|
|
3193
|
+
"--device",
|
|
3194
|
+
identifier
|
|
3195
|
+
]);
|
|
3196
|
+
return result.exitCode === 0 && result.stdout.includes(project.config.appId);
|
|
3197
|
+
};
|
|
3037
3198
|
var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
3038
3199
|
const derivedDataPath = join6(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash6("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
3039
3200
|
await mkdir5(derivedDataPath, { recursive: true });
|
|
@@ -3056,6 +3217,61 @@ var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
|
3056
3217
|
throw new Error(`Xcode did not produce the simulator app at ${appPath}.`);
|
|
3057
3218
|
return appPath;
|
|
3058
3219
|
};
|
|
3220
|
+
var buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
|
|
3221
|
+
const derivedDataPath = join6(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash6("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
3222
|
+
await mkdir5(derivedDataPath, { recursive: true });
|
|
3223
|
+
await requireSuccess2([
|
|
3224
|
+
project.xcodebuild,
|
|
3225
|
+
"-workspace",
|
|
3226
|
+
join6(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
3227
|
+
"-scheme",
|
|
3228
|
+
"App",
|
|
3229
|
+
"-configuration",
|
|
3230
|
+
"Debug",
|
|
3231
|
+
"-destination",
|
|
3232
|
+
`platform=iOS,id=${identifier}`,
|
|
3233
|
+
"-derivedDataPath",
|
|
3234
|
+
derivedDataPath,
|
|
3235
|
+
"-allowProvisioningUpdates",
|
|
3236
|
+
"build"
|
|
3237
|
+
], "iOS physical-device build (configure automatic signing and a Development Team in Xcode if this is the first run)", run, { cwd: project.nativeDirectory, signal });
|
|
3238
|
+
const appPath = join6(derivedDataPath, "Build", "Products", "Debug-iphoneos", "App.app");
|
|
3239
|
+
if (!await pathExists5(appPath))
|
|
3240
|
+
throw new Error(`Xcode did not produce the physical-device app at ${appPath}.`);
|
|
3241
|
+
return appPath;
|
|
3242
|
+
};
|
|
3243
|
+
var ensurePhysicalIosDebugApp = async (options) => {
|
|
3244
|
+
const cacheHit = options.cache?.appId === options.project.config.appId && options.cache.fingerprint === options.fingerprint && options.cache.installations[options.identifier] === options.fingerprint && physicalIosAppIsInstalled(options.project, options.identifier, options.capture);
|
|
3245
|
+
if (cacheHit) {
|
|
3246
|
+
options.log(`iOS native app is unchanged on the selected physical device; skipped Xcode build and install.`);
|
|
3247
|
+
return true;
|
|
3248
|
+
}
|
|
3249
|
+
options.log("iOS native inputs changed or the physical-device install is stale; rebuilding.");
|
|
3250
|
+
options.transition("building");
|
|
3251
|
+
const appPath = await buildPhysicalIosDebugApp(options.project, options.identifier, options.run, options.signal);
|
|
3252
|
+
throwIfAborted2(options.signal);
|
|
3253
|
+
options.transition("installing");
|
|
3254
|
+
await requireSuccess2([
|
|
3255
|
+
options.project.xcrun,
|
|
3256
|
+
"devicectl",
|
|
3257
|
+
"device",
|
|
3258
|
+
"install",
|
|
3259
|
+
"app",
|
|
3260
|
+
"--device",
|
|
3261
|
+
options.identifier,
|
|
3262
|
+
appPath
|
|
3263
|
+
], "iOS physical-device app installation", options.run, { signal: options.signal });
|
|
3264
|
+
await writeNativeCache(options.project.projectRoot, {
|
|
3265
|
+
appId: options.project.config.appId,
|
|
3266
|
+
fingerprint: options.fingerprint,
|
|
3267
|
+
format: NATIVE_CACHE_FORMAT,
|
|
3268
|
+
installations: {
|
|
3269
|
+
...options.cache?.appId === options.project.config.appId ? options.cache.installations : {},
|
|
3270
|
+
[options.identifier]: options.fingerprint
|
|
3271
|
+
}
|
|
3272
|
+
}).catch((error) => options.log(`iOS native cache could not be saved: ${error instanceof Error ? error.message : String(error)}`));
|
|
3273
|
+
return false;
|
|
3274
|
+
};
|
|
3059
3275
|
var ensureIosDebugApp = async (options) => {
|
|
3060
3276
|
const installed = installedAppIdentity(options.project, options.udid, options.capture);
|
|
3061
3277
|
const cacheHit = options.cache?.appId === options.project.config.appId && options.cache.fingerprint === options.fingerprint && installed !== undefined && options.cache.installations[options.udid] === installed;
|
|
@@ -3102,7 +3318,18 @@ var attachNativeLogs = (project, udid, options) => {
|
|
|
3102
3318
|
if (!options.nativeLog)
|
|
3103
3319
|
return null;
|
|
3104
3320
|
const start = options.startNativeLogs ?? defaultStartNativeLogs;
|
|
3105
|
-
|
|
3321
|
+
const command = options.deviceIdentifier ? [
|
|
3322
|
+
project.xcrun,
|
|
3323
|
+
"devicectl",
|
|
3324
|
+
"device",
|
|
3325
|
+
"process",
|
|
3326
|
+
"launch",
|
|
3327
|
+
"--console",
|
|
3328
|
+
"--terminate-existing",
|
|
3329
|
+
"--device",
|
|
3330
|
+
udid,
|
|
3331
|
+
project.config.appId
|
|
3332
|
+
] : [
|
|
3106
3333
|
project.xcrun,
|
|
3107
3334
|
"simctl",
|
|
3108
3335
|
"spawn",
|
|
@@ -3115,7 +3342,8 @@ var attachNativeLogs = (project, udid, options) => {
|
|
|
3115
3342
|
"debug",
|
|
3116
3343
|
"--predicate",
|
|
3117
3344
|
'process == "App"'
|
|
3118
|
-
]
|
|
3345
|
+
];
|
|
3346
|
+
return start(command, { signal: options.signal }, (line) => {
|
|
3119
3347
|
const entry = parseAbsoluteIosLogLine(line);
|
|
3120
3348
|
if (entry)
|
|
3121
3349
|
options.nativeLog?.(entry);
|
|
@@ -3127,6 +3355,7 @@ var IOS_TIMING_PHASES = [
|
|
|
3127
3355
|
["fingerprinting", "fingerprint"],
|
|
3128
3356
|
["booting", "simulator"],
|
|
3129
3357
|
["connecting", "device ready"],
|
|
3358
|
+
["enrolling-trust", "HTTPS trust"],
|
|
3130
3359
|
["checking-native", "app check"],
|
|
3131
3360
|
["building", "Xcode"],
|
|
3132
3361
|
["installing", "install"],
|
|
@@ -3139,12 +3368,13 @@ var timingSummary = (timings) => IOS_TIMING_PHASES.map(([phase, label]) => {
|
|
|
3139
3368
|
}).filter((value) => value !== null).join(", ");
|
|
3140
3369
|
var prepareAbsoluteIosDevProject = async (config, options) => {
|
|
3141
3370
|
if (detectAbsoluteMobileHost() !== "macos")
|
|
3142
|
-
throw new Error("iOS
|
|
3371
|
+
throw new Error("iOS development requires macOS and Xcode.");
|
|
3372
|
+
const target = options.target ?? "simulator";
|
|
3143
3373
|
const projectRoot = resolve5(options.projectRoot);
|
|
3144
3374
|
const checks = await inspectAbsoluteMobileToolchain({ host: "macos" });
|
|
3145
|
-
const failed = checks.filter((check) => check.platform === "ios" && (check.status === "fail" || check.status === "warn"));
|
|
3375
|
+
const failed = checks.filter((check) => check.platform === "ios" && !(target === "device" && check.id === "ios.runtime") && (check.status === "fail" || check.status === "warn"));
|
|
3146
3376
|
if (failed.length > 0)
|
|
3147
|
-
throw new Error(`iOS
|
|
3377
|
+
throw new Error(`iOS ${target} development is not ready: ${failed.map(({ label }) => label).join(", ")}.`);
|
|
3148
3378
|
const xcrun = checks.find((check) => check.id === "ios.xcrun")?.path;
|
|
3149
3379
|
const xcodebuild = checks.find((check) => check.id === "ios.xcodebuild")?.path;
|
|
3150
3380
|
if (!xcrun || !xcodebuild)
|
|
@@ -3175,8 +3405,55 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
|
|
|
3175
3405
|
xcrun
|
|
3176
3406
|
};
|
|
3177
3407
|
};
|
|
3408
|
+
var preparePhysicalIosTarget = async (options) => {
|
|
3409
|
+
options.transition("connecting");
|
|
3410
|
+
validatePhysicalIosDevice(options.project, options.deviceIdentifier, options.capture);
|
|
3411
|
+
if (!options.startOptions.https)
|
|
3412
|
+
return {
|
|
3413
|
+
caEnrollmentServer: null,
|
|
3414
|
+
startedSimulator: false,
|
|
3415
|
+
udid: options.deviceIdentifier
|
|
3416
|
+
};
|
|
3417
|
+
if (!options.startOptions.certificateAuthorityPath)
|
|
3418
|
+
throw new Error("Physical iOS HTTPS development requires the AbsoluteJS development CA certificate.");
|
|
3419
|
+
options.transition("enrolling-trust");
|
|
3420
|
+
const startEnrollment = options.startOptions.startCaEnrollmentServer ?? startAbsoluteIosCaEnrollmentServer;
|
|
3421
|
+
const caEnrollmentServer = await startEnrollment({
|
|
3422
|
+
certificateAuthorityPath: options.startOptions.certificateAuthorityPath,
|
|
3423
|
+
displayHost: options.serverHost
|
|
3424
|
+
});
|
|
3425
|
+
options.log(`On the iOS device, open ${caEnrollmentServer.url}, install the AbsoluteJS development CA profile, then enable it under Settings > General > About > Certificate Trust Settings. This public CA endpoint exists only for this dev session.`);
|
|
3426
|
+
return {
|
|
3427
|
+
caEnrollmentServer,
|
|
3428
|
+
startedSimulator: false,
|
|
3429
|
+
udid: options.deviceIdentifier
|
|
3430
|
+
};
|
|
3431
|
+
};
|
|
3432
|
+
var prepareIosSimulatorTarget = async (options) => {
|
|
3433
|
+
options.transition("booting");
|
|
3434
|
+
const managed = await ensureManagedSimulator(options.project, options.capture);
|
|
3435
|
+
const { device } = managed;
|
|
3436
|
+
const startedSimulator = managed.created || device.state !== "Booted";
|
|
3437
|
+
bootSimulator(options.project, device, options.capture);
|
|
3438
|
+
options.spawn([
|
|
3439
|
+
"open",
|
|
3440
|
+
"-a",
|
|
3441
|
+
"Simulator",
|
|
3442
|
+
"--args",
|
|
3443
|
+
"-CurrentDeviceUDID",
|
|
3444
|
+
device.udid
|
|
3445
|
+
]);
|
|
3446
|
+
options.transition("connecting");
|
|
3447
|
+
await waitForBootedSimulator(options.project, device.udid, options.capture, options.sleep, options.startOptions.signal);
|
|
3448
|
+
await requireSuccess2([options.project.xcrun, "simctl", "bootstatus", device.udid, "-b"], "iOS simulator boot readiness", options.run, { signal: options.startOptions.signal });
|
|
3449
|
+
await trustIosSimulatorDevelopmentCa(options.startOptions, device.udid, options.run, options.log);
|
|
3450
|
+
return { caEnrollmentServer: null, startedSimulator, udid: device.udid };
|
|
3451
|
+
};
|
|
3178
3452
|
var startAbsoluteIosDevSession = async (options) => {
|
|
3179
3453
|
const { project } = options;
|
|
3454
|
+
const deviceIdentifier = options.deviceIdentifier ? normalizeAbsoluteIosDeviceIdentifier(options.deviceIdentifier) : undefined;
|
|
3455
|
+
const targetKind = deviceIdentifier ? "device" : "simulator";
|
|
3456
|
+
const serverHost = deviceIdentifier ? normalizeAbsoluteIosDeviceHost(options.serverHost ?? "") : "localhost";
|
|
3180
3457
|
const capture = options.capture ?? defaultCapture3;
|
|
3181
3458
|
const run = options.run ?? defaultRun2;
|
|
3182
3459
|
const sleep = options.sleep ?? Bun.sleep;
|
|
@@ -3204,6 +3481,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3204
3481
|
options.onStateChange?.(next);
|
|
3205
3482
|
};
|
|
3206
3483
|
let nativeLogs = null;
|
|
3484
|
+
let caEnrollmentServer = null;
|
|
3207
3485
|
const closeLogs = async () => {
|
|
3208
3486
|
const stream = nativeLogs;
|
|
3209
3487
|
nativeLogs = null;
|
|
@@ -3211,39 +3489,66 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3211
3489
|
return;
|
|
3212
3490
|
});
|
|
3213
3491
|
};
|
|
3492
|
+
const relaunchTarget = async (udid) => {
|
|
3493
|
+
if (deviceIdentifier && options.nativeLog) {
|
|
3494
|
+
await closeLogs();
|
|
3495
|
+
nativeLogs = attachNativeLogs(project, udid, options);
|
|
3496
|
+
return;
|
|
3497
|
+
}
|
|
3498
|
+
await requireSuccess2(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app relaunch", run, { signal: options.signal });
|
|
3499
|
+
};
|
|
3214
3500
|
try {
|
|
3215
3501
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
3216
3502
|
throwIfAborted2(options.signal);
|
|
3217
3503
|
transition("syncing");
|
|
3218
3504
|
await requireSuccess2([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
|
|
3219
3505
|
transition("configuring");
|
|
3220
|
-
await writeDevProjection(project, options.port, options.https === true);
|
|
3506
|
+
await writeDevProjection(project, options.port, options.https === true, serverHost);
|
|
3221
3507
|
throwIfAborted2(options.signal);
|
|
3222
3508
|
const fingerprintStartedAt = performance.now();
|
|
3223
3509
|
const fingerprintPromise = fingerprintAbsoluteIosDevProject(project).then((fingerprint2) => {
|
|
3224
3510
|
timings.fingerprinting = performance.now() - fingerprintStartedAt;
|
|
3225
3511
|
return fingerprint2;
|
|
3226
3512
|
});
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3513
|
+
const target = deviceIdentifier ? await preparePhysicalIosTarget({
|
|
3514
|
+
capture,
|
|
3515
|
+
deviceIdentifier,
|
|
3516
|
+
log,
|
|
3517
|
+
project,
|
|
3518
|
+
serverHost,
|
|
3519
|
+
startOptions: options,
|
|
3520
|
+
transition
|
|
3521
|
+
}) : await prepareIosSimulatorTarget({
|
|
3522
|
+
capture,
|
|
3523
|
+
log,
|
|
3524
|
+
project,
|
|
3525
|
+
run,
|
|
3526
|
+
sleep,
|
|
3527
|
+
spawn,
|
|
3528
|
+
startOptions: options,
|
|
3529
|
+
transition
|
|
3530
|
+
});
|
|
3531
|
+
const {
|
|
3532
|
+
caEnrollmentServer: targetCaEnrollmentServer,
|
|
3533
|
+
startedSimulator,
|
|
3534
|
+
udid
|
|
3535
|
+
} = target;
|
|
3536
|
+
caEnrollmentServer = targetCaEnrollmentServer;
|
|
3243
3537
|
const fingerprint = await fingerprintPromise;
|
|
3244
3538
|
transition("checking-native");
|
|
3245
|
-
const
|
|
3246
|
-
|
|
3539
|
+
const cache = await readNativeCache(project.projectRoot);
|
|
3540
|
+
const nativeCacheHit = deviceIdentifier ? await ensurePhysicalIosDebugApp({
|
|
3541
|
+
cache,
|
|
3542
|
+
capture,
|
|
3543
|
+
fingerprint,
|
|
3544
|
+
identifier: deviceIdentifier,
|
|
3545
|
+
log,
|
|
3546
|
+
project,
|
|
3547
|
+
run,
|
|
3548
|
+
signal: options.signal,
|
|
3549
|
+
transition
|
|
3550
|
+
}) : await ensureIosDebugApp({
|
|
3551
|
+
cache,
|
|
3247
3552
|
capture,
|
|
3248
3553
|
fingerprint,
|
|
3249
3554
|
log,
|
|
@@ -3251,24 +3556,18 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3251
3556
|
run,
|
|
3252
3557
|
signal: options.signal,
|
|
3253
3558
|
transition,
|
|
3254
|
-
udid
|
|
3559
|
+
udid
|
|
3255
3560
|
});
|
|
3256
3561
|
throwIfAborted2(options.signal);
|
|
3257
3562
|
if (options.nativeLog)
|
|
3258
3563
|
transition("streaming-logs");
|
|
3259
|
-
nativeLogs = attachNativeLogs(project,
|
|
3564
|
+
nativeLogs = attachNativeLogs(project, udid, options);
|
|
3260
3565
|
transition("launching");
|
|
3261
|
-
|
|
3262
|
-
project.
|
|
3263
|
-
"simctl",
|
|
3264
|
-
"launch",
|
|
3265
|
-
"--terminate-running-process",
|
|
3266
|
-
device.udid,
|
|
3267
|
-
project.config.appId
|
|
3268
|
-
], "iOS app launch", run, { signal: options.signal });
|
|
3566
|
+
if (!deviceIdentifier || !nativeLogs)
|
|
3567
|
+
await requireSuccess2(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app launch", run, { signal: options.signal });
|
|
3269
3568
|
transition("ready");
|
|
3270
3569
|
timings.total = performance.now() - startedAt;
|
|
3271
|
-
log(`iOS
|
|
3570
|
+
log(`iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
3272
3571
|
log(`iOS startup: ${timingSummary(timings)}.`);
|
|
3273
3572
|
let closed = false;
|
|
3274
3573
|
const close = async () => {
|
|
@@ -3277,6 +3576,10 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3277
3576
|
closed = true;
|
|
3278
3577
|
transition("closing");
|
|
3279
3578
|
await closeLogs();
|
|
3579
|
+
await caEnrollmentServer?.close().catch(() => {
|
|
3580
|
+
return;
|
|
3581
|
+
});
|
|
3582
|
+
caEnrollmentServer = null;
|
|
3280
3583
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
3281
3584
|
transition("closed");
|
|
3282
3585
|
};
|
|
@@ -3284,8 +3587,9 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3284
3587
|
close,
|
|
3285
3588
|
nativeCacheHit,
|
|
3286
3589
|
startedSimulator,
|
|
3590
|
+
targetKind,
|
|
3287
3591
|
timings: { ...timings },
|
|
3288
|
-
udid
|
|
3592
|
+
udid,
|
|
3289
3593
|
rebuild: async () => {
|
|
3290
3594
|
if (closed)
|
|
3291
3595
|
throw new Error("iOS development session is closed.");
|
|
@@ -3298,22 +3602,17 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3298
3602
|
throw new Error("iOS development session is closed.");
|
|
3299
3603
|
transition("launching");
|
|
3300
3604
|
try {
|
|
3301
|
-
await
|
|
3302
|
-
project.xcrun,
|
|
3303
|
-
"simctl",
|
|
3304
|
-
"launch",
|
|
3305
|
-
"--terminate-running-process",
|
|
3306
|
-
device.udid,
|
|
3307
|
-
project.config.appId
|
|
3308
|
-
], "iOS app relaunch", run, { signal: options.signal });
|
|
3605
|
+
await relaunchTarget(udid);
|
|
3309
3606
|
transition("ready");
|
|
3310
|
-
log(`iOS app relaunched on ${
|
|
3607
|
+
log(`iOS app relaunched on the selected ${targetKind}.`);
|
|
3311
3608
|
} catch (error) {
|
|
3312
3609
|
transition("failed");
|
|
3313
3610
|
throw error;
|
|
3314
3611
|
}
|
|
3315
3612
|
},
|
|
3316
3613
|
screenshot: async (destination) => {
|
|
3614
|
+
if (deviceIdentifier)
|
|
3615
|
+
throw new Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");
|
|
3317
3616
|
const resolved = resolve5(project.projectRoot, destination);
|
|
3318
3617
|
if (!isInside(project.projectRoot, resolved))
|
|
3319
3618
|
throw new Error("iOS screenshot destination must remain inside the project.");
|
|
@@ -3322,7 +3621,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3322
3621
|
project.xcrun,
|
|
3323
3622
|
"simctl",
|
|
3324
3623
|
"io",
|
|
3325
|
-
|
|
3624
|
+
udid,
|
|
3326
3625
|
"screenshot",
|
|
3327
3626
|
resolved
|
|
3328
3627
|
], "iOS simulator screenshot", run, { signal: options.signal });
|
|
@@ -3335,6 +3634,9 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3335
3634
|
} catch (error) {
|
|
3336
3635
|
transition("failed");
|
|
3337
3636
|
await closeLogs();
|
|
3637
|
+
await caEnrollmentServer?.close().catch(() => {
|
|
3638
|
+
return;
|
|
3639
|
+
});
|
|
3338
3640
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
3339
3641
|
throw error;
|
|
3340
3642
|
}
|
|
@@ -3433,9 +3735,10 @@ var createAbsoluteIosNativeWatcher = async (options) => {
|
|
|
3433
3735
|
};
|
|
3434
3736
|
var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename(path));
|
|
3435
3737
|
// src/mobile/remoteMacProtocol.ts
|
|
3436
|
-
import { createHash as createHash7, randomUUID as
|
|
3437
|
-
import { chmod, mkdir as mkdir6, readFile as
|
|
3738
|
+
import { createHash as createHash7, randomUUID as randomUUID4 } from "crypto";
|
|
3739
|
+
import { chmod, mkdir as mkdir6, readFile as readFile9, rename as rename7, writeFile as writeFile7 } from "fs/promises";
|
|
3438
3740
|
import { homedir as homedir2 } from "os";
|
|
3741
|
+
import { isIP as isIP3 } from "net";
|
|
3439
3742
|
import {
|
|
3440
3743
|
dirname as dirname5,
|
|
3441
3744
|
isAbsolute as isAbsolute5,
|
|
@@ -3462,7 +3765,7 @@ var emptyStore = () => ({
|
|
|
3462
3765
|
});
|
|
3463
3766
|
var loadStore = async (path = defaultProfilePath()) => {
|
|
3464
3767
|
try {
|
|
3465
|
-
const parsed = JSON.parse(await
|
|
3768
|
+
const parsed = JSON.parse(await readFile9(path, "utf8"));
|
|
3466
3769
|
if (parsed.format !== PROFILE_FORMAT || typeof parsed.profiles !== "object" || parsed.profiles === null || Array.isArray(parsed.profiles))
|
|
3467
3770
|
throw new Error("Unsupported remote Mac profile format.");
|
|
3468
3771
|
for (const [key, profile] of Object.entries(parsed.profiles)) {
|
|
@@ -3480,7 +3783,7 @@ var loadStore = async (path = defaultProfilePath()) => {
|
|
|
3480
3783
|
};
|
|
3481
3784
|
var saveStore = async (store, path = defaultProfilePath()) => {
|
|
3482
3785
|
await mkdir6(dirname5(path), { recursive: true });
|
|
3483
|
-
const temporary = `${path}.${
|
|
3786
|
+
const temporary = `${path}.${randomUUID4()}.tmp`;
|
|
3484
3787
|
await writeFile7(temporary, `${JSON.stringify(store, null, 2)}
|
|
3485
3788
|
`, {
|
|
3486
3789
|
mode: 384
|
|
@@ -3548,6 +3851,18 @@ var requireRemoteSuccess = (result, label) => {
|
|
|
3548
3851
|
throw new Error(`${label} failed: ${(result.stderr || result.stdout).trim() || `status ${result.exitCode}`}`);
|
|
3549
3852
|
return result.stdout.trim();
|
|
3550
3853
|
};
|
|
3854
|
+
var captureAbsoluteRemoteMacCommand = async (profile, command, transport) => {
|
|
3855
|
+
if (command.length === 0)
|
|
3856
|
+
throw new TypeError("A Remote Mac command cannot be empty.");
|
|
3857
|
+
if (command.some((argument) => /[\r\n\0]/u.test(argument)))
|
|
3858
|
+
throw new TypeError("Remote Mac command arguments cannot contain controls.");
|
|
3859
|
+
const capture = transport?.capture ?? defaultTransport.capture;
|
|
3860
|
+
return capture([
|
|
3861
|
+
...absoluteRemoteMacSshBase(profile),
|
|
3862
|
+
"/bin/sh -lc",
|
|
3863
|
+
shellQuote(command.map((argument) => shellQuote(argument)).join(" "))
|
|
3864
|
+
]);
|
|
3865
|
+
};
|
|
3551
3866
|
var getAbsoluteRemoteMacProfile = async (name, profilePath) => {
|
|
3552
3867
|
const store = await loadStore(profilePath);
|
|
3553
3868
|
const selected = name ?? process.env.ABSOLUTE_IOS_REMOTE ?? store.defaultProfile;
|
|
@@ -3581,6 +3896,19 @@ var inspectAbsoluteRemoteMac = async (destination, options = {}) => {
|
|
|
3581
3896
|
throw new Error("The remote Mac must have full Xcode installed and selected.");
|
|
3582
3897
|
return { bunPath, home, os: operatingSystem, xcodeVersion };
|
|
3583
3898
|
};
|
|
3899
|
+
var inspectAbsoluteRemoteMacLanHost = async (profile, transport) => {
|
|
3900
|
+
const capture = transport?.capture ?? defaultTransport.capture;
|
|
3901
|
+
const script = `default_interface="$(/sbin/route -n get default 2>/dev/null | /usr/bin/awk '/interface:/{print $2; exit}')"; for interface in "$default_interface" en0 en1; do [ -n "$interface" ] || continue; address="$(/usr/sbin/ipconfig getifaddr "$interface" 2>/dev/null || true)"; if [ -n "$address" ]; then printf '%s\\n' "$address"; exit 0; fi; done; exit 1`;
|
|
3902
|
+
const result = await capture([
|
|
3903
|
+
...absoluteRemoteMacSshBase(profile),
|
|
3904
|
+
"/bin/sh -lc",
|
|
3905
|
+
shellQuote(script)
|
|
3906
|
+
]);
|
|
3907
|
+
const host = requireRemoteSuccess(result, "Remote Mac LAN address discovery").trim();
|
|
3908
|
+
if (isIP3(host) === 0)
|
|
3909
|
+
throw new Error("The Remote Mac did not report a device-reachable LAN address.");
|
|
3910
|
+
return host;
|
|
3911
|
+
};
|
|
3584
3912
|
var listAbsoluteRemoteMacProfiles = async (profilePath) => {
|
|
3585
3913
|
const store = await loadStore(profilePath);
|
|
3586
3914
|
return {
|
|
@@ -3652,7 +3980,7 @@ var installAbsoluteRemoteMacAgent = async (project) => {
|
|
|
3652
3980
|
]);
|
|
3653
3981
|
if (verified.exitCode === 0)
|
|
3654
3982
|
return { ...artifact, remotePath, uploaded: false };
|
|
3655
|
-
const temporary = posix.join(directory, `.agent-${
|
|
3983
|
+
const temporary = posix.join(directory, `.agent-${randomUUID4()}.tmp`);
|
|
3656
3984
|
const installScript = [
|
|
3657
3985
|
"set -eu",
|
|
3658
3986
|
"umask 077",
|
|
@@ -3743,7 +4071,7 @@ var portableMobileConfig = (project) => ({
|
|
|
3743
4071
|
var absoluteRemoteProjectSyncCommands = (project) => {
|
|
3744
4072
|
const current = project.remoteProjectRoot;
|
|
3745
4073
|
const parent = posix.dirname(current);
|
|
3746
|
-
const staging = posix.join(parent, `.incoming-${
|
|
4074
|
+
const staging = posix.join(parent, `.incoming-${randomUUID4()}`);
|
|
3747
4075
|
const previous = posix.join(parent, ".previous");
|
|
3748
4076
|
const script = [
|
|
3749
4077
|
"set -eu",
|
|
@@ -3835,7 +4163,13 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3835
4163
|
await syncProject(options.project);
|
|
3836
4164
|
const syncDuration = performance.now() - syncStartedAt;
|
|
3837
4165
|
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
3838
|
-
const encodedCertificateAuthority = options.certificateAuthorityPath ? (await
|
|
4166
|
+
const encodedCertificateAuthority = options.certificateAuthorityPath ? (await readFile9(options.certificateAuthorityPath)).toString("base64url") : undefined;
|
|
4167
|
+
const physicalDevice = options.deviceIdentifier !== undefined;
|
|
4168
|
+
let relayPort;
|
|
4169
|
+
if (physicalDevice)
|
|
4170
|
+
relayPort = options.port <= 49151 ? options.port + 16384 : options.port - 16384;
|
|
4171
|
+
if (physicalDevice && !options.serverHost)
|
|
4172
|
+
throw new Error("Remote physical iOS development requires the Remote Mac LAN host.");
|
|
3839
4173
|
const remoteCommand = [
|
|
3840
4174
|
`cd ${shellQuote(options.project.remoteProjectRoot)}`,
|
|
3841
4175
|
"&&",
|
|
@@ -3850,14 +4184,22 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3850
4184
|
"--certificate-authority",
|
|
3851
4185
|
shellQuote(encodedCertificateAuthority)
|
|
3852
4186
|
] : [],
|
|
3853
|
-
...options.https ? ["--https"] : []
|
|
4187
|
+
...options.https ? ["--https"] : [],
|
|
4188
|
+
...options.deviceIdentifier ? [
|
|
4189
|
+
"--ios-device",
|
|
4190
|
+
shellQuote(options.deviceIdentifier),
|
|
4191
|
+
"--server-host",
|
|
4192
|
+
shellQuote(options.serverHost ?? ""),
|
|
4193
|
+
"--relay-port",
|
|
4194
|
+
String(relayPort)
|
|
4195
|
+
] : []
|
|
3854
4196
|
].join(" ");
|
|
3855
4197
|
const command = [
|
|
3856
4198
|
...absoluteRemoteMacSshBase(options.project.profile),
|
|
3857
4199
|
"-o",
|
|
3858
4200
|
"ExitOnForwardFailure=yes",
|
|
3859
4201
|
"-R",
|
|
3860
|
-
`${options.port}:127.0.0.1:${options.port}`,
|
|
4202
|
+
physicalDevice ? `127.0.0.1:${relayPort}:127.0.0.1:${options.port}` : `${options.port}:127.0.0.1:${options.port}`,
|
|
3861
4203
|
"/bin/sh -lc",
|
|
3862
4204
|
shellQuote(remoteCommand)
|
|
3863
4205
|
];
|
|
@@ -3945,7 +4287,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3945
4287
|
};
|
|
3946
4288
|
options.log?.(`Remote Mac connected (${options.project.profile.name}); agent ${agent.uploaded ? "uploaded" : "cache hit"}, project synced, and iOS ready in ${totalDuration.toFixed(2)}ms.`);
|
|
3947
4289
|
const request = (commandName) => {
|
|
3948
|
-
const id =
|
|
4290
|
+
const id = randomUUID4();
|
|
3949
4291
|
const response = new Promise((resolve6, reject) => pending.set(id, { reject, resolve: resolve6 }));
|
|
3950
4292
|
process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: 1 })}
|
|
3951
4293
|
`);
|
|
@@ -3978,6 +4320,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3978
4320
|
close,
|
|
3979
4321
|
nativeCacheHit: currentReady.nativeCacheHit,
|
|
3980
4322
|
startedSimulator: currentReady.startedSimulator,
|
|
4323
|
+
targetKind: currentReady.targetKind,
|
|
3981
4324
|
timings: currentReady.timings,
|
|
3982
4325
|
udid: currentReady.udid,
|
|
3983
4326
|
rebuild: async () => {
|
|
@@ -4015,11 +4358,50 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
4015
4358
|
});
|
|
4016
4359
|
return makeSession();
|
|
4017
4360
|
};
|
|
4361
|
+
// src/mobile/iosDeviceAcceptance.ts
|
|
4362
|
+
var absoluteIosDeviceAcceptanceCommands = (options) => {
|
|
4363
|
+
const xcrun = options.xcrun ?? "/usr/bin/xcrun";
|
|
4364
|
+
const prefix = [xcrun, "devicectl", "device"];
|
|
4365
|
+
return {
|
|
4366
|
+
apps: [...prefix, "info", "apps", "--device", options.device],
|
|
4367
|
+
details: [...prefix, "info", "details", "--device", options.device],
|
|
4368
|
+
launch: [
|
|
4369
|
+
...prefix,
|
|
4370
|
+
"process",
|
|
4371
|
+
"launch",
|
|
4372
|
+
"--terminate-existing",
|
|
4373
|
+
"--device",
|
|
4374
|
+
options.device,
|
|
4375
|
+
options.appId
|
|
4376
|
+
]
|
|
4377
|
+
};
|
|
4378
|
+
};
|
|
4379
|
+
var requireSuccess3 = (result, message) => {
|
|
4380
|
+
if (result.exitCode !== 0)
|
|
4381
|
+
throw new Error(message);
|
|
4382
|
+
return result;
|
|
4383
|
+
};
|
|
4384
|
+
var testAbsoluteIosPhysicalDevice = async (options) => {
|
|
4385
|
+
const commands = absoluteIosDeviceAcceptanceCommands(options);
|
|
4386
|
+
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.");
|
|
4387
|
+
const apps = requireSuccess3(await options.capture(commands.apps), "AbsoluteJS could not inspect installed apps on the physical iOS device.");
|
|
4388
|
+
if (!apps.stdout.includes(options.appId))
|
|
4389
|
+
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.");
|
|
4390
|
+
const now = options.now ?? performance.now.bind(performance);
|
|
4391
|
+
const startedAt = now();
|
|
4392
|
+
requireSuccess3(await options.capture(commands.launch), "AbsoluteJS could not relaunch the app on the physical iOS device.");
|
|
4393
|
+
await options.waitForHmr();
|
|
4394
|
+
return {
|
|
4395
|
+
hmrConnected: true,
|
|
4396
|
+
installed: true,
|
|
4397
|
+
relaunchMs: Math.round(now() - startedAt)
|
|
4398
|
+
};
|
|
4399
|
+
};
|
|
4018
4400
|
// src/mobile/associationFiles.ts
|
|
4019
4401
|
import {
|
|
4020
4402
|
access as access7,
|
|
4021
4403
|
mkdir as mkdir7,
|
|
4022
|
-
readFile as
|
|
4404
|
+
readFile as readFile10,
|
|
4023
4405
|
rename as rename8,
|
|
4024
4406
|
rm as rm6,
|
|
4025
4407
|
writeFile as writeFile8
|
|
@@ -4225,7 +4607,7 @@ var createAbsoluteMobileAssociationPlugin = (mobile, projectRoot, options = {})
|
|
|
4225
4607
|
var writeAtomic = async (path, source) => {
|
|
4226
4608
|
let current;
|
|
4227
4609
|
try {
|
|
4228
|
-
current = await
|
|
4610
|
+
current = await readFile10(path, "utf8");
|
|
4229
4611
|
} catch (error) {
|
|
4230
4612
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
4231
4613
|
throw error;
|
|
@@ -4250,7 +4632,7 @@ var assertOwnedOutput = async (root) => {
|
|
|
4250
4632
|
const path = resolve7(root, OWNERSHIP_FILE);
|
|
4251
4633
|
let ownership;
|
|
4252
4634
|
try {
|
|
4253
|
-
ownership = JSON.parse(await
|
|
4635
|
+
ownership = JSON.parse(await readFile10(path, "utf8"));
|
|
4254
4636
|
} catch {
|
|
4255
4637
|
throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
|
|
4256
4638
|
}
|
|
@@ -4386,13 +4768,13 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
|
|
|
4386
4768
|
};
|
|
4387
4769
|
};
|
|
4388
4770
|
// src/mobile/buildPipeline.ts
|
|
4389
|
-
import { readFile as
|
|
4771
|
+
import { readFile as readFile14 } from "fs/promises";
|
|
4390
4772
|
import { join as join14, resolve as resolve12 } from "path";
|
|
4391
4773
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
4392
4774
|
|
|
4393
4775
|
// src/mobile/buildRelease.ts
|
|
4394
4776
|
import { createHash as createHash8 } from "crypto";
|
|
4395
|
-
import { mkdir as mkdir8, readFile as
|
|
4777
|
+
import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
|
|
4396
4778
|
import { basename as basename2, dirname as dirname6, extname, join as join8, relative as relative7, resolve as resolve8 } from "path";
|
|
4397
4779
|
var sha256 = (bytes) => createHash8("sha256").update(bytes).digest("hex");
|
|
4398
4780
|
var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
|
|
@@ -4419,7 +4801,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4419
4801
|
}
|
|
4420
4802
|
let resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
|
|
4421
4803
|
if (metadata.framework === "html" || metadata.framework === "htmx") {
|
|
4422
|
-
const source = await
|
|
4804
|
+
const source = await readFile11(resolvedAssetPath, "utf8");
|
|
4423
4805
|
const rewritten = rewriteStaticScriptPaths(source, manifest);
|
|
4424
4806
|
const documentHash = sha256(new TextEncoder().encode(rewritten));
|
|
4425
4807
|
resolvedAssetPath = join8(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
|
|
@@ -4433,8 +4815,8 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4433
4815
|
].map((key) => manifest[key]).find((path) => typeof path === "string");
|
|
4434
4816
|
const resolvedStylePath = styleAssetPath ? resolveAssetPath(buildDirectory, styleAssetPath) : undefined;
|
|
4435
4817
|
const [bytes, styleBytes] = await Promise.all([
|
|
4436
|
-
|
|
4437
|
-
resolvedStylePath ?
|
|
4818
|
+
readFile11(resolvedAssetPath),
|
|
4819
|
+
resolvedStylePath ? readFile11(resolvedStylePath) : undefined
|
|
4438
4820
|
]);
|
|
4439
4821
|
const bundlePath = `/${relative7(resolve8(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
|
|
4440
4822
|
const styleBundlePath = resolvedStylePath ? `/${relative7(resolve8(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
|
|
@@ -4454,7 +4836,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4454
4836
|
var buildAbsoluteMobileCompatibilityRelease = async (options) => {
|
|
4455
4837
|
const [captured, producerBytes] = await Promise.all([
|
|
4456
4838
|
captureAbsoluteMobileRouteGraph(options.app),
|
|
4457
|
-
|
|
4839
|
+
readFile11(options.producerPath)
|
|
4458
4840
|
]);
|
|
4459
4841
|
if (captured.length === 0) {
|
|
4460
4842
|
throw new TypeError("No instrumented AbsoluteJS mobile page routes were found in the finalized Elysia route graph.");
|
|
@@ -4546,7 +4928,7 @@ import {
|
|
|
4546
4928
|
copyFile as copyFile5,
|
|
4547
4929
|
mkdir as mkdir9,
|
|
4548
4930
|
mkdtemp as mkdtemp4,
|
|
4549
|
-
readFile as
|
|
4931
|
+
readFile as readFile12,
|
|
4550
4932
|
rename as rename9,
|
|
4551
4933
|
rm as rm7,
|
|
4552
4934
|
writeFile as writeFile10
|
|
@@ -5076,7 +5458,7 @@ var resolveProjectImport = async (projectRoot, specifier) => {
|
|
|
5076
5458
|
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
|
|
5077
5459
|
const subpath = specifier.slice(packageName.length);
|
|
5078
5460
|
const packageDirectory = join9(resolve9(projectRoot), "node_modules", packageName);
|
|
5079
|
-
const manifest = JSON.parse(await
|
|
5461
|
+
const manifest = JSON.parse(await readFile12(join9(packageDirectory, "package.json"), "utf8"));
|
|
5080
5462
|
const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
|
|
5081
5463
|
const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
|
|
5082
5464
|
const target = importEntryTarget(entry);
|
|
@@ -5184,7 +5566,7 @@ var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) =
|
|
|
5184
5566
|
};
|
|
5185
5567
|
};
|
|
5186
5568
|
var absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
5187
|
-
const source = await
|
|
5569
|
+
const source = await readFile12(sourcePath, "utf8");
|
|
5188
5570
|
const extension = extname2(sourcePath).toLowerCase();
|
|
5189
5571
|
let scriptLoader;
|
|
5190
5572
|
if (extension === ".tsx")
|
|
@@ -5295,7 +5677,7 @@ import {
|
|
|
5295
5677
|
access as access8,
|
|
5296
5678
|
mkdir as mkdir10,
|
|
5297
5679
|
mkdtemp as mkdtemp5,
|
|
5298
|
-
readFile as
|
|
5680
|
+
readFile as readFile13,
|
|
5299
5681
|
rename as rename10,
|
|
5300
5682
|
rm as rm8,
|
|
5301
5683
|
writeFile as writeFile11
|
|
@@ -5392,7 +5774,7 @@ var resolveProducerHandler = (loaded, exportName) => {
|
|
|
5392
5774
|
};
|
|
5393
5775
|
var loadAbsoluteMobileMaterializedBundle = async (root) => {
|
|
5394
5776
|
const resolvedRoot = resolvePath3(root);
|
|
5395
|
-
const serialized = await
|
|
5777
|
+
const serialized = await readFile13(join10(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
5396
5778
|
const parsed = JSON.parse(serialized);
|
|
5397
5779
|
const index = parseBundleIndex(parsed);
|
|
5398
5780
|
const bundleRoot = join10(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
@@ -5447,7 +5829,7 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
|
|
|
5447
5829
|
var readAbsoluteMobileMaterializedReleases = async (root) => {
|
|
5448
5830
|
const resolvedRoot = resolvePath3(root);
|
|
5449
5831
|
try {
|
|
5450
|
-
const serialized = await
|
|
5832
|
+
const serialized = await readFile13(join10(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
5451
5833
|
const parsed = JSON.parse(serialized);
|
|
5452
5834
|
const index = parseBundleIndex(parsed);
|
|
5453
5835
|
const bundleRoot = join10(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
@@ -5558,7 +5940,7 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
|
5558
5940
|
const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
|
|
5559
5941
|
const root = join14(buildDirectory, ".absolutejs", "mobile-compatibility");
|
|
5560
5942
|
const [manifestSource, previous] = await Promise.all([
|
|
5561
|
-
|
|
5943
|
+
readFile14(join14(buildDirectory, "manifest.json"), "utf8"),
|
|
5562
5944
|
readAbsoluteMobileMaterializedReleases(root)
|
|
5563
5945
|
]);
|
|
5564
5946
|
const manifest = JSON.parse(manifestSource);
|
|
@@ -5957,7 +6339,7 @@ var createAbsoluteMobilePreviewPlugin = (mobile) => {
|
|
|
5957
6339
|
});
|
|
5958
6340
|
};
|
|
5959
6341
|
// src/mobile/nativeDeepLinks.ts
|
|
5960
|
-
import { readFile as
|
|
6342
|
+
import { readFile as readFile15, rename as rename11, writeFile as writeFile12 } from "fs/promises";
|
|
5961
6343
|
import { join as join17 } from "path";
|
|
5962
6344
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
5963
6345
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
@@ -5965,7 +6347,7 @@ var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
|
5965
6347
|
var NOT_FOUND = -1;
|
|
5966
6348
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
5967
6349
|
var writeChangedFile = async (path, source) => {
|
|
5968
|
-
const current = await
|
|
6350
|
+
const current = await readFile15(path, "utf8");
|
|
5969
6351
|
if (current === source)
|
|
5970
6352
|
return false;
|
|
5971
6353
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -6016,7 +6398,7 @@ ${hosts}
|
|
|
6016
6398
|
};
|
|
6017
6399
|
var configureAndroid = async (config) => {
|
|
6018
6400
|
const path = join17(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
6019
|
-
const source = await
|
|
6401
|
+
const source = await readFile15(path, "utf8");
|
|
6020
6402
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
6021
6403
|
if (mainActivity === NOT_FOUND) {
|
|
6022
6404
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -6042,7 +6424,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
6042
6424
|
`;
|
|
6043
6425
|
var configureIosInfo = async (config) => {
|
|
6044
6426
|
const path = join17(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
6045
|
-
const source = await
|
|
6427
|
+
const source = await readFile15(path, "utf8");
|
|
6046
6428
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
6047
6429
|
${END_MARKER}
|
|
6048
6430
|
`;
|
|
@@ -6068,7 +6450,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
6068
6450
|
const path = join17(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
6069
6451
|
let current = "";
|
|
6070
6452
|
try {
|
|
6071
|
-
current = await
|
|
6453
|
+
current = await readFile15(path, "utf8");
|
|
6072
6454
|
} catch (error) {
|
|
6073
6455
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
6074
6456
|
throw error;
|
|
@@ -6084,7 +6466,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
6084
6466
|
};
|
|
6085
6467
|
var configureIosProject = async (config) => {
|
|
6086
6468
|
const path = join17(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
6087
|
-
const source = await
|
|
6469
|
+
const source = await readFile15(path, "utf8");
|
|
6088
6470
|
const declarations = [
|
|
6089
6471
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
6090
6472
|
].map((match) => match[1]);
|
|
@@ -6123,7 +6505,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
6123
6505
|
};
|
|
6124
6506
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
6125
6507
|
init_deviceCapabilities();
|
|
6126
|
-
import { readFile as
|
|
6508
|
+
import { readFile as readFile16, rename as rename12, writeFile as writeFile13 } from "fs/promises";
|
|
6127
6509
|
import { join as join18 } from "path";
|
|
6128
6510
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
6129
6511
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
@@ -6134,7 +6516,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
6134
6516
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
6135
6517
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
6136
6518
|
var writeChangedFile2 = async (path, source) => {
|
|
6137
|
-
const current = await
|
|
6519
|
+
const current = await readFile16(path, "utf8");
|
|
6138
6520
|
if (current === source)
|
|
6139
6521
|
return false;
|
|
6140
6522
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -6154,7 +6536,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
6154
6536
|
};
|
|
6155
6537
|
var optionalSource = async (path) => {
|
|
6156
6538
|
try {
|
|
6157
|
-
return await
|
|
6539
|
+
return await readFile16(path, "utf8");
|
|
6158
6540
|
} catch (error) {
|
|
6159
6541
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
6160
6542
|
return null;
|
|
@@ -6275,7 +6657,7 @@ var configureIosPrivacyProject = async (config, requirements) => {
|
|
|
6275
6657
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
6276
6658
|
return false;
|
|
6277
6659
|
const projectPath = join18(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
6278
|
-
const project = await
|
|
6660
|
+
const project = await readFile16(projectPath, "utf8");
|
|
6279
6661
|
return writeChangedFile2(projectPath, addIosPrivacyProjectReference(project));
|
|
6280
6662
|
};
|
|
6281
6663
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -6328,7 +6710,7 @@ ${next.slice(index)}`;
|
|
|
6328
6710
|
};
|
|
6329
6711
|
var configureIos2 = async (config, plan) => {
|
|
6330
6712
|
const path = join18(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
6331
|
-
const source = await
|
|
6713
|
+
const source = await readFile16(path, "utf8");
|
|
6332
6714
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
6333
6715
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
6334
6716
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -6421,7 +6803,7 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
6421
6803
|
};
|
|
6422
6804
|
var configureAndroid2 = async (config, plan) => {
|
|
6423
6805
|
const path = join18(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
6424
|
-
const source = await
|
|
6806
|
+
const source = await readFile16(path, "utf8");
|
|
6425
6807
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
6426
6808
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
6427
6809
|
`);
|
|
@@ -7308,9 +7690,12 @@ export {
|
|
|
7308
7690
|
verifyAbsoluteMobileAssociationFiles,
|
|
7309
7691
|
validateAbsoluteSshDestination,
|
|
7310
7692
|
validateAbsoluteRemoteMacProfileName,
|
|
7693
|
+
testAbsoluteIosPhysicalDevice,
|
|
7311
7694
|
syncAbsoluteRemoteMacProject,
|
|
7312
7695
|
startAbsoluteRemoteIosDevSession,
|
|
7696
|
+
startAbsoluteIosTcpRelay,
|
|
7313
7697
|
startAbsoluteIosDevSession,
|
|
7698
|
+
startAbsoluteIosCaEnrollmentServer,
|
|
7314
7699
|
serializeAbsoluteMobileAuthEnvironment,
|
|
7315
7700
|
runWithAbsoluteMobileProducer,
|
|
7316
7701
|
runAbsoluteAndroidUpgradeConformance,
|
|
@@ -7345,6 +7730,8 @@ export {
|
|
|
7345
7730
|
parseAbsoluteAndroidInstalledApp,
|
|
7346
7731
|
pairAbsoluteRemoteMac,
|
|
7347
7732
|
normalizeAbsoluteMobileConfig,
|
|
7733
|
+
normalizeAbsoluteIosDeviceIdentifier,
|
|
7734
|
+
normalizeAbsoluteIosDeviceHost,
|
|
7348
7735
|
navigateAbsoluteMobilePage,
|
|
7349
7736
|
missingAbsoluteDeviceCapabilityPackages,
|
|
7350
7737
|
materializeAbsoluteRemoteMacAgent,
|
|
@@ -7361,6 +7748,7 @@ export {
|
|
|
7361
7748
|
installAbsoluteMobileSyncRemediation,
|
|
7362
7749
|
installAbsoluteMobileShellHttp,
|
|
7363
7750
|
installAbsoluteMobileAuthEnvironment,
|
|
7751
|
+
inspectAbsoluteRemoteMacLanHost,
|
|
7364
7752
|
inspectAbsoluteRemoteMac,
|
|
7365
7753
|
inspectAbsoluteMobileRouteMetadata,
|
|
7366
7754
|
inspectAbsoluteAndroidInstalledApp,
|
|
@@ -7393,6 +7781,7 @@ export {
|
|
|
7393
7781
|
createAbsoluteMobileAssociationDocuments,
|
|
7394
7782
|
createAbsoluteIosNativeWatcher,
|
|
7395
7783
|
carryForwardAbsoluteMobileCompatibilityReleases,
|
|
7784
|
+
captureAbsoluteRemoteMacCommand,
|
|
7396
7785
|
captureAbsoluteMobileRouteGraph,
|
|
7397
7786
|
buildAbsoluteMobileCompatibilityRelease,
|
|
7398
7787
|
buildAbsoluteIosRelease,
|
|
@@ -7405,6 +7794,7 @@ export {
|
|
|
7405
7794
|
absoluteRemoteProjectSyncCommands,
|
|
7406
7795
|
absoluteRemoteMacSshBase,
|
|
7407
7796
|
absoluteMobilePreviewDocument,
|
|
7797
|
+
absoluteIosDeviceAcceptanceCommands,
|
|
7408
7798
|
absoluteDeviceNativeRequirements,
|
|
7409
7799
|
MOBILE_PAGE_REQUEST_HEADERS,
|
|
7410
7800
|
AbsoluteMobilePageProtocolError,
|
|
@@ -7430,5 +7820,5 @@ export {
|
|
|
7430
7820
|
ABSOLUTE_ANDROID_RELEASE_FORMAT
|
|
7431
7821
|
};
|
|
7432
7822
|
|
|
7433
|
-
//# debugId=
|
|
7823
|
+
//# debugId=D998DAA8591F90D464756E2164756E21
|
|
7434
7824
|
//# sourceMappingURL=index.js.map
|