@absolutejs/absolute 0.20.0-beta.32 → 0.20.0-beta.34
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/cli/index.js +777 -217
- package/dist/index.js +41 -27
- package/dist/index.js.map +4 -4
- package/dist/mobile/index.js +449 -91
- package/dist/mobile/index.js.map +8 -7
- package/dist/mobile/remoteMacAgentEntry.js +14 -14
- package/dist/src/cli/scripts/dev.d.ts +2 -0
- package/dist/src/dev/devCert.d.ts +6 -4
- package/dist/src/mobile/androidEmulatorController.d.ts +8 -1
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/iosPhysicalDeviceTransport.d.ts +16 -0
- package/dist/src/mobile/iosSimulatorController.d.ts +14 -1
- package/dist/src/mobile/remoteMacProtocol.d.ts +4 -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;
|
|
@@ -2700,6 +2817,40 @@ var requireSuccess2 = async (command, label, run, options) => {
|
|
|
2700
2817
|
if (exitCode !== 0)
|
|
2701
2818
|
throw new Error(`${label} failed with status ${exitCode}.`);
|
|
2702
2819
|
};
|
|
2820
|
+
var trustIosSimulatorDevelopmentCa = async (options, udid, run, log) => {
|
|
2821
|
+
if (!options.https)
|
|
2822
|
+
return;
|
|
2823
|
+
if (!options.certificateAuthorityPath) {
|
|
2824
|
+
throw new Error("iOS Simulator HTTPS requires the AbsoluteJS development CA certificate.");
|
|
2825
|
+
}
|
|
2826
|
+
await requireSuccess2([
|
|
2827
|
+
options.project.xcrun,
|
|
2828
|
+
"simctl",
|
|
2829
|
+
"keychain",
|
|
2830
|
+
udid,
|
|
2831
|
+
"add-root-cert",
|
|
2832
|
+
options.certificateAuthorityPath
|
|
2833
|
+
], "iOS Simulator development CA trust", run, { signal: options.signal });
|
|
2834
|
+
log("Installed the AbsoluteJS development CA into this iOS Simulator trust store.");
|
|
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
|
+
];
|
|
2703
2854
|
var requireCapturedSuccess = (result, label) => {
|
|
2704
2855
|
if (result.exitCode !== 0) {
|
|
2705
2856
|
throw new Error(`${label} failed: ${result.stderr.trim() || result.stdout.trim() || `status ${result.exitCode}`}`);
|
|
@@ -2837,7 +2988,7 @@ var repairAbsoluteIosDevSession = async (projectRoot) => {
|
|
|
2837
2988
|
await rm5(paths.root, { force: true, recursive: true });
|
|
2838
2989
|
return false;
|
|
2839
2990
|
}
|
|
2840
|
-
const journal = await
|
|
2991
|
+
const journal = await readFile8(paths.journal, "utf8").then((source) => parseJournal(JSON.parse(source))).catch(() => null);
|
|
2841
2992
|
if (!journal || !isInside(projectRoot, journal.nativeConfigPath) || !isInside(projectRoot, journal.infoPath) || !isInside(paths.root, journal.configBackupPath) || !isInside(paths.root, journal.infoBackupPath)) {
|
|
2842
2993
|
throw new Error(`Refusing unsafe or invalid iOS dev journal at ${paths.journal}.`);
|
|
2843
2994
|
}
|
|
@@ -2868,14 +3019,14 @@ var iosDevelopmentInfoPlist = (source, cleartext) => {
|
|
|
2868
3019
|
<true/>
|
|
2869
3020
|
</dict>`);
|
|
2870
3021
|
};
|
|
2871
|
-
var writeDevProjection = async (project, port, https) => {
|
|
3022
|
+
var writeDevProjection = async (project, port, https, serverHost = "localhost") => {
|
|
2872
3023
|
const paths = journalPaths(project.projectRoot);
|
|
2873
3024
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
2874
3025
|
const nativeConfigPath = join6(project.nativeDirectory, "App", "App", "capacitor.config.json");
|
|
2875
3026
|
const infoPath = join6(project.nativeDirectory, "App", "App", "Info.plist");
|
|
2876
3027
|
const [configSource, infoSource] = await Promise.all([
|
|
2877
|
-
|
|
2878
|
-
|
|
3028
|
+
readFile8(nativeConfigPath, "utf8"),
|
|
3029
|
+
readFile8(infoPath, "utf8")
|
|
2879
3030
|
]);
|
|
2880
3031
|
const parsed = JSON.parse(configSource);
|
|
2881
3032
|
if (!isRecord3(parsed))
|
|
@@ -2897,6 +3048,7 @@ var writeDevProjection = async (project, port, https) => {
|
|
|
2897
3048
|
flag: "wx"
|
|
2898
3049
|
});
|
|
2899
3050
|
const developmentUrl = new URL(`${https ? "https" : "http"}://localhost:${port}${project.config.entry}`);
|
|
3051
|
+
developmentUrl.hostname = isIP2(serverHost) === 6 ? `[${serverHost}]` : serverHost;
|
|
2900
3052
|
developmentUrl.searchParams.set("__absolute_target", "capacitor-ios");
|
|
2901
3053
|
const existingServer = parsed.server;
|
|
2902
3054
|
parsed.server = {
|
|
@@ -2926,10 +3078,10 @@ var parseNativeCache = (value) => {
|
|
|
2926
3078
|
]))
|
|
2927
3079
|
};
|
|
2928
3080
|
};
|
|
2929
|
-
var readNativeCache = (projectRoot) =>
|
|
3081
|
+
var readNativeCache = (projectRoot) => readFile8(nativeCachePath(projectRoot), "utf8").then((source) => parseNativeCache(JSON.parse(source))).catch(() => null);
|
|
2930
3082
|
var writeNativeCache = async (projectRoot, cache) => {
|
|
2931
3083
|
const destination = nativeCachePath(projectRoot);
|
|
2932
|
-
const temporary = `${destination}.${process.pid}.${
|
|
3084
|
+
const temporary = `${destination}.${process.pid}.${randomUUID3()}.tmp`;
|
|
2933
3085
|
await mkdir5(dirname4(destination), { recursive: true });
|
|
2934
3086
|
try {
|
|
2935
3087
|
await writeFile6(temporary, `${JSON.stringify(cache, null, "\t")}
|
|
@@ -3018,6 +3170,31 @@ var installedAppIdentity = (project, udid, capture) => {
|
|
|
3018
3170
|
]);
|
|
3019
3171
|
return result.exitCode === 0 && result.stdout.trim() ? result.stdout.trim() : undefined;
|
|
3020
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
|
+
};
|
|
3021
3198
|
var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
3022
3199
|
const derivedDataPath = join6(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash6("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
3023
3200
|
await mkdir5(derivedDataPath, { recursive: true });
|
|
@@ -3040,6 +3217,61 @@ var buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
|
3040
3217
|
throw new Error(`Xcode did not produce the simulator app at ${appPath}.`);
|
|
3041
3218
|
return appPath;
|
|
3042
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
|
+
};
|
|
3043
3275
|
var ensureIosDebugApp = async (options) => {
|
|
3044
3276
|
const installed = installedAppIdentity(options.project, options.udid, options.capture);
|
|
3045
3277
|
const cacheHit = options.cache?.appId === options.project.config.appId && options.cache.fingerprint === options.fingerprint && installed !== undefined && options.cache.installations[options.udid] === installed;
|
|
@@ -3086,7 +3318,18 @@ var attachNativeLogs = (project, udid, options) => {
|
|
|
3086
3318
|
if (!options.nativeLog)
|
|
3087
3319
|
return null;
|
|
3088
3320
|
const start = options.startNativeLogs ?? defaultStartNativeLogs;
|
|
3089
|
-
|
|
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
|
+
] : [
|
|
3090
3333
|
project.xcrun,
|
|
3091
3334
|
"simctl",
|
|
3092
3335
|
"spawn",
|
|
@@ -3099,7 +3342,8 @@ var attachNativeLogs = (project, udid, options) => {
|
|
|
3099
3342
|
"debug",
|
|
3100
3343
|
"--predicate",
|
|
3101
3344
|
'process == "App"'
|
|
3102
|
-
]
|
|
3345
|
+
];
|
|
3346
|
+
return start(command, { signal: options.signal }, (line) => {
|
|
3103
3347
|
const entry = parseAbsoluteIosLogLine(line);
|
|
3104
3348
|
if (entry)
|
|
3105
3349
|
options.nativeLog?.(entry);
|
|
@@ -3111,6 +3355,7 @@ var IOS_TIMING_PHASES = [
|
|
|
3111
3355
|
["fingerprinting", "fingerprint"],
|
|
3112
3356
|
["booting", "simulator"],
|
|
3113
3357
|
["connecting", "device ready"],
|
|
3358
|
+
["enrolling-trust", "HTTPS trust"],
|
|
3114
3359
|
["checking-native", "app check"],
|
|
3115
3360
|
["building", "Xcode"],
|
|
3116
3361
|
["installing", "install"],
|
|
@@ -3123,12 +3368,13 @@ var timingSummary = (timings) => IOS_TIMING_PHASES.map(([phase, label]) => {
|
|
|
3123
3368
|
}).filter((value) => value !== null).join(", ");
|
|
3124
3369
|
var prepareAbsoluteIosDevProject = async (config, options) => {
|
|
3125
3370
|
if (detectAbsoluteMobileHost() !== "macos")
|
|
3126
|
-
throw new Error("iOS
|
|
3371
|
+
throw new Error("iOS development requires macOS and Xcode.");
|
|
3372
|
+
const target = options.target ?? "simulator";
|
|
3127
3373
|
const projectRoot = resolve5(options.projectRoot);
|
|
3128
3374
|
const checks = await inspectAbsoluteMobileToolchain({ host: "macos" });
|
|
3129
|
-
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"));
|
|
3130
3376
|
if (failed.length > 0)
|
|
3131
|
-
throw new Error(`iOS
|
|
3377
|
+
throw new Error(`iOS ${target} development is not ready: ${failed.map(({ label }) => label).join(", ")}.`);
|
|
3132
3378
|
const xcrun = checks.find((check) => check.id === "ios.xcrun")?.path;
|
|
3133
3379
|
const xcodebuild = checks.find((check) => check.id === "ios.xcodebuild")?.path;
|
|
3134
3380
|
if (!xcrun || !xcodebuild)
|
|
@@ -3159,8 +3405,55 @@ var prepareAbsoluteIosDevProject = async (config, options) => {
|
|
|
3159
3405
|
xcrun
|
|
3160
3406
|
};
|
|
3161
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
|
+
};
|
|
3162
3452
|
var startAbsoluteIosDevSession = async (options) => {
|
|
3163
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";
|
|
3164
3457
|
const capture = options.capture ?? defaultCapture3;
|
|
3165
3458
|
const run = options.run ?? defaultRun2;
|
|
3166
3459
|
const sleep = options.sleep ?? Bun.sleep;
|
|
@@ -3188,6 +3481,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3188
3481
|
options.onStateChange?.(next);
|
|
3189
3482
|
};
|
|
3190
3483
|
let nativeLogs = null;
|
|
3484
|
+
let caEnrollmentServer = null;
|
|
3191
3485
|
const closeLogs = async () => {
|
|
3192
3486
|
const stream = nativeLogs;
|
|
3193
3487
|
nativeLogs = null;
|
|
@@ -3195,38 +3489,66 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3195
3489
|
return;
|
|
3196
3490
|
});
|
|
3197
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
|
+
};
|
|
3198
3500
|
try {
|
|
3199
3501
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
3200
3502
|
throwIfAborted2(options.signal);
|
|
3201
3503
|
transition("syncing");
|
|
3202
3504
|
await requireSuccess2([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
|
|
3203
3505
|
transition("configuring");
|
|
3204
|
-
await writeDevProjection(project, options.port, options.https === true);
|
|
3506
|
+
await writeDevProjection(project, options.port, options.https === true, serverHost);
|
|
3205
3507
|
throwIfAborted2(options.signal);
|
|
3206
3508
|
const fingerprintStartedAt = performance.now();
|
|
3207
3509
|
const fingerprintPromise = fingerprintAbsoluteIosDevProject(project).then((fingerprint2) => {
|
|
3208
3510
|
timings.fingerprinting = performance.now() - fingerprintStartedAt;
|
|
3209
3511
|
return fingerprint2;
|
|
3210
3512
|
});
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
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;
|
|
3226
3537
|
const fingerprint = await fingerprintPromise;
|
|
3227
3538
|
transition("checking-native");
|
|
3228
|
-
const
|
|
3229
|
-
|
|
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,
|
|
3230
3552
|
capture,
|
|
3231
3553
|
fingerprint,
|
|
3232
3554
|
log,
|
|
@@ -3234,24 +3556,18 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3234
3556
|
run,
|
|
3235
3557
|
signal: options.signal,
|
|
3236
3558
|
transition,
|
|
3237
|
-
udid
|
|
3559
|
+
udid
|
|
3238
3560
|
});
|
|
3239
3561
|
throwIfAborted2(options.signal);
|
|
3240
3562
|
if (options.nativeLog)
|
|
3241
3563
|
transition("streaming-logs");
|
|
3242
|
-
nativeLogs = attachNativeLogs(project,
|
|
3564
|
+
nativeLogs = attachNativeLogs(project, udid, options);
|
|
3243
3565
|
transition("launching");
|
|
3244
|
-
|
|
3245
|
-
project.
|
|
3246
|
-
"simctl",
|
|
3247
|
-
"launch",
|
|
3248
|
-
"--terminate-running-process",
|
|
3249
|
-
device.udid,
|
|
3250
|
-
project.config.appId
|
|
3251
|
-
], "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 });
|
|
3252
3568
|
transition("ready");
|
|
3253
3569
|
timings.total = performance.now() - startedAt;
|
|
3254
|
-
log(`iOS
|
|
3570
|
+
log(`iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
3255
3571
|
log(`iOS startup: ${timingSummary(timings)}.`);
|
|
3256
3572
|
let closed = false;
|
|
3257
3573
|
const close = async () => {
|
|
@@ -3260,6 +3576,10 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3260
3576
|
closed = true;
|
|
3261
3577
|
transition("closing");
|
|
3262
3578
|
await closeLogs();
|
|
3579
|
+
await caEnrollmentServer?.close().catch(() => {
|
|
3580
|
+
return;
|
|
3581
|
+
});
|
|
3582
|
+
caEnrollmentServer = null;
|
|
3263
3583
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
3264
3584
|
transition("closed");
|
|
3265
3585
|
};
|
|
@@ -3267,8 +3587,9 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3267
3587
|
close,
|
|
3268
3588
|
nativeCacheHit,
|
|
3269
3589
|
startedSimulator,
|
|
3590
|
+
targetKind,
|
|
3270
3591
|
timings: { ...timings },
|
|
3271
|
-
udid
|
|
3592
|
+
udid,
|
|
3272
3593
|
rebuild: async () => {
|
|
3273
3594
|
if (closed)
|
|
3274
3595
|
throw new Error("iOS development session is closed.");
|
|
@@ -3281,22 +3602,17 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3281
3602
|
throw new Error("iOS development session is closed.");
|
|
3282
3603
|
transition("launching");
|
|
3283
3604
|
try {
|
|
3284
|
-
await
|
|
3285
|
-
project.xcrun,
|
|
3286
|
-
"simctl",
|
|
3287
|
-
"launch",
|
|
3288
|
-
"--terminate-running-process",
|
|
3289
|
-
device.udid,
|
|
3290
|
-
project.config.appId
|
|
3291
|
-
], "iOS app relaunch", run, { signal: options.signal });
|
|
3605
|
+
await relaunchTarget(udid);
|
|
3292
3606
|
transition("ready");
|
|
3293
|
-
log(`iOS app relaunched on ${
|
|
3607
|
+
log(`iOS app relaunched on the selected ${targetKind}.`);
|
|
3294
3608
|
} catch (error) {
|
|
3295
3609
|
transition("failed");
|
|
3296
3610
|
throw error;
|
|
3297
3611
|
}
|
|
3298
3612
|
},
|
|
3299
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.");
|
|
3300
3616
|
const resolved = resolve5(project.projectRoot, destination);
|
|
3301
3617
|
if (!isInside(project.projectRoot, resolved))
|
|
3302
3618
|
throw new Error("iOS screenshot destination must remain inside the project.");
|
|
@@ -3305,7 +3621,7 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3305
3621
|
project.xcrun,
|
|
3306
3622
|
"simctl",
|
|
3307
3623
|
"io",
|
|
3308
|
-
|
|
3624
|
+
udid,
|
|
3309
3625
|
"screenshot",
|
|
3310
3626
|
resolved
|
|
3311
3627
|
], "iOS simulator screenshot", run, { signal: options.signal });
|
|
@@ -3318,6 +3634,9 @@ var startAbsoluteIosDevSession = async (options) => {
|
|
|
3318
3634
|
} catch (error) {
|
|
3319
3635
|
transition("failed");
|
|
3320
3636
|
await closeLogs();
|
|
3637
|
+
await caEnrollmentServer?.close().catch(() => {
|
|
3638
|
+
return;
|
|
3639
|
+
});
|
|
3321
3640
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
3322
3641
|
throw error;
|
|
3323
3642
|
}
|
|
@@ -3416,9 +3735,10 @@ var createAbsoluteIosNativeWatcher = async (options) => {
|
|
|
3416
3735
|
};
|
|
3417
3736
|
var isAbsoluteIosNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename(path));
|
|
3418
3737
|
// src/mobile/remoteMacProtocol.ts
|
|
3419
|
-
import { createHash as createHash7, randomUUID as
|
|
3420
|
-
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";
|
|
3421
3740
|
import { homedir as homedir2 } from "os";
|
|
3741
|
+
import { isIP as isIP3 } from "net";
|
|
3422
3742
|
import {
|
|
3423
3743
|
dirname as dirname5,
|
|
3424
3744
|
isAbsolute as isAbsolute5,
|
|
@@ -3445,7 +3765,7 @@ var emptyStore = () => ({
|
|
|
3445
3765
|
});
|
|
3446
3766
|
var loadStore = async (path = defaultProfilePath()) => {
|
|
3447
3767
|
try {
|
|
3448
|
-
const parsed = JSON.parse(await
|
|
3768
|
+
const parsed = JSON.parse(await readFile9(path, "utf8"));
|
|
3449
3769
|
if (parsed.format !== PROFILE_FORMAT || typeof parsed.profiles !== "object" || parsed.profiles === null || Array.isArray(parsed.profiles))
|
|
3450
3770
|
throw new Error("Unsupported remote Mac profile format.");
|
|
3451
3771
|
for (const [key, profile] of Object.entries(parsed.profiles)) {
|
|
@@ -3463,7 +3783,7 @@ var loadStore = async (path = defaultProfilePath()) => {
|
|
|
3463
3783
|
};
|
|
3464
3784
|
var saveStore = async (store, path = defaultProfilePath()) => {
|
|
3465
3785
|
await mkdir6(dirname5(path), { recursive: true });
|
|
3466
|
-
const temporary = `${path}.${
|
|
3786
|
+
const temporary = `${path}.${randomUUID4()}.tmp`;
|
|
3467
3787
|
await writeFile7(temporary, `${JSON.stringify(store, null, 2)}
|
|
3468
3788
|
`, {
|
|
3469
3789
|
mode: 384
|
|
@@ -3564,6 +3884,19 @@ var inspectAbsoluteRemoteMac = async (destination, options = {}) => {
|
|
|
3564
3884
|
throw new Error("The remote Mac must have full Xcode installed and selected.");
|
|
3565
3885
|
return { bunPath, home, os: operatingSystem, xcodeVersion };
|
|
3566
3886
|
};
|
|
3887
|
+
var inspectAbsoluteRemoteMacLanHost = async (profile, transport) => {
|
|
3888
|
+
const capture = transport?.capture ?? defaultTransport.capture;
|
|
3889
|
+
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`;
|
|
3890
|
+
const result = await capture([
|
|
3891
|
+
...absoluteRemoteMacSshBase(profile),
|
|
3892
|
+
"/bin/sh -lc",
|
|
3893
|
+
shellQuote(script)
|
|
3894
|
+
]);
|
|
3895
|
+
const host = requireRemoteSuccess(result, "Remote Mac LAN address discovery").trim();
|
|
3896
|
+
if (isIP3(host) === 0)
|
|
3897
|
+
throw new Error("The Remote Mac did not report a device-reachable LAN address.");
|
|
3898
|
+
return host;
|
|
3899
|
+
};
|
|
3567
3900
|
var listAbsoluteRemoteMacProfiles = async (profilePath) => {
|
|
3568
3901
|
const store = await loadStore(profilePath);
|
|
3569
3902
|
return {
|
|
@@ -3635,7 +3968,7 @@ var installAbsoluteRemoteMacAgent = async (project) => {
|
|
|
3635
3968
|
]);
|
|
3636
3969
|
if (verified.exitCode === 0)
|
|
3637
3970
|
return { ...artifact, remotePath, uploaded: false };
|
|
3638
|
-
const temporary = posix.join(directory, `.agent-${
|
|
3971
|
+
const temporary = posix.join(directory, `.agent-${randomUUID4()}.tmp`);
|
|
3639
3972
|
const installScript = [
|
|
3640
3973
|
"set -eu",
|
|
3641
3974
|
"umask 077",
|
|
@@ -3726,7 +4059,7 @@ var portableMobileConfig = (project) => ({
|
|
|
3726
4059
|
var absoluteRemoteProjectSyncCommands = (project) => {
|
|
3727
4060
|
const current = project.remoteProjectRoot;
|
|
3728
4061
|
const parent = posix.dirname(current);
|
|
3729
|
-
const staging = posix.join(parent, `.incoming-${
|
|
4062
|
+
const staging = posix.join(parent, `.incoming-${randomUUID4()}`);
|
|
3730
4063
|
const previous = posix.join(parent, ".previous");
|
|
3731
4064
|
const script = [
|
|
3732
4065
|
"set -eu",
|
|
@@ -3818,6 +4151,13 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3818
4151
|
await syncProject(options.project);
|
|
3819
4152
|
const syncDuration = performance.now() - syncStartedAt;
|
|
3820
4153
|
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
4154
|
+
const encodedCertificateAuthority = options.certificateAuthorityPath ? (await readFile9(options.certificateAuthorityPath)).toString("base64url") : undefined;
|
|
4155
|
+
const physicalDevice = options.deviceIdentifier !== undefined;
|
|
4156
|
+
let relayPort;
|
|
4157
|
+
if (physicalDevice)
|
|
4158
|
+
relayPort = options.port <= 49151 ? options.port + 16384 : options.port - 16384;
|
|
4159
|
+
if (physicalDevice && !options.serverHost)
|
|
4160
|
+
throw new Error("Remote physical iOS development requires the Remote Mac LAN host.");
|
|
3821
4161
|
const remoteCommand = [
|
|
3822
4162
|
`cd ${shellQuote(options.project.remoteProjectRoot)}`,
|
|
3823
4163
|
"&&",
|
|
@@ -3828,14 +4168,26 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3828
4168
|
String(options.port),
|
|
3829
4169
|
"--mobile-config",
|
|
3830
4170
|
shellQuote(encodedConfig),
|
|
3831
|
-
...
|
|
4171
|
+
...encodedCertificateAuthority ? [
|
|
4172
|
+
"--certificate-authority",
|
|
4173
|
+
shellQuote(encodedCertificateAuthority)
|
|
4174
|
+
] : [],
|
|
4175
|
+
...options.https ? ["--https"] : [],
|
|
4176
|
+
...options.deviceIdentifier ? [
|
|
4177
|
+
"--ios-device",
|
|
4178
|
+
shellQuote(options.deviceIdentifier),
|
|
4179
|
+
"--server-host",
|
|
4180
|
+
shellQuote(options.serverHost ?? ""),
|
|
4181
|
+
"--relay-port",
|
|
4182
|
+
String(relayPort)
|
|
4183
|
+
] : []
|
|
3832
4184
|
].join(" ");
|
|
3833
4185
|
const command = [
|
|
3834
4186
|
...absoluteRemoteMacSshBase(options.project.profile),
|
|
3835
4187
|
"-o",
|
|
3836
4188
|
"ExitOnForwardFailure=yes",
|
|
3837
4189
|
"-R",
|
|
3838
|
-
`${options.port}:127.0.0.1:${options.port}`,
|
|
4190
|
+
physicalDevice ? `127.0.0.1:${relayPort}:127.0.0.1:${options.port}` : `${options.port}:127.0.0.1:${options.port}`,
|
|
3839
4191
|
"/bin/sh -lc",
|
|
3840
4192
|
shellQuote(remoteCommand)
|
|
3841
4193
|
];
|
|
@@ -3923,7 +4275,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3923
4275
|
};
|
|
3924
4276
|
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.`);
|
|
3925
4277
|
const request = (commandName) => {
|
|
3926
|
-
const id =
|
|
4278
|
+
const id = randomUUID4();
|
|
3927
4279
|
const response = new Promise((resolve6, reject) => pending.set(id, { reject, resolve: resolve6 }));
|
|
3928
4280
|
process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: 1 })}
|
|
3929
4281
|
`);
|
|
@@ -3956,6 +4308,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3956
4308
|
close,
|
|
3957
4309
|
nativeCacheHit: currentReady.nativeCacheHit,
|
|
3958
4310
|
startedSimulator: currentReady.startedSimulator,
|
|
4311
|
+
targetKind: currentReady.targetKind,
|
|
3959
4312
|
timings: currentReady.timings,
|
|
3960
4313
|
udid: currentReady.udid,
|
|
3961
4314
|
rebuild: async () => {
|
|
@@ -3997,7 +4350,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3997
4350
|
import {
|
|
3998
4351
|
access as access7,
|
|
3999
4352
|
mkdir as mkdir7,
|
|
4000
|
-
readFile as
|
|
4353
|
+
readFile as readFile10,
|
|
4001
4354
|
rename as rename8,
|
|
4002
4355
|
rm as rm6,
|
|
4003
4356
|
writeFile as writeFile8
|
|
@@ -4203,7 +4556,7 @@ var createAbsoluteMobileAssociationPlugin = (mobile, projectRoot, options = {})
|
|
|
4203
4556
|
var writeAtomic = async (path, source) => {
|
|
4204
4557
|
let current;
|
|
4205
4558
|
try {
|
|
4206
|
-
current = await
|
|
4559
|
+
current = await readFile10(path, "utf8");
|
|
4207
4560
|
} catch (error) {
|
|
4208
4561
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
4209
4562
|
throw error;
|
|
@@ -4228,7 +4581,7 @@ var assertOwnedOutput = async (root) => {
|
|
|
4228
4581
|
const path = resolve7(root, OWNERSHIP_FILE);
|
|
4229
4582
|
let ownership;
|
|
4230
4583
|
try {
|
|
4231
|
-
ownership = JSON.parse(await
|
|
4584
|
+
ownership = JSON.parse(await readFile10(path, "utf8"));
|
|
4232
4585
|
} catch {
|
|
4233
4586
|
throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
|
|
4234
4587
|
}
|
|
@@ -4364,13 +4717,13 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
|
|
|
4364
4717
|
};
|
|
4365
4718
|
};
|
|
4366
4719
|
// src/mobile/buildPipeline.ts
|
|
4367
|
-
import { readFile as
|
|
4720
|
+
import { readFile as readFile14 } from "fs/promises";
|
|
4368
4721
|
import { join as join14, resolve as resolve12 } from "path";
|
|
4369
4722
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
4370
4723
|
|
|
4371
4724
|
// src/mobile/buildRelease.ts
|
|
4372
4725
|
import { createHash as createHash8 } from "crypto";
|
|
4373
|
-
import { mkdir as mkdir8, readFile as
|
|
4726
|
+
import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
|
|
4374
4727
|
import { basename as basename2, dirname as dirname6, extname, join as join8, relative as relative7, resolve as resolve8 } from "path";
|
|
4375
4728
|
var sha256 = (bytes) => createHash8("sha256").update(bytes).digest("hex");
|
|
4376
4729
|
var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
|
|
@@ -4397,7 +4750,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4397
4750
|
}
|
|
4398
4751
|
let resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
|
|
4399
4752
|
if (metadata.framework === "html" || metadata.framework === "htmx") {
|
|
4400
|
-
const source = await
|
|
4753
|
+
const source = await readFile11(resolvedAssetPath, "utf8");
|
|
4401
4754
|
const rewritten = rewriteStaticScriptPaths(source, manifest);
|
|
4402
4755
|
const documentHash = sha256(new TextEncoder().encode(rewritten));
|
|
4403
4756
|
resolvedAssetPath = join8(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
|
|
@@ -4411,8 +4764,8 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4411
4764
|
].map((key) => manifest[key]).find((path) => typeof path === "string");
|
|
4412
4765
|
const resolvedStylePath = styleAssetPath ? resolveAssetPath(buildDirectory, styleAssetPath) : undefined;
|
|
4413
4766
|
const [bytes, styleBytes] = await Promise.all([
|
|
4414
|
-
|
|
4415
|
-
resolvedStylePath ?
|
|
4767
|
+
readFile11(resolvedAssetPath),
|
|
4768
|
+
resolvedStylePath ? readFile11(resolvedStylePath) : undefined
|
|
4416
4769
|
]);
|
|
4417
4770
|
const bundlePath = `/${relative7(resolve8(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
|
|
4418
4771
|
const styleBundlePath = resolvedStylePath ? `/${relative7(resolve8(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
|
|
@@ -4432,7 +4785,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4432
4785
|
var buildAbsoluteMobileCompatibilityRelease = async (options) => {
|
|
4433
4786
|
const [captured, producerBytes] = await Promise.all([
|
|
4434
4787
|
captureAbsoluteMobileRouteGraph(options.app),
|
|
4435
|
-
|
|
4788
|
+
readFile11(options.producerPath)
|
|
4436
4789
|
]);
|
|
4437
4790
|
if (captured.length === 0) {
|
|
4438
4791
|
throw new TypeError("No instrumented AbsoluteJS mobile page routes were found in the finalized Elysia route graph.");
|
|
@@ -4524,7 +4877,7 @@ import {
|
|
|
4524
4877
|
copyFile as copyFile5,
|
|
4525
4878
|
mkdir as mkdir9,
|
|
4526
4879
|
mkdtemp as mkdtemp4,
|
|
4527
|
-
readFile as
|
|
4880
|
+
readFile as readFile12,
|
|
4528
4881
|
rename as rename9,
|
|
4529
4882
|
rm as rm7,
|
|
4530
4883
|
writeFile as writeFile10
|
|
@@ -5054,7 +5407,7 @@ var resolveProjectImport = async (projectRoot, specifier) => {
|
|
|
5054
5407
|
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
|
|
5055
5408
|
const subpath = specifier.slice(packageName.length);
|
|
5056
5409
|
const packageDirectory = join9(resolve9(projectRoot), "node_modules", packageName);
|
|
5057
|
-
const manifest = JSON.parse(await
|
|
5410
|
+
const manifest = JSON.parse(await readFile12(join9(packageDirectory, "package.json"), "utf8"));
|
|
5058
5411
|
const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
|
|
5059
5412
|
const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
|
|
5060
5413
|
const target = importEntryTarget(entry);
|
|
@@ -5162,7 +5515,7 @@ var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) =
|
|
|
5162
5515
|
};
|
|
5163
5516
|
};
|
|
5164
5517
|
var absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
5165
|
-
const source = await
|
|
5518
|
+
const source = await readFile12(sourcePath, "utf8");
|
|
5166
5519
|
const extension = extname2(sourcePath).toLowerCase();
|
|
5167
5520
|
let scriptLoader;
|
|
5168
5521
|
if (extension === ".tsx")
|
|
@@ -5273,7 +5626,7 @@ import {
|
|
|
5273
5626
|
access as access8,
|
|
5274
5627
|
mkdir as mkdir10,
|
|
5275
5628
|
mkdtemp as mkdtemp5,
|
|
5276
|
-
readFile as
|
|
5629
|
+
readFile as readFile13,
|
|
5277
5630
|
rename as rename10,
|
|
5278
5631
|
rm as rm8,
|
|
5279
5632
|
writeFile as writeFile11
|
|
@@ -5370,7 +5723,7 @@ var resolveProducerHandler = (loaded, exportName) => {
|
|
|
5370
5723
|
};
|
|
5371
5724
|
var loadAbsoluteMobileMaterializedBundle = async (root) => {
|
|
5372
5725
|
const resolvedRoot = resolvePath3(root);
|
|
5373
|
-
const serialized = await
|
|
5726
|
+
const serialized = await readFile13(join10(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
5374
5727
|
const parsed = JSON.parse(serialized);
|
|
5375
5728
|
const index = parseBundleIndex(parsed);
|
|
5376
5729
|
const bundleRoot = join10(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
@@ -5425,7 +5778,7 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
|
|
|
5425
5778
|
var readAbsoluteMobileMaterializedReleases = async (root) => {
|
|
5426
5779
|
const resolvedRoot = resolvePath3(root);
|
|
5427
5780
|
try {
|
|
5428
|
-
const serialized = await
|
|
5781
|
+
const serialized = await readFile13(join10(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
5429
5782
|
const parsed = JSON.parse(serialized);
|
|
5430
5783
|
const index = parseBundleIndex(parsed);
|
|
5431
5784
|
const bundleRoot = join10(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
@@ -5536,7 +5889,7 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
|
5536
5889
|
const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
|
|
5537
5890
|
const root = join14(buildDirectory, ".absolutejs", "mobile-compatibility");
|
|
5538
5891
|
const [manifestSource, previous] = await Promise.all([
|
|
5539
|
-
|
|
5892
|
+
readFile14(join14(buildDirectory, "manifest.json"), "utf8"),
|
|
5540
5893
|
readAbsoluteMobileMaterializedReleases(root)
|
|
5541
5894
|
]);
|
|
5542
5895
|
const manifest = JSON.parse(manifestSource);
|
|
@@ -5935,7 +6288,7 @@ var createAbsoluteMobilePreviewPlugin = (mobile) => {
|
|
|
5935
6288
|
});
|
|
5936
6289
|
};
|
|
5937
6290
|
// src/mobile/nativeDeepLinks.ts
|
|
5938
|
-
import { readFile as
|
|
6291
|
+
import { readFile as readFile15, rename as rename11, writeFile as writeFile12 } from "fs/promises";
|
|
5939
6292
|
import { join as join17 } from "path";
|
|
5940
6293
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
5941
6294
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
@@ -5943,7 +6296,7 @@ var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
|
5943
6296
|
var NOT_FOUND = -1;
|
|
5944
6297
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
5945
6298
|
var writeChangedFile = async (path, source) => {
|
|
5946
|
-
const current = await
|
|
6299
|
+
const current = await readFile15(path, "utf8");
|
|
5947
6300
|
if (current === source)
|
|
5948
6301
|
return false;
|
|
5949
6302
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -5994,7 +6347,7 @@ ${hosts}
|
|
|
5994
6347
|
};
|
|
5995
6348
|
var configureAndroid = async (config) => {
|
|
5996
6349
|
const path = join17(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
5997
|
-
const source = await
|
|
6350
|
+
const source = await readFile15(path, "utf8");
|
|
5998
6351
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
5999
6352
|
if (mainActivity === NOT_FOUND) {
|
|
6000
6353
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -6020,7 +6373,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
6020
6373
|
`;
|
|
6021
6374
|
var configureIosInfo = async (config) => {
|
|
6022
6375
|
const path = join17(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
6023
|
-
const source = await
|
|
6376
|
+
const source = await readFile15(path, "utf8");
|
|
6024
6377
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
6025
6378
|
${END_MARKER}
|
|
6026
6379
|
`;
|
|
@@ -6046,7 +6399,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
6046
6399
|
const path = join17(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
6047
6400
|
let current = "";
|
|
6048
6401
|
try {
|
|
6049
|
-
current = await
|
|
6402
|
+
current = await readFile15(path, "utf8");
|
|
6050
6403
|
} catch (error) {
|
|
6051
6404
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
6052
6405
|
throw error;
|
|
@@ -6062,7 +6415,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
6062
6415
|
};
|
|
6063
6416
|
var configureIosProject = async (config) => {
|
|
6064
6417
|
const path = join17(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
6065
|
-
const source = await
|
|
6418
|
+
const source = await readFile15(path, "utf8");
|
|
6066
6419
|
const declarations = [
|
|
6067
6420
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
6068
6421
|
].map((match) => match[1]);
|
|
@@ -6101,7 +6454,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
6101
6454
|
};
|
|
6102
6455
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
6103
6456
|
init_deviceCapabilities();
|
|
6104
|
-
import { readFile as
|
|
6457
|
+
import { readFile as readFile16, rename as rename12, writeFile as writeFile13 } from "fs/promises";
|
|
6105
6458
|
import { join as join18 } from "path";
|
|
6106
6459
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
6107
6460
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
@@ -6112,7 +6465,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
6112
6465
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
6113
6466
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
6114
6467
|
var writeChangedFile2 = async (path, source) => {
|
|
6115
|
-
const current = await
|
|
6468
|
+
const current = await readFile16(path, "utf8");
|
|
6116
6469
|
if (current === source)
|
|
6117
6470
|
return false;
|
|
6118
6471
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -6132,7 +6485,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
6132
6485
|
};
|
|
6133
6486
|
var optionalSource = async (path) => {
|
|
6134
6487
|
try {
|
|
6135
|
-
return await
|
|
6488
|
+
return await readFile16(path, "utf8");
|
|
6136
6489
|
} catch (error) {
|
|
6137
6490
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
6138
6491
|
return null;
|
|
@@ -6253,7 +6606,7 @@ var configureIosPrivacyProject = async (config, requirements) => {
|
|
|
6253
6606
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
6254
6607
|
return false;
|
|
6255
6608
|
const projectPath = join18(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
6256
|
-
const project = await
|
|
6609
|
+
const project = await readFile16(projectPath, "utf8");
|
|
6257
6610
|
return writeChangedFile2(projectPath, addIosPrivacyProjectReference(project));
|
|
6258
6611
|
};
|
|
6259
6612
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -6306,7 +6659,7 @@ ${next.slice(index)}`;
|
|
|
6306
6659
|
};
|
|
6307
6660
|
var configureIos2 = async (config, plan) => {
|
|
6308
6661
|
const path = join18(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
6309
|
-
const source = await
|
|
6662
|
+
const source = await readFile16(path, "utf8");
|
|
6310
6663
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
6311
6664
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
6312
6665
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -6399,7 +6752,7 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
6399
6752
|
};
|
|
6400
6753
|
var configureAndroid2 = async (config, plan) => {
|
|
6401
6754
|
const path = join18(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
6402
|
-
const source = await
|
|
6755
|
+
const source = await readFile16(path, "utf8");
|
|
6403
6756
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
6404
6757
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
6405
6758
|
`);
|
|
@@ -7288,7 +7641,9 @@ export {
|
|
|
7288
7641
|
validateAbsoluteRemoteMacProfileName,
|
|
7289
7642
|
syncAbsoluteRemoteMacProject,
|
|
7290
7643
|
startAbsoluteRemoteIosDevSession,
|
|
7644
|
+
startAbsoluteIosTcpRelay,
|
|
7291
7645
|
startAbsoluteIosDevSession,
|
|
7646
|
+
startAbsoluteIosCaEnrollmentServer,
|
|
7292
7647
|
serializeAbsoluteMobileAuthEnvironment,
|
|
7293
7648
|
runWithAbsoluteMobileProducer,
|
|
7294
7649
|
runAbsoluteAndroidUpgradeConformance,
|
|
@@ -7323,6 +7678,8 @@ export {
|
|
|
7323
7678
|
parseAbsoluteAndroidInstalledApp,
|
|
7324
7679
|
pairAbsoluteRemoteMac,
|
|
7325
7680
|
normalizeAbsoluteMobileConfig,
|
|
7681
|
+
normalizeAbsoluteIosDeviceIdentifier,
|
|
7682
|
+
normalizeAbsoluteIosDeviceHost,
|
|
7326
7683
|
navigateAbsoluteMobilePage,
|
|
7327
7684
|
missingAbsoluteDeviceCapabilityPackages,
|
|
7328
7685
|
materializeAbsoluteRemoteMacAgent,
|
|
@@ -7339,6 +7696,7 @@ export {
|
|
|
7339
7696
|
installAbsoluteMobileSyncRemediation,
|
|
7340
7697
|
installAbsoluteMobileShellHttp,
|
|
7341
7698
|
installAbsoluteMobileAuthEnvironment,
|
|
7699
|
+
inspectAbsoluteRemoteMacLanHost,
|
|
7342
7700
|
inspectAbsoluteRemoteMac,
|
|
7343
7701
|
inspectAbsoluteMobileRouteMetadata,
|
|
7344
7702
|
inspectAbsoluteAndroidInstalledApp,
|
|
@@ -7408,5 +7766,5 @@ export {
|
|
|
7408
7766
|
ABSOLUTE_ANDROID_RELEASE_FORMAT
|
|
7409
7767
|
};
|
|
7410
7768
|
|
|
7411
|
-
//# debugId=
|
|
7769
|
+
//# debugId=ED7CBBBE08CD962364756E2164756E21
|
|
7412
7770
|
//# sourceMappingURL=index.js.map
|