@absolutejs/absolute 0.20.0-beta.33 → 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 +481 -144
- package/dist/mobile/index.js +429 -93
- package/dist/mobile/index.js.map +7 -6
- package/dist/mobile/remoteMacAgentEntry.js +14 -14
- package/dist/src/cli/scripts/dev.d.ts +1 -0
- 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 +12 -1
- package/dist/src/mobile/remoteMacProtocol.d.ts +3 -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
|
|
@@ -3581,6 +3884,19 @@ var inspectAbsoluteRemoteMac = async (destination, options = {}) => {
|
|
|
3581
3884
|
throw new Error("The remote Mac must have full Xcode installed and selected.");
|
|
3582
3885
|
return { bunPath, home, os: operatingSystem, xcodeVersion };
|
|
3583
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
|
+
};
|
|
3584
3900
|
var listAbsoluteRemoteMacProfiles = async (profilePath) => {
|
|
3585
3901
|
const store = await loadStore(profilePath);
|
|
3586
3902
|
return {
|
|
@@ -3652,7 +3968,7 @@ var installAbsoluteRemoteMacAgent = async (project) => {
|
|
|
3652
3968
|
]);
|
|
3653
3969
|
if (verified.exitCode === 0)
|
|
3654
3970
|
return { ...artifact, remotePath, uploaded: false };
|
|
3655
|
-
const temporary = posix.join(directory, `.agent-${
|
|
3971
|
+
const temporary = posix.join(directory, `.agent-${randomUUID4()}.tmp`);
|
|
3656
3972
|
const installScript = [
|
|
3657
3973
|
"set -eu",
|
|
3658
3974
|
"umask 077",
|
|
@@ -3743,7 +4059,7 @@ var portableMobileConfig = (project) => ({
|
|
|
3743
4059
|
var absoluteRemoteProjectSyncCommands = (project) => {
|
|
3744
4060
|
const current = project.remoteProjectRoot;
|
|
3745
4061
|
const parent = posix.dirname(current);
|
|
3746
|
-
const staging = posix.join(parent, `.incoming-${
|
|
4062
|
+
const staging = posix.join(parent, `.incoming-${randomUUID4()}`);
|
|
3747
4063
|
const previous = posix.join(parent, ".previous");
|
|
3748
4064
|
const script = [
|
|
3749
4065
|
"set -eu",
|
|
@@ -3835,7 +4151,13 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3835
4151
|
await syncProject(options.project);
|
|
3836
4152
|
const syncDuration = performance.now() - syncStartedAt;
|
|
3837
4153
|
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
3838
|
-
const encodedCertificateAuthority = options.certificateAuthorityPath ? (await
|
|
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.");
|
|
3839
4161
|
const remoteCommand = [
|
|
3840
4162
|
`cd ${shellQuote(options.project.remoteProjectRoot)}`,
|
|
3841
4163
|
"&&",
|
|
@@ -3850,14 +4172,22 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3850
4172
|
"--certificate-authority",
|
|
3851
4173
|
shellQuote(encodedCertificateAuthority)
|
|
3852
4174
|
] : [],
|
|
3853
|
-
...options.https ? ["--https"] : []
|
|
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
|
+
] : []
|
|
3854
4184
|
].join(" ");
|
|
3855
4185
|
const command = [
|
|
3856
4186
|
...absoluteRemoteMacSshBase(options.project.profile),
|
|
3857
4187
|
"-o",
|
|
3858
4188
|
"ExitOnForwardFailure=yes",
|
|
3859
4189
|
"-R",
|
|
3860
|
-
`${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}`,
|
|
3861
4191
|
"/bin/sh -lc",
|
|
3862
4192
|
shellQuote(remoteCommand)
|
|
3863
4193
|
];
|
|
@@ -3945,7 +4275,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3945
4275
|
};
|
|
3946
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.`);
|
|
3947
4277
|
const request = (commandName) => {
|
|
3948
|
-
const id =
|
|
4278
|
+
const id = randomUUID4();
|
|
3949
4279
|
const response = new Promise((resolve6, reject) => pending.set(id, { reject, resolve: resolve6 }));
|
|
3950
4280
|
process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: 1 })}
|
|
3951
4281
|
`);
|
|
@@ -3978,6 +4308,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
3978
4308
|
close,
|
|
3979
4309
|
nativeCacheHit: currentReady.nativeCacheHit,
|
|
3980
4310
|
startedSimulator: currentReady.startedSimulator,
|
|
4311
|
+
targetKind: currentReady.targetKind,
|
|
3981
4312
|
timings: currentReady.timings,
|
|
3982
4313
|
udid: currentReady.udid,
|
|
3983
4314
|
rebuild: async () => {
|
|
@@ -4019,7 +4350,7 @@ var startAbsoluteRemoteIosDevSession = async (options) => {
|
|
|
4019
4350
|
import {
|
|
4020
4351
|
access as access7,
|
|
4021
4352
|
mkdir as mkdir7,
|
|
4022
|
-
readFile as
|
|
4353
|
+
readFile as readFile10,
|
|
4023
4354
|
rename as rename8,
|
|
4024
4355
|
rm as rm6,
|
|
4025
4356
|
writeFile as writeFile8
|
|
@@ -4225,7 +4556,7 @@ var createAbsoluteMobileAssociationPlugin = (mobile, projectRoot, options = {})
|
|
|
4225
4556
|
var writeAtomic = async (path, source) => {
|
|
4226
4557
|
let current;
|
|
4227
4558
|
try {
|
|
4228
|
-
current = await
|
|
4559
|
+
current = await readFile10(path, "utf8");
|
|
4229
4560
|
} catch (error) {
|
|
4230
4561
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
4231
4562
|
throw error;
|
|
@@ -4250,7 +4581,7 @@ var assertOwnedOutput = async (root) => {
|
|
|
4250
4581
|
const path = resolve7(root, OWNERSHIP_FILE);
|
|
4251
4582
|
let ownership;
|
|
4252
4583
|
try {
|
|
4253
|
-
ownership = JSON.parse(await
|
|
4584
|
+
ownership = JSON.parse(await readFile10(path, "utf8"));
|
|
4254
4585
|
} catch {
|
|
4255
4586
|
throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
|
|
4256
4587
|
}
|
|
@@ -4386,13 +4717,13 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
|
|
|
4386
4717
|
};
|
|
4387
4718
|
};
|
|
4388
4719
|
// src/mobile/buildPipeline.ts
|
|
4389
|
-
import { readFile as
|
|
4720
|
+
import { readFile as readFile14 } from "fs/promises";
|
|
4390
4721
|
import { join as join14, resolve as resolve12 } from "path";
|
|
4391
4722
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
4392
4723
|
|
|
4393
4724
|
// src/mobile/buildRelease.ts
|
|
4394
4725
|
import { createHash as createHash8 } from "crypto";
|
|
4395
|
-
import { mkdir as mkdir8, readFile as
|
|
4726
|
+
import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
|
|
4396
4727
|
import { basename as basename2, dirname as dirname6, extname, join as join8, relative as relative7, resolve as resolve8 } from "path";
|
|
4397
4728
|
var sha256 = (bytes) => createHash8("sha256").update(bytes).digest("hex");
|
|
4398
4729
|
var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
|
|
@@ -4419,7 +4750,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4419
4750
|
}
|
|
4420
4751
|
let resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
|
|
4421
4752
|
if (metadata.framework === "html" || metadata.framework === "htmx") {
|
|
4422
|
-
const source = await
|
|
4753
|
+
const source = await readFile11(resolvedAssetPath, "utf8");
|
|
4423
4754
|
const rewritten = rewriteStaticScriptPaths(source, manifest);
|
|
4424
4755
|
const documentHash = sha256(new TextEncoder().encode(rewritten));
|
|
4425
4756
|
resolvedAssetPath = join8(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
|
|
@@ -4433,8 +4764,8 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4433
4764
|
].map((key) => manifest[key]).find((path) => typeof path === "string");
|
|
4434
4765
|
const resolvedStylePath = styleAssetPath ? resolveAssetPath(buildDirectory, styleAssetPath) : undefined;
|
|
4435
4766
|
const [bytes, styleBytes] = await Promise.all([
|
|
4436
|
-
|
|
4437
|
-
resolvedStylePath ?
|
|
4767
|
+
readFile11(resolvedAssetPath),
|
|
4768
|
+
resolvedStylePath ? readFile11(resolvedStylePath) : undefined
|
|
4438
4769
|
]);
|
|
4439
4770
|
const bundlePath = `/${relative7(resolve8(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
|
|
4440
4771
|
const styleBundlePath = resolvedStylePath ? `/${relative7(resolve8(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
|
|
@@ -4454,7 +4785,7 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
|
|
|
4454
4785
|
var buildAbsoluteMobileCompatibilityRelease = async (options) => {
|
|
4455
4786
|
const [captured, producerBytes] = await Promise.all([
|
|
4456
4787
|
captureAbsoluteMobileRouteGraph(options.app),
|
|
4457
|
-
|
|
4788
|
+
readFile11(options.producerPath)
|
|
4458
4789
|
]);
|
|
4459
4790
|
if (captured.length === 0) {
|
|
4460
4791
|
throw new TypeError("No instrumented AbsoluteJS mobile page routes were found in the finalized Elysia route graph.");
|
|
@@ -4546,7 +4877,7 @@ import {
|
|
|
4546
4877
|
copyFile as copyFile5,
|
|
4547
4878
|
mkdir as mkdir9,
|
|
4548
4879
|
mkdtemp as mkdtemp4,
|
|
4549
|
-
readFile as
|
|
4880
|
+
readFile as readFile12,
|
|
4550
4881
|
rename as rename9,
|
|
4551
4882
|
rm as rm7,
|
|
4552
4883
|
writeFile as writeFile10
|
|
@@ -5076,7 +5407,7 @@ var resolveProjectImport = async (projectRoot, specifier) => {
|
|
|
5076
5407
|
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
|
|
5077
5408
|
const subpath = specifier.slice(packageName.length);
|
|
5078
5409
|
const packageDirectory = join9(resolve9(projectRoot), "node_modules", packageName);
|
|
5079
|
-
const manifest = JSON.parse(await
|
|
5410
|
+
const manifest = JSON.parse(await readFile12(join9(packageDirectory, "package.json"), "utf8"));
|
|
5080
5411
|
const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
|
|
5081
5412
|
const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
|
|
5082
5413
|
const target = importEntryTarget(entry);
|
|
@@ -5184,7 +5515,7 @@ var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) =
|
|
|
5184
5515
|
};
|
|
5185
5516
|
};
|
|
5186
5517
|
var absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
5187
|
-
const source = await
|
|
5518
|
+
const source = await readFile12(sourcePath, "utf8");
|
|
5188
5519
|
const extension = extname2(sourcePath).toLowerCase();
|
|
5189
5520
|
let scriptLoader;
|
|
5190
5521
|
if (extension === ".tsx")
|
|
@@ -5295,7 +5626,7 @@ import {
|
|
|
5295
5626
|
access as access8,
|
|
5296
5627
|
mkdir as mkdir10,
|
|
5297
5628
|
mkdtemp as mkdtemp5,
|
|
5298
|
-
readFile as
|
|
5629
|
+
readFile as readFile13,
|
|
5299
5630
|
rename as rename10,
|
|
5300
5631
|
rm as rm8,
|
|
5301
5632
|
writeFile as writeFile11
|
|
@@ -5392,7 +5723,7 @@ var resolveProducerHandler = (loaded, exportName) => {
|
|
|
5392
5723
|
};
|
|
5393
5724
|
var loadAbsoluteMobileMaterializedBundle = async (root) => {
|
|
5394
5725
|
const resolvedRoot = resolvePath3(root);
|
|
5395
|
-
const serialized = await
|
|
5726
|
+
const serialized = await readFile13(join10(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
5396
5727
|
const parsed = JSON.parse(serialized);
|
|
5397
5728
|
const index = parseBundleIndex(parsed);
|
|
5398
5729
|
const bundleRoot = join10(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
@@ -5447,7 +5778,7 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
|
|
|
5447
5778
|
var readAbsoluteMobileMaterializedReleases = async (root) => {
|
|
5448
5779
|
const resolvedRoot = resolvePath3(root);
|
|
5449
5780
|
try {
|
|
5450
|
-
const serialized = await
|
|
5781
|
+
const serialized = await readFile13(join10(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
5451
5782
|
const parsed = JSON.parse(serialized);
|
|
5452
5783
|
const index = parseBundleIndex(parsed);
|
|
5453
5784
|
const bundleRoot = join10(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
@@ -5558,7 +5889,7 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
|
5558
5889
|
const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
|
|
5559
5890
|
const root = join14(buildDirectory, ".absolutejs", "mobile-compatibility");
|
|
5560
5891
|
const [manifestSource, previous] = await Promise.all([
|
|
5561
|
-
|
|
5892
|
+
readFile14(join14(buildDirectory, "manifest.json"), "utf8"),
|
|
5562
5893
|
readAbsoluteMobileMaterializedReleases(root)
|
|
5563
5894
|
]);
|
|
5564
5895
|
const manifest = JSON.parse(manifestSource);
|
|
@@ -5957,7 +6288,7 @@ var createAbsoluteMobilePreviewPlugin = (mobile) => {
|
|
|
5957
6288
|
});
|
|
5958
6289
|
};
|
|
5959
6290
|
// src/mobile/nativeDeepLinks.ts
|
|
5960
|
-
import { readFile as
|
|
6291
|
+
import { readFile as readFile15, rename as rename11, writeFile as writeFile12 } from "fs/promises";
|
|
5961
6292
|
import { join as join17 } from "path";
|
|
5962
6293
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
5963
6294
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
@@ -5965,7 +6296,7 @@ var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
|
5965
6296
|
var NOT_FOUND = -1;
|
|
5966
6297
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
5967
6298
|
var writeChangedFile = async (path, source) => {
|
|
5968
|
-
const current = await
|
|
6299
|
+
const current = await readFile15(path, "utf8");
|
|
5969
6300
|
if (current === source)
|
|
5970
6301
|
return false;
|
|
5971
6302
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -6016,7 +6347,7 @@ ${hosts}
|
|
|
6016
6347
|
};
|
|
6017
6348
|
var configureAndroid = async (config) => {
|
|
6018
6349
|
const path = join17(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
6019
|
-
const source = await
|
|
6350
|
+
const source = await readFile15(path, "utf8");
|
|
6020
6351
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
6021
6352
|
if (mainActivity === NOT_FOUND) {
|
|
6022
6353
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -6042,7 +6373,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
6042
6373
|
`;
|
|
6043
6374
|
var configureIosInfo = async (config) => {
|
|
6044
6375
|
const path = join17(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
6045
|
-
const source = await
|
|
6376
|
+
const source = await readFile15(path, "utf8");
|
|
6046
6377
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
6047
6378
|
${END_MARKER}
|
|
6048
6379
|
`;
|
|
@@ -6068,7 +6399,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
6068
6399
|
const path = join17(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
6069
6400
|
let current = "";
|
|
6070
6401
|
try {
|
|
6071
|
-
current = await
|
|
6402
|
+
current = await readFile15(path, "utf8");
|
|
6072
6403
|
} catch (error) {
|
|
6073
6404
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
6074
6405
|
throw error;
|
|
@@ -6084,7 +6415,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
6084
6415
|
};
|
|
6085
6416
|
var configureIosProject = async (config) => {
|
|
6086
6417
|
const path = join17(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
6087
|
-
const source = await
|
|
6418
|
+
const source = await readFile15(path, "utf8");
|
|
6088
6419
|
const declarations = [
|
|
6089
6420
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
6090
6421
|
].map((match) => match[1]);
|
|
@@ -6123,7 +6454,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
6123
6454
|
};
|
|
6124
6455
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
6125
6456
|
init_deviceCapabilities();
|
|
6126
|
-
import { readFile as
|
|
6457
|
+
import { readFile as readFile16, rename as rename12, writeFile as writeFile13 } from "fs/promises";
|
|
6127
6458
|
import { join as join18 } from "path";
|
|
6128
6459
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
6129
6460
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
@@ -6134,7 +6465,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
6134
6465
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
6135
6466
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
6136
6467
|
var writeChangedFile2 = async (path, source) => {
|
|
6137
|
-
const current = await
|
|
6468
|
+
const current = await readFile16(path, "utf8");
|
|
6138
6469
|
if (current === source)
|
|
6139
6470
|
return false;
|
|
6140
6471
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
@@ -6154,7 +6485,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
6154
6485
|
};
|
|
6155
6486
|
var optionalSource = async (path) => {
|
|
6156
6487
|
try {
|
|
6157
|
-
return await
|
|
6488
|
+
return await readFile16(path, "utf8");
|
|
6158
6489
|
} catch (error) {
|
|
6159
6490
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
6160
6491
|
return null;
|
|
@@ -6275,7 +6606,7 @@ var configureIosPrivacyProject = async (config, requirements) => {
|
|
|
6275
6606
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
6276
6607
|
return false;
|
|
6277
6608
|
const projectPath = join18(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
6278
|
-
const project = await
|
|
6609
|
+
const project = await readFile16(projectPath, "utf8");
|
|
6279
6610
|
return writeChangedFile2(projectPath, addIosPrivacyProjectReference(project));
|
|
6280
6611
|
};
|
|
6281
6612
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -6328,7 +6659,7 @@ ${next.slice(index)}`;
|
|
|
6328
6659
|
};
|
|
6329
6660
|
var configureIos2 = async (config, plan) => {
|
|
6330
6661
|
const path = join18(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
6331
|
-
const source = await
|
|
6662
|
+
const source = await readFile16(path, "utf8");
|
|
6332
6663
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
6333
6664
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
6334
6665
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -6421,7 +6752,7 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
6421
6752
|
};
|
|
6422
6753
|
var configureAndroid2 = async (config, plan) => {
|
|
6423
6754
|
const path = join18(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
6424
|
-
const source = await
|
|
6755
|
+
const source = await readFile16(path, "utf8");
|
|
6425
6756
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
6426
6757
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
6427
6758
|
`);
|
|
@@ -7310,7 +7641,9 @@ export {
|
|
|
7310
7641
|
validateAbsoluteRemoteMacProfileName,
|
|
7311
7642
|
syncAbsoluteRemoteMacProject,
|
|
7312
7643
|
startAbsoluteRemoteIosDevSession,
|
|
7644
|
+
startAbsoluteIosTcpRelay,
|
|
7313
7645
|
startAbsoluteIosDevSession,
|
|
7646
|
+
startAbsoluteIosCaEnrollmentServer,
|
|
7314
7647
|
serializeAbsoluteMobileAuthEnvironment,
|
|
7315
7648
|
runWithAbsoluteMobileProducer,
|
|
7316
7649
|
runAbsoluteAndroidUpgradeConformance,
|
|
@@ -7345,6 +7678,8 @@ export {
|
|
|
7345
7678
|
parseAbsoluteAndroidInstalledApp,
|
|
7346
7679
|
pairAbsoluteRemoteMac,
|
|
7347
7680
|
normalizeAbsoluteMobileConfig,
|
|
7681
|
+
normalizeAbsoluteIosDeviceIdentifier,
|
|
7682
|
+
normalizeAbsoluteIosDeviceHost,
|
|
7348
7683
|
navigateAbsoluteMobilePage,
|
|
7349
7684
|
missingAbsoluteDeviceCapabilityPackages,
|
|
7350
7685
|
materializeAbsoluteRemoteMacAgent,
|
|
@@ -7361,6 +7696,7 @@ export {
|
|
|
7361
7696
|
installAbsoluteMobileSyncRemediation,
|
|
7362
7697
|
installAbsoluteMobileShellHttp,
|
|
7363
7698
|
installAbsoluteMobileAuthEnvironment,
|
|
7699
|
+
inspectAbsoluteRemoteMacLanHost,
|
|
7364
7700
|
inspectAbsoluteRemoteMac,
|
|
7365
7701
|
inspectAbsoluteMobileRouteMetadata,
|
|
7366
7702
|
inspectAbsoluteAndroidInstalledApp,
|
|
@@ -7430,5 +7766,5 @@ export {
|
|
|
7430
7766
|
ABSOLUTE_ANDROID_RELEASE_FORMAT
|
|
7431
7767
|
};
|
|
7432
7768
|
|
|
7433
|
-
//# debugId=
|
|
7769
|
+
//# debugId=ED7CBBBE08CD962364756E2164756E21
|
|
7434
7770
|
//# sourceMappingURL=index.js.map
|